diff --git a/CHANGELOG.md b/CHANGELOG.md
index 67c355bcc7bd8b2d1b450ebc8240d3e19e9b4cf6..ddcbc8c2cc06bbddf7a7a8c694645f0ea1e309b3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,23 @@
+0.74.0-beta7
+=============
+* Framework improvements
+    * Exceptions are caught and logged before reaching the Phrase::__toString() method
+    * Refactored controller actions in the Checkout area
+    * Refactored controller actions in the Tax area
+    * Implemented new look & feel for the Edit Order page (View/Edit Order)
+    * Replaced the end-to-end test for Onepage Checkout with online shipment methods with the scenario test
+* Fixed bugs
+    * Fixed an issue where a success message was absent when adding a product with options from Wishlist to Shopping Cart
+    * Fixed an issue where an exception was thrown when trying to sort Customer Groups by Tax Class
+    * Fixed an issue where the background color changed to the “on focus” state when clicking  the Admin Menu logo
+    * Fixed an issue with Mini Shopping Cart containing extra empty space
+* GitHub issues
+    * [#1173] (https://github.com/magento/magento2/pull/1173) -- Change to HttpClient4 from Java client; fix regex issues
+    * [#1185] (https://github.com/magento/magento2/pull/1185) -- Error message for duplicated phrases not allowed in Generator.php
+    * [#1199] (https://github.com/magento/magento2/pull/1199) -- Add Event for sales_order_state_change_before during Order->saveState()
+    * [#1201] (https://github.com/magento/magento2/pull/1101) -- Add customer_validate event
+    * [#1202] (https://github.com/magento/magento2/pull/1102) -- Email sending events
+
 0.74.0-beta6
 =============
 * Framework improvements
diff --git a/app/code/Magento/AdminNotification/composer.json b/app/code/Magento/AdminNotification/composer.json
index 354ef5fe45ea35de94ce81c1970bbb98e1a889ab..f458a240d3166d604a83b026cf38c06e32ed6247 100644
--- a/app/code/Magento/AdminNotification/composer.json
+++ b/app/code/Magento/AdminNotification/composer.json
@@ -3,15 +3,15 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-media-storage": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-media-storage": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "lib-libxml": "*",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/AdminNotification/view/adminhtml/templates/toolbar_entry.phtml b/app/code/Magento/AdminNotification/view/adminhtml/templates/toolbar_entry.phtml
index 4eb8992290adff8b14a85fc98e0f1b7b944a812c..e020a661d4d917d2e61ef793ab0c76bdb2eda699 100644
--- a/app/code/Magento/AdminNotification/view/adminhtml/templates/toolbar_entry.phtml
+++ b/app/code/Magento/AdminNotification/view/adminhtml/templates/toolbar_entry.phtml
@@ -14,12 +14,12 @@
 ?>
 <div
     data-mage-init='{"toolbarEntry": {}}'
-    class="notifications-wrapper"
+    class="notifications-wrapper admin__action-dropdown-wrap"
     data-notification-count="<?php echo $notificationCount; ?>">
     <?php if ($notificationCount > 0) : ?>
         <a
             href="<?php echo $block->getUrl('adminhtml/notification/index'); ?>"
-            class="notifications-action"
+            class="notifications-action admin__action-dropdown"
             data-mage-init='{"dropdown":{}}'
             title="<?php echo __('Notifications'); ?>"
             data-toggle="dropdown">
@@ -28,7 +28,7 @@
             </span>
         </a>
         <ul
-            class="notifications-list"
+            class="admin__action-dropdown-menu"
             data-mark-as-read-url="<?php echo $block->getUrl('adminhtml/notification/ajaxMarkAsRead'); ?>">
             <?php foreach ($block->getLatestUnreadNotifications() as $notification) : ?>
             <?php /** @var $notification \Magento\AdminNotification\Model\Inbox*/ ?>
@@ -76,7 +76,7 @@
         </ul>
     <?php else : ?>
         <a
-            class="notifications-action"
+            class="notifications-action admin__action-dropdown"
             href="<?php echo $block->getUrl('adminhtml/notification/index'); ?>"
             title="<?php echo __('Notifications'); ?>">
         </a>
diff --git a/app/code/Magento/AdminNotification/view/adminhtml/web/toolbar_entry.js b/app/code/Magento/AdminNotification/view/adminhtml/web/toolbar_entry.js
index 43e4869cdf52625f864894e028715f0bc6de40d7..7eb99c590fb4a66a814a18698258bb1b3993e784 100644
--- a/app/code/Magento/AdminNotification/view/adminhtml/web/toolbar_entry.js
+++ b/app/code/Magento/AdminNotification/view/adminhtml/web/toolbar_entry.js
@@ -11,7 +11,7 @@ define([
 
     // Mark notification as read via AJAX call
     var markNotificationAsRead = function (notificationId) {
-            var requestUrl = $('.notifications-wrapper .notifications-list').attr('data-mark-as-read-url');
+            var requestUrl = $('.notifications-wrapper .admin__action-dropdown-menu').attr('data-mark-as-read-url');
             $.ajax({
                 url: requestUrl,
                 type: 'POST',
@@ -33,7 +33,7 @@ define([
 
             if (notificationCount == 0) {
                 // Change appearance of the bubble and its behavior when the last notification is removed
-                $('.notifications-wrapper .notifications-list').remove();
+                $('.notifications-wrapper .admin__action-dropdown-menu').remove();
                 var notificationIcon = $('.notifications-wrapper .notifications-icon');
                 notificationIcon.removeAttr('data-toggle');
                 notificationIcon.off('click.dropdown');
@@ -45,7 +45,7 @@ define([
                 }
                 $('.notifications-entry-last .notifications-counter').text(notificationCount);
                 // Modify caption of the 'See All' link
-                var actionElement = $('.notifications-wrapper .notifications-list .last .action-more');
+                var actionElement = $('.notifications-wrapper .admin__action-dropdown-menu .last .action-more');
                 actionElement.text(actionElement.text().replace(/\d+/, notificationCount));
             }
         },
@@ -65,7 +65,7 @@ define([
         };
 
     // Show notification description when corresponding item is clicked
-    $('.notifications-wrapper .notifications-list .notifications-entry').on('click.showNotification', function (event) {
+    $('.notifications-wrapper .admin__action-dropdown-menu .notifications-entry').on('click.showNotification', function (event) {
         // hide notification dropdown
         $('.notifications-wrapper .notifications-icon').trigger('click.dropdown');
 
diff --git a/app/code/Magento/Authorization/composer.json b/app/code/Magento/Authorization/composer.json
index 22341f8d0b4d16e93ce92006994cd36e1fbedb58..7e752b8409c4e92ccb1114620a761fdb81d5f50e 100644
--- a/app/code/Magento/Authorization/composer.json
+++ b/app/code/Magento/Authorization/composer.json
@@ -3,12 +3,12 @@
     "description": "Authorization module provides access to Magento ACL functionality.",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Backend/App/Action/Context.php b/app/code/Magento/Backend/App/Action/Context.php
index e6618170e4d6b72683ed960679575649e307dec4..b16e9b05d18047a5420f007e4136cce3177907a5 100644
--- a/app/code/Magento/Backend/App/Action/Context.php
+++ b/app/code/Magento/Backend/App/Action/Context.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\Backend\App\Action;
 
+use Magento\Framework\Controller\ResultFactory;
+
 /**
  * Backend Controller context
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
@@ -62,6 +64,7 @@ class Context extends \Magento\Framework\App\Action\Context
      * @param \Magento\Framework\App\ViewInterface $view
      * @param \Magento\Framework\Message\ManagerInterface $messageManager
      * @param \Magento\Backend\Model\View\Result\RedirectFactory $resultRedirectFactory
+     * @param \Magento\Framework\Controller\ResultFactory $resultFactory
      * @param \Magento\Backend\Model\Session $session
      * @param \Magento\Framework\AuthorizationInterface $authorization
      * @param \Magento\Backend\Model\Auth $auth
@@ -83,6 +86,7 @@ class Context extends \Magento\Framework\App\Action\Context
         \Magento\Framework\App\ViewInterface $view,
         \Magento\Framework\Message\ManagerInterface $messageManager,
         \Magento\Backend\Model\View\Result\RedirectFactory $resultRedirectFactory,
+        ResultFactory $resultFactory,
         \Magento\Backend\Model\Session $session,
         \Magento\Framework\AuthorizationInterface $authorization,
         \Magento\Backend\Model\Auth $auth,
@@ -102,7 +106,8 @@ class Context extends \Magento\Framework\App\Action\Context
             $actionFlag,
             $view,
             $messageManager,
-            $resultRedirectFactory
+            $resultRedirectFactory,
+            $resultFactory
         );
 
         $this->_session = $session;
diff --git a/app/code/Magento/Backend/App/Config.php b/app/code/Magento/Backend/App/Config.php
index d8eaa7af14254bd16dd3c8f7ae3cc9a549e75cde..0ac5211b41d9f58308d4f57977e0c8054c15e4c7 100644
--- a/app/code/Magento/Backend/App/Config.php
+++ b/app/code/Magento/Backend/App/Config.php
@@ -10,6 +10,8 @@
 
 namespace Magento\Backend\App;
 
+use Magento\Framework\App\Config\ScopeConfigInterface;
+
 /**
  * Backend config accessor
  */
@@ -36,7 +38,7 @@ class Config implements ConfigInterface
      */
     public function getValue($path)
     {
-        return $this->_scopePool->getScope(\Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT, null)->getValue($path);
+        return $this->_scopePool->getScope(ScopeConfigInterface::SCOPE_TYPE_DEFAULT, null)->getValue($path);
     }
 
     /**
@@ -48,7 +50,7 @@ class Config implements ConfigInterface
      */
     public function setValue($path, $value)
     {
-        $this->_scopePool->getScope(\Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT, null)->setValue($path, $value);
+        $this->_scopePool->getScope(ScopeConfigInterface::SCOPE_TYPE_DEFAULT, null)->setValue($path, $value);
     }
 
     /**
@@ -59,6 +61,6 @@ class Config implements ConfigInterface
      */
     public function isSetFlag($path)
     {
-        return !!$this->_scopePool->getScope(\Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT, null)->getValue($path);
+        return !!$this->_scopePool->getScope(ScopeConfigInterface::SCOPE_TYPE_DEFAULT, null)->getValue($path);
     }
 }
diff --git a/app/code/Magento/Backend/Block/Menu.php b/app/code/Magento/Backend/Block/Menu.php
index 6eaed8e5b16344608d8b4672b933ca2b013c284d..087fd1fa351709778cc536f519c4b84206d97134 100644
--- a/app/code/Magento/Backend/Block/Menu.php
+++ b/app/code/Magento/Backend/Block/Menu.php
@@ -419,7 +419,7 @@ class Menu extends \Magento\Backend\Block\Template
         if ($level == 0 && $limit) {
             $colStops = $this->_columnBrake($menuItem->getChildren(), $limit);
             $output .= '<strong class="submenu-title">' . $this->_getAnchorLabel($menuItem) . '</strong>';
-            $output .= '<a href="#" class="submenu-close _close" data-role="close-submenu"></a>';
+            $output .= '<a href="#" class="action-close _close" data-role="close-submenu"></a>';
         }
 
         $output .= $this->renderNavigation($menuItem->getChildren(), $level + 1, $limit, $colStops);
@@ -436,6 +436,7 @@ class Menu extends \Magento\Backend\Block\Template
      * @param array $colBrakes
      * @return string HTML
      * @SuppressWarnings(PHPMD.NPathComplexity)
+     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
      */
     public function renderNavigation($menu, $level = 0, $limit = 0, $colBrakes = [])
     {
@@ -454,21 +455,30 @@ class Menu extends \Magento\Backend\Block\Template
             }
 
             $id = $this->getJsId($menuItem->getId());
-            $output .= '<li ' . $this->getUiId(
-                $menuItem->getId()
-            ) . ' class="item-' . $itemClass . ' ' . $this->_renderItemCssClass(
-                $menuItem,
-                $level
-            ) . ($level == 0 ? '" id="' . $id . '" aria-haspopup="true' : '')
-                . '" role="menu-item">' . $this->_renderAnchor(
-                $menuItem,
-                $level
-            ) . $this->_addSubMenu(
-                $menuItem,
-                $level,
-                $limit,
-                $id
-            ) . '</li>';
+            if (count($menu) > 1 || $level != 1) {
+                $output .= '<li ' . $this->getUiId(
+                        $menuItem->getId()
+                    ) . ' class="item-' . $itemClass . ' ' . $this->_renderItemCssClass(
+                        $menuItem,
+                        $level
+                    ) . ($level == 0 ? '" id="' . $id . '" aria-haspopup="true' : '')
+                    . '" role="menu-item">' . $this->_renderAnchor(
+                        $menuItem,
+                        $level
+                    ) . $this->_addSubMenu(
+                        $menuItem,
+                        $level,
+                        $limit,
+                        $id
+                    ) . '</li>';
+            } else {
+                $output .= $this->_addSubMenu(
+                    $menuItem,
+                    $level,
+                    $limit,
+                    $id);
+            }
+
             $itemPosition++;
         }
 
diff --git a/app/code/Magento/Backend/Block/Page/System/Config/Robots/Reset.php b/app/code/Magento/Backend/Block/Page/System/Config/Robots/Reset.php
index d32e99a00d814b5a134e9e3060526e7586f9043e..827ae18b0b8e1f908653597bc1816a6c73d9b148 100644
--- a/app/code/Magento/Backend/Block/Page/System/Config/Robots/Reset.php
+++ b/app/code/Magento/Backend/Block/Page/System/Config/Robots/Reset.php
@@ -8,6 +8,8 @@
 
 namespace Magento\Backend\Block\Page\System\Config\Robots;
 
+use Magento\Framework\App\Config\ScopeConfigInterface;
+
 /**
  * "Reset to Defaults" button renderer
  *
@@ -50,7 +52,7 @@ class Reset extends \Magento\Config\Block\System\Config\Form\Field
     public function getRobotsDefaultCustomInstructions()
     {
         return trim((string)$this->_scopeConfig->getValue(
-            self::XML_PATH_ROBOTS_DEFAULT_CUSTOM_INSTRUCTIONS, \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT
+            self::XML_PATH_ROBOTS_DEFAULT_CUSTOM_INSTRUCTIONS, ScopeConfigInterface::SCOPE_TYPE_DEFAULT
         ));
     }
 
diff --git a/app/code/Magento/Backend/Block/Widget/Grid.php b/app/code/Magento/Backend/Block/Widget/Grid.php
index 0e0ac51f859950b32f695e7014a04de1a7ce4684..1d33dc18146219f8fe4cb68d00b03a1aefa0ebad 100644
--- a/app/code/Magento/Backend/Block/Widget/Grid.php
+++ b/app/code/Magento/Backend/Block/Widget/Grid.php
@@ -391,6 +391,10 @@ class Grid extends \Magento\Backend\Block\Widget
      */
     protected function _prepareGrid()
     {
+        $this->_eventManager->dispatch(
+            'backend_block_widget_grid_prepare_grid_before',
+            ['grid' => $this, 'collection' => $this->getCollection()]
+        );
         if ($this->getChildBlock('grid.massaction') && $this->getChildBlock('grid.massaction')->isAvailable()) {
             $this->getChildBlock('grid.massaction')->prepareMassactionColumn();
         }
@@ -433,6 +437,10 @@ class Grid extends \Magento\Backend\Block\Widget
                 'Magento\Backend\Block\Widget\Button'
             )->setData(
                 ['label' => __('Reset Filter'), 'onclick' => $this->getJsObjectName() . '.resetFilter()', 'class' => 'action-reset']
+            )->setDataAttribute(
+                [
+                    'action' => 'grid-filter-reset'
+                ]
             )
         );
         $this->setChild(
@@ -445,6 +453,10 @@ class Grid extends \Magento\Backend\Block\Widget
                     'onclick' => $this->getJsObjectName() . '.doFilter()',
                     'class' => 'task',
                 ]
+            )->setDataAttribute(
+                [
+                    'action' => 'grid-filter-apply'
+                ]
             )
         );
     }
diff --git a/app/code/Magento/Backend/Block/Widget/Grid/Column/Filter/Datetime.php b/app/code/Magento/Backend/Block/Widget/Grid/Column/Filter/Datetime.php
index 4d5255c93cd4187907d0873697444b7d2203af2f..7ff6ce3773c50ef14917a85706ac5d8a0af4d02b 100644
--- a/app/code/Magento/Backend/Block/Widget/Grid/Column/Filter/Datetime.php
+++ b/app/code/Magento/Backend/Block/Widget/Grid/Column/Filter/Datetime.php
@@ -104,7 +104,7 @@ class Datetime extends \Magento\Backend\Block\Widget\Grid\Column\Filter\Date
         $html =
             '<div class="range" id="' . $htmlId . '_range"><div class="range-line date">' . '<input type="text" name="'
             . $this->_getHtmlName() . '[from]" id="' . $htmlId . '_from"' . ' value="' . $this->getEscapedValue('from')
-            . '" class="input-text no-changes" placeholder="' . __(
+            . '" class="input-text admin__control-text no-changes" placeholder="' . __(
                 'From'
             ) . '" ' . $this->getUiId(
                 'filter',
@@ -114,7 +114,7 @@ class Datetime extends \Magento\Backend\Block\Widget\Grid\Column\Filter\Date
         $html .= '<div class="range-line date">' . '<input type="text" name="' . $this->_getHtmlName() . '[to]" id="'
             . $htmlId . '_to"' . ' value="' . $this->getEscapedValue(
                 'to'
-            ) . '" class="input-text no-changes" placeholder="' . __(
+            ) . '" class="input-text admin__control-text no-changes" placeholder="' . __(
                 'To'
             ) . '" ' . $this->getUiId(
                 'filter',
diff --git a/app/code/Magento/Backend/Block/Widget/Grid/Extended.php b/app/code/Magento/Backend/Block/Widget/Grid/Extended.php
index cafd687c9da150d6c0d56c7e0649645a24923e51..516c3eaae5040e655ac5bf02c7b2871a9208a394 100644
--- a/app/code/Magento/Backend/Block/Widget/Grid/Extended.php
+++ b/app/code/Magento/Backend/Block/Widget/Grid/Extended.php
@@ -208,6 +208,10 @@ class Extended extends \Magento\Backend\Block\Widget\Grid implements \Magento\Ba
                     'onclick' => $this->getJsObjectName() . '.resetFilter()',
                     'class' => 'action-reset'
                 ]
+            )->setDataAttribute(
+                [
+                    'action' => 'grid-filter-reset'
+                ]
             )
         );
         $this->setChild(
@@ -218,6 +222,10 @@ class Extended extends \Magento\Backend\Block\Widget\Grid implements \Magento\Ba
                     'onclick' => $this->getJsObjectName() . '.doFilter()',
                     'class' => 'task',
                 ]
+            )->setDataAttribute(
+                [
+                    'action' => 'grid-filter-apply'
+                ]
             )
         );
         return parent::_prepareLayout();
diff --git a/app/code/Magento/Backend/Model/Auth/Session.php b/app/code/Magento/Backend/Model/Auth/Session.php
index fec438f70c744d7b7cc9999d8574f3e4deef862c..d5cf7e86c4b8ae8c301a2993893a9d31d615e7e5 100644
--- a/app/code/Magento/Backend/Model/Auth/Session.php
+++ b/app/code/Magento/Backend/Model/Auth/Session.php
@@ -61,9 +61,11 @@ class Session extends \Magento\Framework\Session\SessionManager implements \Mage
      * @param \Magento\Framework\Session\StorageInterface $storage
      * @param CookieManagerInterface $cookieManager
      * @param CookieMetadataFactory $cookieMetadataFactory
+     * @param \Magento\Framework\App\State $appState
      * @param \Magento\Framework\Acl\Builder $aclBuilder
      * @param \Magento\Backend\Model\UrlInterface $backendUrl
      * @param \Magento\Backend\App\ConfigInterface $config
+     * @throws \Magento\Framework\Exception\SessionException
      * @SuppressWarnings(PHPMD.ExcessiveParameterList)
      */
     public function __construct(
@@ -75,6 +77,7 @@ class Session extends \Magento\Framework\Session\SessionManager implements \Mage
         \Magento\Framework\Session\StorageInterface $storage,
         CookieManagerInterface $cookieManager,
         CookieMetadataFactory $cookieMetadataFactory,
+        \Magento\Framework\App\State $appState,
         \Magento\Framework\Acl\Builder $aclBuilder,
         \Magento\Backend\Model\UrlInterface $backendUrl,
         \Magento\Backend\App\ConfigInterface $config
@@ -90,9 +93,9 @@ class Session extends \Magento\Framework\Session\SessionManager implements \Mage
             $validator,
             $storage,
             $cookieManager,
-            $cookieMetadataFactory
+            $cookieMetadataFactory,
+            $appState
         );
-        $this->start();
     }
 
     /**
diff --git a/app/code/Magento/Backend/Model/Locale/Manager.php b/app/code/Magento/Backend/Model/Locale/Manager.php
index 76a327f1364d1b42a05f3ea000474049d5b87068..4f9584c96a81706b0eaefafd3137a27d75291fc3 100644
--- a/app/code/Magento/Backend/Model/Locale/Manager.php
+++ b/app/code/Magento/Backend/Model/Locale/Manager.php
@@ -68,7 +68,7 @@ class Manager
      */
     public function getUserInterfaceLocale()
     {
-        $interfaceLocale = \Magento\Framework\Locale\ResolverInterface::DEFAULT_LOCALE;
+        $interfaceLocale = \Magento\Framework\Locale\Resolver::DEFAULT_LOCALE;
 
         $userData = $this->_authSession->getUser();
         if ($userData && $userData->getInterfaceLocale()) {
diff --git a/app/code/Magento/Backend/Model/Session.php b/app/code/Magento/Backend/Model/Session.php
index c0719bb2ecf9ef98084a0ecba7e11630732eddbf..6dd5af4a3c54830029f8372e214009a4e3b04bef 100644
--- a/app/code/Magento/Backend/Model/Session.php
+++ b/app/code/Magento/Backend/Model/Session.php
@@ -9,39 +9,6 @@ namespace Magento\Backend\Model;
 
 class Session extends \Magento\Framework\Session\SessionManager
 {
-    /**
-     * @param \Magento\Framework\App\Request\Http $request
-     * @param \Magento\Framework\Session\SidResolverInterface $sidResolver
-     * @param \Magento\Framework\Session\Config\ConfigInterface $sessionConfig
-     * @param \Magento\Framework\Session\SaveHandlerInterface $saveHandler
-     * @param \Magento\Framework\Session\ValidatorInterface $validator
-     * @param \Magento\Framework\Session\StorageInterface $storage
-     * @param \Magento\Framework\Stdlib\CookieManagerInterface $cookieManager
-     * @param \Magento\Framework\Stdlib\Cookie\CookieMetadataFactory $cookieMetadataFactory
-     */
-    public function __construct(
-        \Magento\Framework\App\Request\Http $request,
-        \Magento\Framework\Session\SidResolverInterface $sidResolver,
-        \Magento\Framework\Session\Config\ConfigInterface $sessionConfig,
-        \Magento\Framework\Session\SaveHandlerInterface $saveHandler,
-        \Magento\Framework\Session\ValidatorInterface $validator,
-        \Magento\Framework\Session\StorageInterface $storage,
-        \Magento\Framework\Stdlib\CookieManagerInterface $cookieManager,
-        \Magento\Framework\Stdlib\Cookie\CookieMetadataFactory $cookieMetadataFactory
-    ) {
-        parent::__construct(
-            $request,
-            $sidResolver,
-            $sessionConfig,
-            $saveHandler,
-            $validator,
-            $storage,
-            $cookieManager,
-            $cookieMetadataFactory
-        );
-        $this->start();
-    }
-
     /**
      * Skip path validation in backend area
      *
diff --git a/app/code/Magento/Backend/Model/Session/Quote.php b/app/code/Magento/Backend/Model/Session/Quote.php
index 2f1f75ab07e9201d03ec0706fc3a0fb20f42ddc1..1427e1ad5ad570d5ea93c0f5cef3c5cdfd71c4cb 100644
--- a/app/code/Magento/Backend/Model/Session/Quote.php
+++ b/app/code/Magento/Backend/Model/Session/Quote.php
@@ -83,11 +83,13 @@ class Quote extends \Magento\Framework\Session\SessionManager
      * @param \Magento\Framework\Session\StorageInterface $storage
      * @param \Magento\Framework\Stdlib\CookieManagerInterface $cookieManager
      * @param \Magento\Framework\Stdlib\Cookie\CookieMetadataFactory $cookieMetadataFactory
+     * @param \Magento\Framework\App\State $appState
      * @param CustomerRepositoryInterface $customerRepository
      * @param \Magento\Quote\Model\QuoteRepository $quoteRepository
      * @param \Magento\Sales\Model\OrderFactory $orderFactory
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
      * @param GroupManagementInterface $groupManagement
+     * @throws \Magento\Framework\Exception\SessionException
      * @SuppressWarnings(PHPMD.ExcessiveParameterList)
      */
     public function __construct(
@@ -99,6 +101,7 @@ class Quote extends \Magento\Framework\Session\SessionManager
         \Magento\Framework\Session\StorageInterface $storage,
         \Magento\Framework\Stdlib\CookieManagerInterface $cookieManager,
         \Magento\Framework\Stdlib\Cookie\CookieMetadataFactory $cookieMetadataFactory,
+        \Magento\Framework\App\State $appState,
         CustomerRepositoryInterface $customerRepository,
         \Magento\Quote\Model\QuoteRepository $quoteRepository,
         \Magento\Sales\Model\OrderFactory $orderFactory,
@@ -118,9 +121,9 @@ class Quote extends \Magento\Framework\Session\SessionManager
             $validator,
             $storage,
             $cookieManager,
-            $cookieMetadataFactory
+            $cookieMetadataFactory,
+            $appState
         );
-        $this->start();
         if ($this->_storeManager->hasSingleStore()) {
             $this->setStoreId($this->_storeManager->getStore(true)->getId());
         }
@@ -147,7 +150,7 @@ class Quote extends \Magento\Framework\Session\SessionManager
                     $this->_quote->setStoreId($this->getStoreId());
                 }
 
-                if ($this->getCustomerId()) {
+                if ($this->getCustomerId() && $this->getCustomerId() != $this->_quote->getCustomerId()) {
                     $customer = $this->customerRepository->getById($this->getCustomerId());
                     $this->_quote->assignCustomer($customer);
                 }
diff --git a/app/code/Magento/Backend/Model/Url.php b/app/code/Magento/Backend/Model/Url.php
index 265a7237ed37e1713fb17d97a3674c633d406341..36fbfafe66974d236c0bc90c2d7133fc3bcf128b 100644
--- a/app/code/Magento/Backend/Model/Url.php
+++ b/app/code/Magento/Backend/Model/Url.php
@@ -83,7 +83,7 @@ class Url extends \Magento\Framework\Url implements \Magento\Backend\Model\UrlIn
      * @param \Magento\Framework\Url\ScopeResolverInterface $scopeResolver
      * @param \Magento\Framework\Session\Generic $session
      * @param \Magento\Framework\Session\SidResolverInterface $sidResolver
-     * @param \Magento\Framework\Url\RouteParamsResolverFactory $routeParamsResolver
+     * @param \Magento\Framework\Url\RouteParamsResolverFactory $routeParamsResolverFactory
      * @param \Magento\Framework\Url\QueryParamsResolverInterface $queryParamsResolver
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param string $scopeType
@@ -105,7 +105,7 @@ class Url extends \Magento\Framework\Url implements \Magento\Backend\Model\UrlIn
         \Magento\Framework\Url\ScopeResolverInterface $scopeResolver,
         \Magento\Framework\Session\Generic $session,
         \Magento\Framework\Session\SidResolverInterface $sidResolver,
-        \Magento\Framework\Url\RouteParamsResolverFactory $routeParamsResolver,
+        \Magento\Framework\Url\RouteParamsResolverFactory $routeParamsResolverFactory,
         \Magento\Framework\Url\QueryParamsResolverInterface $queryParamsResolver,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         $scopeType,
@@ -126,7 +126,7 @@ class Url extends \Magento\Framework\Url implements \Magento\Backend\Model\UrlIn
             $scopeResolver,
             $session,
             $sidResolver,
-            $routeParamsResolver,
+            $routeParamsResolverFactory,
             $queryParamsResolver,
             $scopeConfig,
             $scopeType,
diff --git a/app/code/Magento/Backend/Setup/ConfigOptionsList.php b/app/code/Magento/Backend/Setup/ConfigOptionsList.php
index 83a953cd2f2232cc36e741682e95e3c406dfc194..4872cd18fe2099561e1b9bf5cb580ea43d756f56 100644
--- a/app/code/Magento/Backend/Setup/ConfigOptionsList.php
+++ b/app/code/Magento/Backend/Setup/ConfigOptionsList.php
@@ -19,7 +19,7 @@ class ConfigOptionsList implements ConfigOptionsListInterface
     /**
      * Input key for the options
      */
-    const INPUT_KEY_BACKEND_FRONTNAME = 'backend_frontname';
+    const INPUT_KEY_BACKEND_FRONTNAME = 'backend-frontname';
 
     /**
      * Path to the values in the deployment config
diff --git a/app/code/Magento/Backend/Test/Unit/Model/Locale/ManagerTest.php b/app/code/Magento/Backend/Test/Unit/Model/Locale/ManagerTest.php
index 000c861f11d8eba4c098f8427df867287de61c2d..a624a526d5dbffd7dcd06460a11872fb1f4328c2 100644
--- a/app/code/Magento/Backend/Test/Unit/Model/Locale/ManagerTest.php
+++ b/app/code/Magento/Backend/Test/Unit/Model/Locale/ManagerTest.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\Backend\Test\Unit\Model\Locale;
 
+use Magento\Framework\Locale\Resolver;
+
 class ManagerTest extends \PHPUnit_Framework_TestCase
 {
     /**
@@ -87,7 +89,7 @@ class ManagerTest extends \PHPUnit_Framework_TestCase
     {
         $locale = $this->_model->getUserInterfaceLocale();
 
-        $this->assertEquals($locale, \Magento\Framework\Locale\ResolverInterface::DEFAULT_LOCALE);
+        $this->assertEquals($locale, Resolver::DEFAULT_LOCALE);
     }
 
     /**
diff --git a/app/code/Magento/Backend/Test/Unit/Model/Session/QuoteTest.php b/app/code/Magento/Backend/Test/Unit/Model/Session/QuoteTest.php
index 13f906bee346b45c02399d3f2cdc59602f9dec3f..fd3af3380023396c31f53ac97a41a1a631154993 100644
--- a/app/code/Magento/Backend/Test/Unit/Model/Session/QuoteTest.php
+++ b/app/code/Magento/Backend/Test/Unit/Model/Session/QuoteTest.php
@@ -182,6 +182,13 @@ class QuoteTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
+        $appStateMock = $this->getMock(
+            'Magento\Framework\App\State',
+            [],
+            [],
+            '',
+            false
+        );
         $this->storeManagerMock = $this->getMockForAbstractClass(
             'Magento\Store\Model\StoreManagerInterface',
             [],
@@ -201,11 +208,12 @@ class QuoteTest extends \PHPUnit_Framework_TestCase
                 'storage' => $this->storageMock,
                 'cookieManager' => $this->cookieManagerMock,
                 'cookieMetadataFactory' => $this->cookieMetadataFactoryMock,
+                'appState' => $appStateMock,
                 'customerRepository' => $this->customerRepositoryMock,
                 'quoteRepository' => $this->quoteRepositoryMock,
                 'orderFactory' => $this->orderFactoryMock,
                 'storeManager' => $this->storeManagerMock,
-                'groupManagement' => $this->groupManagementMock
+                'groupManagement' => $this->groupManagementMock,
             ],
             '',
             true
@@ -217,12 +225,42 @@ class QuoteTest extends \PHPUnit_Framework_TestCase
      *
      * @return void
      */
-    public function testGetQuote()
+    public function testGetQuoteWithoutQuoteId()
     {
-        $storeId = 10;
         $quoteId = 22;
-        $customerGroupId = 77;
+        $storeId = 10;
         $customerId = 66;
+        $customerGroupId = 77;
+
+        $this->quote->expects($this->any())
+            ->method('getQuoteId')
+            ->will($this->returnValue(null));
+        $this->quote->expects($this->any())
+            ->method('setQuoteId')
+            ->with($quoteId);
+        $this->quote->expects($this->any())
+            ->method('getStoreId')
+            ->will($this->returnValue($storeId));
+        $this->quote->expects($this->any())
+            ->method('getCustomerId')
+            ->will($this->returnValue($customerId));
+
+        $defaultGroup = $this->getMockBuilder('Magento\Customer\Api\Data\GroupInterface')
+            ->getMock();
+        $defaultGroup->expects($this->any())
+            ->method('getId')
+            ->will($this->returnValue($customerGroupId));
+        $this->groupManagementMock->expects($this->any())
+            ->method('getDefaultGroup')
+            ->will($this->returnValue($defaultGroup));
+
+        $dataCustomerMock = $this->getMockBuilder('Magento\Customer\Api\Data\CustomerInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->customerRepositoryMock->expects($this->once())
+            ->method('getById')
+            ->with($customerId)
+            ->willReturn($dataCustomerMock);
 
         $quoteMock = $this->getMock(
             'Magento\Quote\Model\Quote',
@@ -240,28 +278,9 @@ class QuoteTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
-
-        $defaultGroup = $this->getMockBuilder('Magento\Customer\Api\Data\GroupInterface')
-            ->getMock();
-        $defaultGroup->expects($this->any())
-            ->method('getId')
-            ->will($this->returnValue($customerGroupId));
-        $this->groupManagementMock->expects($this->any())
-            ->method('getDefaultGroup')
-            ->will($this->returnValue($defaultGroup));
-
-        $this->quoteRepositoryMock->expects($this->once())
-            ->method('create')
-            ->will($this->returnValue($quoteMock));
-        $this->quote->expects($this->any())
-            ->method('getStoreId')
-            ->will($this->returnValue($storeId));
         $quoteMock->expects($this->once())
             ->method('setStoreId')
             ->with($storeId);
-        $this->quote->expects($this->any())
-            ->method('getQuoteId')
-            ->will($this->returnValue(null));
         $quoteMock->expects($this->once())
             ->method('setCustomerGroupId')
             ->with($customerGroupId)
@@ -270,25 +289,9 @@ class QuoteTest extends \PHPUnit_Framework_TestCase
             ->method('setIsActive')
             ->with(false)
             ->will($this->returnSelf());
-        $this->quoteRepositoryMock->expects($this->once())
-            ->method('save')
-            ->with($quoteMock);
         $quoteMock->expects($this->once())
             ->method('getId')
             ->will($this->returnValue($quoteId));
-        $this->quote->expects($this->any())
-            ->method('setQuoteId')
-            ->with($quoteId);
-        $this->quote->expects($this->any())
-            ->method('getCustomerId')
-            ->will($this->returnValue($customerId));
-        $dataCustomerMock = $this->getMockBuilder('Magento\Customer\Api\Data\CustomerInterface')
-            ->disableOriginalConstructor()
-            ->getMock();
-        $this->customerRepositoryMock->expects($this->once())
-            ->method('getById')
-            ->with($customerId)
-            ->willReturn($dataCustomerMock);
         $quoteMock->expects($this->once())
             ->method('assignCustomer')
             ->with($dataCustomerMock);
@@ -299,6 +302,13 @@ class QuoteTest extends \PHPUnit_Framework_TestCase
             ->method('setIsSuperMode')
             ->with(true);
 
+        $this->quoteRepositoryMock->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue($quoteMock));
+        $this->quoteRepositoryMock->expects($this->once())
+            ->method('save')
+            ->with($quoteMock);
+
         $this->assertEquals($quoteMock, $this->quote->getQuote());
     }
 
@@ -306,12 +316,33 @@ class QuoteTest extends \PHPUnit_Framework_TestCase
      * Run test getQuote method
      *
      * @return void
+     * @dataProvider getQuoteDataProvider
      */
-    public function testGetQuoteGet()
+    public function testGetQuoteWithQuoteId($customerId, $quoteCustomerId, $expectedNumberOfInvokes)
     {
-        $storeId = 10;
         $quoteId = 22;
-        $customerId = 66;
+        $storeId = 10;
+
+        $this->quote->expects($this->any())
+            ->method('getQuoteId')
+            ->will($this->returnValue($quoteId));
+        $this->quote->expects($this->any())
+            ->method('setQuoteId')
+            ->with($quoteId);
+        $this->quote->expects($this->any())
+            ->method('getStoreId')
+            ->will($this->returnValue($storeId));
+        $this->quote->expects($this->any())
+            ->method('getCustomerId')
+            ->will($this->returnValue($customerId));
+
+        $dataCustomerMock = $this->getMockBuilder('Magento\Customer\Api\Data\CustomerInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->customerRepositoryMock->expects($this->$expectedNumberOfInvokes())
+            ->method('getById')
+            ->with($customerId)
+            ->willReturn($dataCustomerMock);
 
         $quoteMock = $this->getMock(
             'Magento\Quote\Model\Quote',
@@ -323,43 +354,17 @@ class QuoteTest extends \PHPUnit_Framework_TestCase
                 'assignCustomer',
                 'setIgnoreOldQty',
                 'setIsSuperMode',
+                'getCustomerId',
                 '__wakeup'
             ],
             [],
             '',
             false
         );
-
-        $this->quoteRepositoryMock->expects($this->once())
-            ->method('create')
-            ->will($this->returnValue($quoteMock));
-        $this->quote->expects($this->any())
-            ->method('getStoreId')
-            ->will($this->returnValue($storeId));
         $quoteMock->expects($this->once())
             ->method('setStoreId')
             ->with($storeId);
-        $this->quote->expects($this->any())
-            ->method('getQuoteId')
-            ->will($this->returnValue($quoteId));
-        $this->quoteRepositoryMock->expects($this->once())
-            ->method('get')
-            ->with($quoteId)
-            ->willReturn($quoteMock);
-        $this->quote->expects($this->any())
-            ->method('setQuoteId')
-            ->with($quoteId);
-        $this->quote->expects($this->any())
-            ->method('getCustomerId')
-            ->will($this->returnValue($customerId));
-        $dataCustomerMock = $this->getMockBuilder('Magento\Customer\Api\Data\CustomerInterface')
-            ->disableOriginalConstructor()
-            ->getMock();
-        $this->customerRepositoryMock->expects($this->once())
-            ->method('getById')
-            ->with($customerId)
-            ->willReturn($dataCustomerMock);
-        $quoteMock->expects($this->once())
+        $quoteMock->expects($this->$expectedNumberOfInvokes())
             ->method('assignCustomer')
             ->with($dataCustomerMock);
         $quoteMock->expects($this->once())
@@ -368,7 +373,29 @@ class QuoteTest extends \PHPUnit_Framework_TestCase
         $quoteMock->expects($this->once())
             ->method('setIsSuperMode')
             ->with(true);
+        $quoteMock->expects($this->once())
+            ->method('getCustomerId')
+            ->will($this->returnValue($quoteCustomerId));
+
+        $this->quoteRepositoryMock->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue($quoteMock));
+        $this->quoteRepositoryMock->expects($this->once())
+            ->method('get')
+            ->with($quoteId)
+            ->willReturn($quoteMock);
 
         $this->assertEquals($quoteMock, $this->quote->getQuote());
     }
+
+    /**
+     * @return array
+     */
+    public function getQuoteDataProvider()
+    {
+        return [
+            'customer ids different' => [66, null, 'once'],
+            'customer ids same' => [66, 66, 'never'],
+        ];
+    }
 }
diff --git a/app/code/Magento/Backend/Test/Unit/Model/UrlTest.php b/app/code/Magento/Backend/Test/Unit/Model/UrlTest.php
index a53b891a17be5e100f0916cf04e6b2a4f3469c71..b833fe25752a09ecd9af87a7147f4debf493affe 100644
--- a/app/code/Magento/Backend/Test/Unit/Model/UrlTest.php
+++ b/app/code/Magento/Backend/Test/Unit/Model/UrlTest.php
@@ -165,7 +165,7 @@ class UrlTest extends \PHPUnit_Framework_TestCase
                 'menuConfig' => $this->_menuConfigMock,
                 'authSession' => $this->_authSessionMock,
                 'encryptor' => $this->_encryptor,
-                'routeParamsResolver' => $this->_paramsResolverMock
+                'routeParamsResolverFactory' => $this->_paramsResolverMock
             ]
         );
         $this->_paramsResolverMock->expects(
@@ -186,7 +186,7 @@ class UrlTest extends \PHPUnit_Framework_TestCase
                 'menuConfig' => $this->_menuConfigMock,
                 'authSession' => $this->_authSessionMock,
                 'encryptor' => $this->_encryptor,
-                'routeParamsResolver' => $this->_paramsResolverMock
+                'routeParamsResolverFactory' => $this->_paramsResolverMock
             ]
         );
 
@@ -259,7 +259,7 @@ class UrlTest extends \PHPUnit_Framework_TestCase
             [
                 'backendHelper' => $helperMock,
                 'authSession' => $this->_authSessionMock,
-                'routeParamsResolver' => $this->_paramsResolverMock
+                'routeParamsResolverFactory' => $this->_paramsResolverMock
             ]
         );
         $urlModel->getAreaFrontName();
diff --git a/app/code/Magento/Backend/composer.json b/app/code/Magento/Backend/composer.json
index d229a7feb44b54367af4b052d1c43bc2a8f7e517..d304a64899593b2b01303dd3e431a9c59fb47fbc 100644
--- a/app/code/Magento/Backend/composer.json
+++ b/app/code/Magento/Backend/composer.json
@@ -3,27 +3,27 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-directory": "0.74.0-beta6",
-        "magento/module-developer": "0.74.0-beta6",
-        "magento/module-eav": "0.74.0-beta6",
-        "magento/module-cron": "0.74.0-beta6",
-        "magento/module-theme": "0.74.0-beta6",
-        "magento/module-reports": "0.74.0-beta6",
-        "magento/module-sales": "0.74.0-beta6",
-        "magento/module-quote": "0.74.0-beta6",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/module-user": "0.74.0-beta6",
-        "magento/module-backup": "0.74.0-beta6",
-        "magento/module-customer": "0.74.0-beta6",
-        "magento/module-translation": "0.74.0-beta6",
-        "magento/module-require-js": "0.74.0-beta6",
-        "magento/module-config": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-directory": "0.74.0-beta7",
+        "magento/module-developer": "0.74.0-beta7",
+        "magento/module-eav": "0.74.0-beta7",
+        "magento/module-cron": "0.74.0-beta7",
+        "magento/module-theme": "0.74.0-beta7",
+        "magento/module-reports": "0.74.0-beta7",
+        "magento/module-sales": "0.74.0-beta7",
+        "magento/module-quote": "0.74.0-beta7",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/module-user": "0.74.0-beta7",
+        "magento/module-backup": "0.74.0-beta7",
+        "magento/module-customer": "0.74.0-beta7",
+        "magento/module-translation": "0.74.0-beta7",
+        "magento/module-require-js": "0.74.0-beta7",
+        "magento/module-config": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Backend/etc/adminhtml/di.xml b/app/code/Magento/Backend/etc/adminhtml/di.xml
index ba52677a683d9ee8e098cdd48bda87ddc128c2e9..553d30e85541f36dbd0a50834d1d146d99b84d5d 100644
--- a/app/code/Magento/Backend/etc/adminhtml/di.xml
+++ b/app/code/Magento/Backend/etc/adminhtml/di.xml
@@ -90,6 +90,24 @@
             <argument name="instanceName" xsi:type="string">Magento\Backend\Model\View\Result\Page</argument>
         </arguments>
     </type>
+    <type name="Magento\Framework\Controller\ResultFactory">
+        <arguments>
+            <argument name="typeMap" xsi:type="array">
+                <item name="redirect" xsi:type="array">
+                    <item name="type" xsi:type="const">Magento\Framework\Controller\ResultFactory::TYPE_REDIRECT</item>
+                    <item name="class" xsi:type="string">Magento\Backend\Model\View\Result\Redirect</item>
+                </item>
+                <item name="page" xsi:type="array">
+                    <item name="type" xsi:type="const">Magento\Framework\Controller\ResultFactory::TYPE_PAGE</item>
+                    <item name="class" xsi:type="string">Magento\Backend\Model\View\Result\Page</item>
+                </item>
+                <item name="forward" xsi:type="array">
+                    <item name="type" xsi:type="const">Magento\Framework\Controller\ResultFactory::TYPE_FORWARD</item>
+                    <item name="class" xsi:type="string">Magento\Backend\Model\View\Result\Forward</item>
+                </item>
+            </argument>
+        </arguments>
+    </type>
     <type name="Magento\Framework\View\Layout\BuilderFactory">
         <arguments>
             <argument name="typeMap" xsi:type="array">
diff --git a/app/code/Magento/Backend/view/adminhtml/templates/admin/login.phtml b/app/code/Magento/Backend/view/adminhtml/templates/admin/login.phtml
index 1d1cb81fd064a8dce77e3e6b76b8675672293118..12d8f0b32e94d50d64a55d9b687b84492af28c20 100644
--- a/app/code/Magento/Backend/view/adminhtml/templates/admin/login.phtml
+++ b/app/code/Magento/Backend/view/adminhtml/templates/admin/login.phtml
@@ -7,6 +7,7 @@
 // @codingStandardsIgnoreFile
 
 ?>
+
 <form method="post" action="" id="login-form" data-mage-init='{"form": {}, "validation": {}}' autocomplete="off">
     <fieldset class="admin__fieldset">
         <legend class="admin__legend"><span><?php echo __('Welcome, please sign in') ?></span></legend><br/>
@@ -14,15 +15,33 @@
         <div class="admin__field _required field-username">
             <label for="username" class="admin__field-label"><span><?php echo __('Username') ?></span></label>
             <div class="admin__field-control">
-                <input type="text" id="username" name="login[username]" autofocus value="" data-validate="{required:true}" class="admin__control-text" placeholder="<?php echo __('user name') ?>" />
+                <input
+                    id="username"
+                    class="admin__control-text"
+                    type="text"
+                    name="login[username]"
+                    autofocus
+                    value=""
+                    data-validate="{required:true}"
+                    placeholder="<?php echo __('user name') ?>"/>
             </div>
         </div>
         <div class="admin__field _required field-password">
             <label for="login" class="admin__field-label"><span><?php echo __('Password') ?></span></label>
             <div class="admin__field-control">
                 <!-- This is a dummy hidden field to trick firefox from auto filling the password -->
-                <input type="text" class="admin__control-dummy" name="dummy" id="dummy" />
-                <input type="password" id="login" name="login[password]" data-validate="{required:true}" class="admin__control-text" value="" placeholder="<?php echo __('password') ?>" />
+                <input
+                    id="dummy"
+                    class="admin__control-dummy"
+                    type="text"
+                    name="dummy"/>
+                <input
+                    id="login"
+                    class="admin__control-text"
+                    type="password"
+                    name="login[password]"
+                    data-validate="{required:true}"
+                    value="" placeholder="<?php echo __('password') ?>" />
             </div>
         </div>
         <?php echo $block->getChildHtml('form.additional.info'); ?>
diff --git a/app/code/Magento/Backend/view/adminhtml/templates/dashboard/grid.phtml b/app/code/Magento/Backend/view/adminhtml/templates/dashboard/grid.phtml
index 78d3d2677e94c705cc86af43d9562ff37aaacc6f..e9a724fdbf857b838c893142f1cd7c88e8276af3 100644
--- a/app/code/Magento/Backend/view/adminhtml/templates/dashboard/grid.phtml
+++ b/app/code/Magento/Backend/view/adminhtml/templates/dashboard/grid.phtml
@@ -14,7 +14,7 @@ $numColumns = sizeof($block->getColumns());
 <?php if ($block->getCollection()): ?>
 <div class="dashboard-item-content">
     <?php if ($block->getCollection()->getSize()>0): ?>
-        <table class="table-info dashboard-data" id="<?php echo $block->getId() ?>_table">
+        <table class="admin__table-primary dashboard-data" id="<?php echo $block->getId() ?>_table">
             <?php
             /* This part is commented to remove all <col> tags from the code. */
             /* foreach ($block->getColumns() as $_column): ?>
diff --git a/app/code/Magento/Backend/view/adminhtml/templates/page/header.phtml b/app/code/Magento/Backend/view/adminhtml/templates/page/header.phtml
index 6e90069f9ee6c87bfcc4119b16c78d46ecfd3583..8b60043de0f8d49b63f65ab771eef3a065fcfec6 100644
--- a/app/code/Magento/Backend/view/adminhtml/templates/page/header.phtml
+++ b/app/code/Magento/Backend/view/adminhtml/templates/page/header.phtml
@@ -21,18 +21,18 @@
         </a>
     <?php break; ?>
     <?php case 'user': ?>
-        <div class="admin-user">
+        <div class="admin-user admin__action-dropdown-wrap">
             <a
                 href="<?php echo $block->getUrl('adminhtml/system_account/index') ?>"
-                class="admin-user-account"
+                class="admin__action-dropdown"
                 title="<?php echo $block->escapeHtml(__('My Account')) ?>"
                 data-mage-init='{"dropdown":{}}'
                 data-toggle="dropdown">
-                <span class="admin-user-account-text-wrapper">
+                <span class="admin__action-dropdown-text">
                     <span class="admin-user-account-text"><?php echo $block->escapeHtml($block->getUser()->getUsername()); ?></span>
                 </span>
             </a>
-            <ul class="admin-user-menu">
+            <ul class="admin__action-dropdown-menu">
                 <?php if ($block->getAuthorization()->isAllowed('Magento_Backend::myaccount')): ?>
                 <li>
                     <a
diff --git a/app/code/Magento/Backup/README.md b/app/code/Magento/Backup/README.md
index 661f8a5d6ddd86f23772c9f595526420ae51dd9e..59688ea3e716e162e8efa9421de0ffe004ec3cee 100644
--- a/app/code/Magento/Backup/README.md
+++ b/app/code/Magento/Backup/README.md
@@ -1,3 +1,3 @@
 The Backup module allows administrators to perform backups and rollbacks. Types of backups include system, database and media backups. This module relies on the Cron module to schedule backups.
 
-This module does not effect the storefront.
\ No newline at end of file
+This module does not affect the storefront.
diff --git a/app/code/Magento/Backup/composer.json b/app/code/Magento/Backup/composer.json
index f7f9a0371534346f0bc39f7d7087a12200428386..e562c51a28780fef47745fed5db8c70162f3417a 100644
--- a/app/code/Magento/Backup/composer.json
+++ b/app/code/Magento/Backup/composer.json
@@ -3,14 +3,14 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-cron": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-cron": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Backup/view/adminhtml/layout/backup_index_block.xml b/app/code/Magento/Backup/view/adminhtml/layout/backup_index_block.xml
index 861bc2050e44a61e3cf1daf950dcad8fc05d0997..1553a783f6356dca8510044813cd919312ff5fdb 100644
--- a/app/code/Magento/Backup/view/adminhtml/layout/backup_index_block.xml
+++ b/app/code/Magento/Backup/view/adminhtml/layout/backup_index_block.xml
@@ -46,7 +46,6 @@
                         <arguments>
                             <argument name="header" xsi:type="string" translate="true">Name</argument>
                             <argument name="index" xsi:type="string">display_name</argument>
-                            <argument name="filter" xsi:type="string">0</argument>
                             <argument name="sortable" xsi:type="string">1</argument>
                             <argument name="column_css_class" xsi:type="string">col-name</argument>
                             <argument name="header_css_class" xsi:type="string">col-name</argument>
diff --git a/app/code/Magento/Bundle/composer.json b/app/code/Magento/Bundle/composer.json
index a16b4ad6d56cfb1002fae21f984ace5e9a5ea588..07f3110b0c936a3d3a3cdfac5dcf640aaf6b7c1e 100644
--- a/app/code/Magento/Bundle/composer.json
+++ b/app/code/Magento/Bundle/composer.json
@@ -3,28 +3,28 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/module-tax": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-sales": "0.74.0-beta6",
-        "magento/module-checkout": "0.74.0-beta6",
-        "magento/module-catalog-inventory": "0.74.0-beta6",
-        "magento/module-customer": "0.74.0-beta6",
-        "magento/module-catalog-rule": "0.74.0-beta6",
-        "magento/module-eav": "0.74.0-beta6",
-        "magento/module-config": "0.74.0-beta6",
-        "magento/module-gift-message": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
-        "magento/module-quote": "0.74.0-beta6",
-        "magento/module-media-storage": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/module-tax": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-sales": "0.74.0-beta7",
+        "magento/module-checkout": "0.74.0-beta7",
+        "magento/module-catalog-inventory": "0.74.0-beta7",
+        "magento/module-customer": "0.74.0-beta7",
+        "magento/module-catalog-rule": "0.74.0-beta7",
+        "magento/module-eav": "0.74.0-beta7",
+        "magento/module-config": "0.74.0-beta7",
+        "magento/module-gift-message": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
+        "magento/module-quote": "0.74.0-beta7",
+        "magento/module-media-storage": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "suggest": {
-        "magento/module-webapi": "0.74.0-beta6"
+        "magento/module-webapi": "0.74.0-beta7"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Bundle/etc/data_object.xml b/app/code/Magento/Bundle/etc/service_data_attributes.xml
similarity index 70%
rename from app/code/Magento/Bundle/etc/data_object.xml
rename to app/code/Magento/Bundle/etc/service_data_attributes.xml
index 2b3da013978f971bb20baca3a5e0ca95f2b501fc..8150a2dceeddd7d70d4e16ffa3d1b6996f316d5d 100644
--- a/app/code/Magento/Bundle/etc/data_object.xml
+++ b/app/code/Magento/Bundle/etc/service_data_attributes.xml
@@ -5,8 +5,8 @@
  * See COPYING.txt for license details.
  */
 -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Api/etc/data_object.xsd">
-    <custom_attributes for="Magento\Catalog\Api\Data\ProductInterface">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Api/etc/service_data_attributes.xsd">
+    <extension_attributes for="Magento\Catalog\Api\Data\ProductInterface">
         <attribute code="bundle_product_options" type="Magento\Bundle\Api\Data\OptionInterface[]" />
-    </custom_attributes>
+    </extension_attributes>
 </config>
diff --git a/app/code/Magento/Bundle/view/adminhtml/templates/product/composite/fieldset/options/bundle.phtml b/app/code/Magento/Bundle/view/adminhtml/templates/product/composite/fieldset/options/bundle.phtml
index 73d5d50ee6574c39c785bb19b5c59977faf7d54c..c1f89d31bf4b7f5373a4538aa402470328621606 100644
--- a/app/code/Magento/Bundle/view/adminhtml/templates/product/composite/fieldset/options/bundle.phtml
+++ b/app/code/Magento/Bundle/view/adminhtml/templates/product/composite/fieldset/options/bundle.phtml
@@ -11,7 +11,8 @@
 <?php /* @var $block \Magento\Bundle\Block\Adminhtml\Catalog\Product\Composite\Fieldset\Bundle */ ?>
 <?php $options = $block->decorateArray($block->getOptions()); ?>
 <?php if (count($options)): ?>
-<fieldset id="catalog_product_composite_configure_fields_bundle" class="fieldset admin__fieldset composite-bundle <?php echo $block->getIsLastFieldset() ? ' last-fieldset' : '' ?>">
+<fieldset id="catalog_product_composite_configure_fields_bundle"
+          class="fieldset admin__fieldset composite-bundle<?php echo $block->getIsLastFieldset() ? ' last-fieldset' : '' ?>">
     <legend class="legend admin__legend"><span><?php echo __('Bundle Items') ?></span></legend><br />
     <?php foreach ($options as $option) : ?>
         <?php if ($option->getSelections()) : ?>
diff --git a/app/code/Magento/Bundle/view/adminhtml/templates/sales/creditmemo/create/items/renderer.phtml b/app/code/Magento/Bundle/view/adminhtml/templates/sales/creditmemo/create/items/renderer.phtml
index 6986d5ab2953413e6dc7d7ae5a3bd3c168f834f7..1179737cea667d6e059ea35b4add49db3264d4a2 100644
--- a/app/code/Magento/Bundle/view/adminhtml/templates/sales/creditmemo/create/items/renderer.phtml
+++ b/app/code/Magento/Bundle/view/adminhtml/templates/sales/creditmemo/create/items/renderer.phtml
@@ -50,8 +50,8 @@
         <?php if (!$_item->getOrderItem()->getParentItem()): ?>
         <td class="col-product">
             <div class="product-title"><?php echo $block->escapeHtml($_item->getName()) ?></div>
-            <div>
-                <strong><?php echo __('SKU') ?>:</strong>
+            <div class="product-sku-block">
+                <span><?php echo __('SKU') ?>:</span>
                 <?php echo implode('<br />', $this->helper('Magento\Catalog\Helper\Data')->splitSku($block->escapeHtml($_item->getSku()))); ?>
             </div>
         </td>
@@ -67,46 +67,46 @@
         </td>
         <td class="col-ordered-qty">
             <?php if ($block->canShowPriceInfo($_item)): ?>
-                <table cellspacing="0" class="qty-table">
+                <table class="data-table qty-table">
                     <tr>
-                        <td><?php echo __('Ordered') ?></td>
-                        <td><strong><?php echo $_item->getOrderItem()->getQtyOrdered()*1 ?></strong></td>
+                        <th><?php echo __('Ordered') ?></th>
+                        <td><?php echo $_item->getOrderItem()->getQtyOrdered()*1 ?></td>
                     </tr>
                     <?php if ((float) $_item->getOrderItem()->getQtyInvoiced()): ?>
                     <tr>
-                        <td><?php echo __('Invoiced') ?></td>
-                        <td><strong><?php echo $_item->getOrderItem()->getQtyInvoiced()*1 ?></strong></td>
+                        <th><?php echo __('Invoiced') ?></th>
+                        <td><?php echo $_item->getOrderItem()->getQtyInvoiced()*1 ?></td>
                     </tr>
                     <?php endif; ?>
                     <?php if ((float) $_item->getOrderItem()->getQtyShipped() && $block->isShipmentSeparately($_item)): ?>
                     <tr>
-                        <td><?php echo __('Shipped') ?></td>
-                        <td><strong><?php echo $_item->getOrderItem()->getQtyShipped()*1 ?></strong></td>
+                        <th><?php echo __('Shipped') ?></th>
+                        <td><?php echo $_item->getOrderItem()->getQtyShipped()*1 ?></td>
                     </tr>
                     <?php endif; ?>
                     <?php if ((float) $_item->getOrderItem()->getQtyRefunded()): ?>
                     <tr>
-                        <td><?php echo __('Refunded') ?></td>
-                        <td><strong><?php echo $_item->getOrderItem()->getQtyRefunded()*1 ?></strong></td>
+                        <th><?php echo __('Refunded') ?></th>
+                        <td><?php echo $_item->getOrderItem()->getQtyRefunded()*1 ?></td>
                     </tr>
                     <?php endif; ?>
                     <?php if ((float) $_item->getOrderItem()->getQtyCanceled()): ?>
                     <tr>
-                        <td><?php echo __('Canceled') ?></td>
-                        <td><strong><?php echo $_item->getOrderItem()->getQtyCanceled()*1 ?></strong></td>
+                        <th><?php echo __('Canceled') ?></th>
+                        <td><?php echo $_item->getOrderItem()->getQtyCanceled()*1 ?></td>
                     </tr>
                     <?php endif; ?>
                 </table>
             <?php elseif ($block->isShipmentSeparately($_item)): ?>
-                <table cellspacing="0" class="qty-table">
+                <table class="data-table qty-table">
                     <tr>
-                        <td><?php echo __('Ordered') ?></td>
-                        <td><strong><?php echo $_item->getOrderItem()->getQtyOrdered()*1 ?></strong></td>
+                        <th><?php echo __('Ordered') ?></th>
+                        <td><?php echo $_item->getOrderItem()->getQtyOrdered()*1 ?></td>
                     </tr>
                     <?php if ((float) $_item->getOrderItem()->getQtyShipped()): ?>
                     <tr>
-                        <td><?php echo __('Shipped') ?></td>
-                        <td><strong><?php echo $_item->getOrderItem()->getQtyShipped()*1 ?></strong></td>
+                        <th><?php echo __('Shipped') ?></th>
+                        <td><?php echo $_item->getOrderItem()->getQtyShipped()*1 ?></td>
                     </tr>
                     <?php endif; ?>
                 </table>
@@ -118,17 +118,24 @@
         <td class="col-return-to-stock">
             <?php if ($block->canShowPriceInfo($_item)): ?>
                 <?php if ($block->canReturnItemToStock($_item)) : ?>
-                    <input type="checkbox" name="creditmemo[items][<?php echo $_item->getOrderItemId() ?>][back_to_stock]" value="1"<?php if ($_item->getBackToStock()):?> checked="checked"<?php endif;?> />
+                    <input type="checkbox"
+                           class="admin__control-checkbox"
+                           name="creditmemo[items][<?php echo $_item->getOrderItemId() ?>][back_to_stock]"
+                           value="1"<?php if ($_item->getBackToStock()):?> checked="checked"<?php endif;?> />
+                    <label class="admin__field-label"></label>
                 <?php endif; ?>
             <?php else: ?>
                 &nbsp;
             <?php endif; ?>
         </td>
         <?php endif; ?>
-        <td class="col-refund">
+        <td class="col-refund col-qty">
             <?php if ($block->canShowPriceInfo($_item)): ?>
                 <?php if ($block->canEditQty()) : ?>
-                    <input type="text" class="input-text qty-input" name="creditmemo[items][<?php echo $_item->getOrderItemId() ?>][qty]" value="<?php echo $_item->getQty()*1 ?>" />
+                    <input type="text"
+                           class="input-text admin__control-text qty-input"
+                           name="creditmemo[items][<?php echo $_item->getOrderItemId() ?>][qty]"
+                           value="<?php echo $_item->getQty()*1 ?>" />
                 <?php else: ?>
                     <?php echo $_item->getQty()*1 ?>
                 <?php endif; ?>
diff --git a/app/code/Magento/Bundle/view/adminhtml/templates/sales/creditmemo/view/items/renderer.phtml b/app/code/Magento/Bundle/view/adminhtml/templates/sales/creditmemo/view/items/renderer.phtml
index 37b22d2d43a2b046b225e2a2b247efc230ac5663..339bc32af067a91741ffcf2945265f7696177ecd 100644
--- a/app/code/Magento/Bundle/view/adminhtml/templates/sales/creditmemo/view/items/renderer.phtml
+++ b/app/code/Magento/Bundle/view/adminhtml/templates/sales/creditmemo/view/items/renderer.phtml
@@ -48,8 +48,8 @@
         <?php if (!$_item->getOrderItem()->getParentItem()): ?>
         <td class="col-product">
             <div class="product-title"><?php echo $block->escapeHtml($_item->getName()) ?></div>
-            <div>
-                <strong><?php echo __('SKU') ?>:</strong>
+            <div class="product-sku-block">
+                <span><?php echo __('SKU') ?>:</span>
                 <?php echo implode('<br />', $this->helper('Magento\Catalog\Helper\Data')->splitSku($block->escapeHtml($_item->getSku()))); ?>
             </div>
         </td>
diff --git a/app/code/Magento/Bundle/view/adminhtml/templates/sales/invoice/create/items/renderer.phtml b/app/code/Magento/Bundle/view/adminhtml/templates/sales/invoice/create/items/renderer.phtml
index 5ad5c664845271785c65c01e01aa961591b6c333..ffabb6efc13ddf417d9fccb35aacdbec50099598 100644
--- a/app/code/Magento/Bundle/view/adminhtml/templates/sales/invoice/create/items/renderer.phtml
+++ b/app/code/Magento/Bundle/view/adminhtml/templates/sales/invoice/create/items/renderer.phtml
@@ -49,8 +49,8 @@
         <?php if (!$_item->getOrderItem()->getParentItem()): ?>
         <td class="col-product">
             <div class="product-title"><?php echo $block->escapeHtml($_item->getName()) ?></div>
-            <div>
-                <strong><?php echo __('SKU') ?>:</strong>
+            <div class="product-sku-block">
+                <span><?php echo __('SKU') ?>:</span>
                 <?php echo implode('<br />', $this->helper('Magento\Catalog\Helper\Data')->splitSku($block->escapeHtml($_item->getSku()))); ?>
             </div>
         </td>
@@ -68,46 +68,46 @@
         </td>
         <td class="col-qty">
             <?php if ($block->canShowPriceInfo($_item)): ?>
-                <table cellspacing="0" class="qty-table">
+                <table class="data-table qty-table">
                     <tr>
-                        <td><?php echo __('Ordered') ?></td>
+                        <th><?php echo __('Ordered') ?></th>
                         <td><strong><?php echo $_item->getOrderItem()->getQtyOrdered()*1 ?></strong></td>
                     </tr>
                     <?php if ((float) $_item->getOrderItem()->getQtyInvoiced()): ?>
                     <tr>
-                        <td><?php echo __('Invoiced') ?></td>
-                        <td><strong><?php echo $_item->getOrderItem()->getQtyInvoiced()*1 ?></strong></td>
+                        <th><?php echo __('Invoiced') ?></th>
+                        <td><?php echo $_item->getOrderItem()->getQtyInvoiced()*1 ?></td>
                     </tr>
                     <?php endif; ?>
                     <?php if ((float) $_item->getOrderItem()->getQtyShipped() && $block->isShipmentSeparately($_item)): ?>
                     <tr>
-                        <td><?php echo __('Shipped') ?></td>
-                        <td><strong><?php echo $_item->getOrderItem()->getQtyShipped()*1 ?></strong></td>
+                        <th><?php echo __('Shipped') ?></th>
+                        <td><?php echo $_item->getOrderItem()->getQtyShipped()*1 ?></td>
                     </tr>
                     <?php endif; ?>
                     <?php if ((float) $_item->getOrderItem()->getQtyRefunded()): ?>
                     <tr>
-                        <td><?php echo __('Refunded') ?></td>
-                        <td><strong><?php echo $_item->getOrderItem()->getQtyRefunded()*1 ?></strong></td>
+                        <th><?php echo __('Refunded') ?></th>
+                        <td><?php echo $_item->getOrderItem()->getQtyRefunded()*1 ?></td>
                     </tr>
                     <?php endif; ?>
                     <?php if ((float) $_item->getOrderItem()->getQtyCanceled()): ?>
                     <tr>
-                        <td><?php echo __('Canceled') ?></td>
-                        <td><strong><?php echo $_item->getOrderItem()->getQtyCanceled()*1 ?></strong></td>
+                        <th><?php echo __('Canceled') ?></th>
+                        <td><?php echo $_item->getOrderItem()->getQtyCanceled()*1 ?></td>
                     </tr>
                     <?php endif; ?>
                 </table>
             <?php elseif ($block->isShipmentSeparately($_item)): ?>
-                <table cellspacing="0" class="qty-table">
+                <table class="data-table qty-table">
                     <tr>
-                        <td><?php echo __('Ordered') ?></td>
-                        <td><strong><?php echo $_item->getOrderItem()->getQtyOrdered()*1 ?></strong></td>
+                        <th><?php echo __('Ordered') ?></th>
+                        <td><?php echo $_item->getOrderItem()->getQtyOrdered()*1 ?></td>
                     </tr>
                     <?php if ((float) $_item->getOrderItem()->getQtyShipped()): ?>
                     <tr>
-                        <td><?php echo __('Shipped') ?></td>
-                        <td><strong><?php echo $_item->getOrderItem()->getQtyShipped()*1 ?></strong></td>
+                        <th><?php echo __('Shipped') ?></th>
+                        <td><?php echo $_item->getOrderItem()->getQtyShipped()*1 ?></td>
                     </tr>
                     <?php endif; ?>
                 </table>
@@ -118,7 +118,10 @@
         <td class="col-qty-invoice">
             <?php if ($block->canShowPriceInfo($_item)): ?>
                 <?php if ($block->canEditQty()) : ?>
-                    <input type="text" class="input-text qty-input" name="invoice[items][<?php echo $_item->getOrderItemId() ?>]" value="<?php echo $_item->getQty()*1 ?>" />
+                    <input type="text"
+                           class="input-text admin__control-text qty-input"
+                           name="invoice[items][<?php echo $_item->getOrderItemId() ?>]"
+                           value="<?php echo $_item->getQty()*1 ?>" />
                 <?php else : ?>
                     <?php echo $_item->getQty()*1 ?>
                 <?php endif; ?>
diff --git a/app/code/Magento/Bundle/view/adminhtml/templates/sales/invoice/view/items/renderer.phtml b/app/code/Magento/Bundle/view/adminhtml/templates/sales/invoice/view/items/renderer.phtml
index 33db5d905cf3acebb353d935c8665e76c5f455fc..904d804580feace61ab761f2daaf284fc712b64c 100644
--- a/app/code/Magento/Bundle/view/adminhtml/templates/sales/invoice/view/items/renderer.phtml
+++ b/app/code/Magento/Bundle/view/adminhtml/templates/sales/invoice/view/items/renderer.phtml
@@ -48,8 +48,8 @@
         <?php if (!$_item->getOrderItem()->getParentItem()): ?>
         <td class="col-product">
             <div class="product-title"><?php echo $block->escapeHtml($_item->getName()) ?></div>
-            <div>
-                <strong><?php echo __('SKU') ?>:</strong>
+            <div class="product-sku-block">
+                <span><?php echo __('SKU') ?>:</span>
                 <?php echo implode('<br />', $this->helper('Magento\Catalog\Helper\Data')->splitSku($block->escapeHtml($_item->getSku()))); ?>
             </div>
         <?php else: ?>
diff --git a/app/code/Magento/Bundle/view/adminhtml/templates/sales/order/view/items/renderer.phtml b/app/code/Magento/Bundle/view/adminhtml/templates/sales/order/view/items/renderer.phtml
index 8c89a6e27c5cf1c22168dd930127ad3efb3d97c5..2f31655de1e2eaa36a24aeb73c80812725ba71e0 100644
--- a/app/code/Magento/Bundle/view/adminhtml/templates/sales/order/view/items/renderer.phtml
+++ b/app/code/Magento/Bundle/view/adminhtml/templates/sales/order/view/items/renderer.phtml
@@ -53,8 +53,8 @@
             <div class="product-title" id="order_item_<?php echo $_item->getId() ?>_title">
                 <?php echo $block->escapeHtml($_item->getName()) ?>
             </div>
-            <div>
-                <strong><?php echo __('SKU') ?>:</strong>
+            <div class="product-sku-block">
+                <span><?php echo __('SKU') ?>:</span>
                 <?php echo implode('<br />', $this->helper('Magento\Catalog\Helper\Data')->splitSku($block->escapeHtml($_item->getSku()))); ?>
             </div>
         </td>
@@ -86,46 +86,46 @@
         </td>
         <td class="col-ordered-qty">
             <?php if ($block->canShowPriceInfo($_item)): ?>
-                <table cellspacing="0" class="qty-table">
+                <table class="data-table qty-table">
                     <tr>
-                        <td><?php echo __('Ordered') ?></td>
-                        <td><strong><?php echo $_item->getQtyOrdered()*1 ?></strong></td>
+                        <th><?php echo __('Ordered') ?></th>
+                        <td><?php echo $_item->getQtyOrdered()*1 ?></td>
                     </tr>
                     <?php if ((float) $_item->getQtyInvoiced()): ?>
                     <tr>
-                        <td><?php echo __('Invoiced') ?></td>
-                        <td><strong><?php echo $_item->getQtyInvoiced()*1 ?></strong></td>
+                        <th><?php echo __('Invoiced') ?></th>
+                        <td><?php echo $_item->getQtyInvoiced()*1 ?></td>
                     </tr>
                     <?php endif; ?>
                     <?php if ((float) $_item->getQtyShipped() && $block->isShipmentSeparately($_item)): ?>
                     <tr>
-                        <td><?php echo __('Shipped') ?></td>
-                        <td><strong><?php echo $_item->getQtyShipped()*1 ?></strong></td>
+                        <th><?php echo __('Shipped') ?></th>
+                        <td><?php echo $_item->getQtyShipped()*1 ?></td>
                     </tr>
                     <?php endif; ?>
                     <?php if ((float) $_item->getQtyRefunded()): ?>
                     <tr>
-                        <td><?php echo __('Refunded') ?></td>
-                        <td><strong><?php echo $_item->getQtyRefunded()*1 ?></strong></td>
+                        <th><?php echo __('Refunded') ?></th>
+                        <td><?php echo $_item->getQtyRefunded()*1 ?></td>
                     </tr>
                     <?php endif; ?>
                     <?php if ((float) $_item->getQtyCanceled()): ?>
                     <tr>
-                        <td><?php echo __('Canceled') ?></td>
-                        <td><strong><?php echo $_item->getQtyCanceled()*1 ?></strong></td>
+                        <th><?php echo __('Canceled') ?></th>
+                        <td><?php echo $_item->getQtyCanceled()*1 ?></td>
                     </tr>
                     <?php endif; ?>
                 </table>
             <?php elseif ($block->isShipmentSeparately($_item)): ?>
-                <table cellspacing="0" class="qty-table">
+                <table class="data-table qty-table">
                     <tr>
-                        <td><?php echo __('Ordered') ?></td>
-                        <td><strong><?php echo $_item->getQtyOrdered()*1 ?></strong></td>
+                        <th><?php echo __('Ordered') ?></th>
+                        <td><?php echo $_item->getQtyOrdered()*1 ?></td>
                     </tr>
                     <?php if ((float) $_item->getQtyShipped()): ?>
                     <tr>
-                        <td><?php echo __('Shipped') ?></td>
-                        <td><strong><?php echo $_item->getQtyShipped()*1 ?></strong></td>
+                        <th><?php echo __('Shipped') ?></th>
+                        <td><?php echo $_item->getQtyShipped()*1 ?></td>
                     </tr>
                     <?php endif; ?>
                 </table>
diff --git a/app/code/Magento/Bundle/view/adminhtml/templates/sales/shipment/create/items/renderer.phtml b/app/code/Magento/Bundle/view/adminhtml/templates/sales/shipment/create/items/renderer.phtml
index 08ef77d9161508a2601fe4ff14fb2ae2ab093e98..f1555682244ee4ba68b1d7e6202f2d9b66f884bc 100644
--- a/app/code/Magento/Bundle/view/adminhtml/templates/sales/shipment/create/items/renderer.phtml
+++ b/app/code/Magento/Bundle/view/adminhtml/templates/sales/shipment/create/items/renderer.phtml
@@ -43,8 +43,8 @@
         <?php if (!$_item->getOrderItem()->getParentItem()): ?>
         <td class="col-product">
             <div class="product-title"><?php echo $block->escapeHtml($_item->getName()) ?></div>
-            <div>
-                <strong><?php echo __('SKU') ?>:</strong>
+            <div class="product-sku-block">
+                <span><?php echo __('SKU') ?>:</span>
                 <?php echo implode('<br />', $this->helper('Magento\Catalog\Helper\Data')->splitSku($block->escapeHtml($_item->getSku()))); ?>
             </div>
         </td>
@@ -60,7 +60,10 @@
         </td>
         <td class="col-qty last">
             <?php if ($block->isShipmentSeparately($_item)): ?>
-                <input type="text" class="input-text" name="shipment[items][<?php echo $_item->getOrderItemId() ?>]" value="<?php echo $_item->getQty()*1 ?>" />
+                <input type="text"
+                       class="input-text admin__control-text"
+                       name="shipment[items][<?php echo $_item->getOrderItemId() ?>]"
+                       value="<?php echo $_item->getQty()*1 ?>" />
             <?php else: ?>
                 &nbsp;
             <?php endif; ?>
diff --git a/app/code/Magento/Bundle/view/adminhtml/templates/sales/shipment/view/items/renderer.phtml b/app/code/Magento/Bundle/view/adminhtml/templates/sales/shipment/view/items/renderer.phtml
index 16c98a2522059be6648f1c36364584dca4a26ac7..e8a2d69f16530de18698e5808cc57591fb420bb2 100644
--- a/app/code/Magento/Bundle/view/adminhtml/templates/sales/shipment/view/items/renderer.phtml
+++ b/app/code/Magento/Bundle/view/adminhtml/templates/sales/shipment/view/items/renderer.phtml
@@ -43,8 +43,8 @@
         <?php if (!$_item->getParentItem()): ?>
         <td class="col-product">
             <div class="product-title"><?php echo $block->escapeHtml($_item->getName()) ?></div>
-            <div>
-                <strong><?php echo __('SKU') ?>:</strong>
+            <div class="product-sku-block">
+                <span><?php echo __('SKU') ?>:</span>
                 <?php echo implode('<br />', $this->helper('Magento\Catalog\Helper\Data')->splitSku($block->escapeHtml($_item->getSku()))); ?>
             </div>
         </td>
diff --git a/app/code/Magento/CacheInvalidate/composer.json b/app/code/Magento/CacheInvalidate/composer.json
index 4e1062c5a74902db562b9e2c7ed010ff9ab5bdfa..31eb21d58f55a24acfd34f0b5ca9623adead22f0 100644
--- a/app/code/Magento/CacheInvalidate/composer.json
+++ b/app/code/Magento/CacheInvalidate/composer.json
@@ -3,12 +3,12 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-page-cache": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-page-cache": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Captcha/composer.json b/app/code/Magento/Captcha/composer.json
index dee103fd89226bade4029e318d5b99fd03bf2b30..d1ee6a69a432e98b832400e6b8bd3143bb7531cb 100644
--- a/app/code/Magento/Captcha/composer.json
+++ b/app/code/Magento/Captcha/composer.json
@@ -3,15 +3,15 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-customer": "0.74.0-beta6",
-        "magento/module-checkout": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-customer": "0.74.0-beta7",
+        "magento/module-checkout": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Captcha/view/adminhtml/templates/default.phtml b/app/code/Magento/Captcha/view/adminhtml/templates/default.phtml
index d862e010441d261c1f906fc79dc8f28a9db1de57..d8811b0a29338951f610ca182a481d368745f3de 100644
--- a/app/code/Magento/Captcha/view/adminhtml/templates/default.phtml
+++ b/app/code/Magento/Captcha/view/adminhtml/templates/default.phtml
@@ -11,9 +11,16 @@
 <?php /* @var $block \Magento\Captcha\Block\Captcha\DefaultCaptcha */ ?>
 <?php $captcha = $block->getCaptchaModel() ?>
 <div class="admin__field _required">
-    <label for="captcha" class="admin__field-label"><span><?php echo __('Please enter the letters from the image') ?></span></label>
+    <label for="captcha" class="admin__field-label">
+        <span><?php echo __('Please enter the letters from the image') ?></span>
+    </label>
     <div class="admin__field-control">
-        <input type="text" name="<?php echo \Magento\Captcha\Helper\Data::INPUT_NAME_FIELD_VALUE ?>[<?php echo $block->getFormId()?>]" id="captcha" data-validate="{required:true}" class="admin__control-text"/>
+        <input
+            id="captcha"
+            class="admin__control-text"
+            type="text"
+            name="<?php echo \Magento\Captcha\Helper\Data::INPUT_NAME_FIELD_VALUE ?>[<?php echo $block->getFormId()?>]"
+            data-validate="{required:true}"/>
         <?php if ($captcha->isCaseSensitive()) :?>
             <div class="admin__field-note">
                 <span><?php echo __('<strong>Attention</strong>: Captcha is case sensitive.') ?></span>
@@ -22,8 +29,16 @@
     </div>
 </div>
 <div class="admin__field field-captcha">
-    <img id="captcha-reload" class="captcha-reload" src="<?php echo $block->getViewFileUrl('Magento_Captcha::reload.png') ?>" alt="<?php echo __('Reload captcha') ?>"/>
-    <img id="<?php echo $block->getFormId() ?>" width="<?php echo $block->getImgWidth() ?>" height="<?php echo $block->getImgHeight() ?>" src="<?php echo $captcha->getImgSrc() ?>" />
+    <img
+        id="captcha-reload"
+        class="captcha-reload"
+        src="<?php echo $block->getViewFileUrl('Magento_Captcha::reload.png') ?>"
+        alt="<?php echo __('Reload captcha') ?>"/>
+    <img
+        id="<?php echo $block->getFormId() ?>"
+        width="<?php echo $block->getImgWidth() ?>"
+        height="<?php echo $block->getImgHeight() ?>"
+        src="<?php echo $captcha->getImgSrc() ?>" />
 </div>
 <script>
     require(["prototype", "mage/captcha"], function(){
diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php
index a79466c6007bfb13a619d59a922c29d99d947968..29be0868558ee450d152d492091f5cb5b9bbaef8 100644
--- a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php
+++ b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php
@@ -29,7 +29,7 @@ class Toolbar extends \Magento\Framework\View\Element\Template
      *
      * @var array
      */
-    protected $_availableOrder = [];
+    protected $_availableOrder = null;
 
     /**
      * List of available view types
@@ -146,19 +146,6 @@ class Toolbar extends \Magento\Framework\View\Element\Template
         parent::__construct($context, $data);
     }
 
-    /**
-     * Init Toolbar
-     *
-     * @return null
-     */
-    protected function _construct()
-    {
-        parent::_construct();
-        $this->_orderField = $this->_productListHelper->getDefaultSortField();
-        $this->_availableOrder = $this->_catalogConfig->getAttributeUsedForSortByArray();
-        $this->_availableMode = $this->_productListHelper->getAvailableViewMode();
-    }
-
     /**
      * Disable list state params memorizing
      *
@@ -241,7 +228,7 @@ class Toolbar extends \Magento\Framework\View\Element\Template
         }
 
         $orders = $this->getAvailableOrders();
-        $defaultOrder = $this->_orderField;
+        $defaultOrder = $this->getOrderField();
 
         if (!isset($orders[$defaultOrder])) {
             $keys = array_keys($orders);
@@ -295,6 +282,7 @@ class Toolbar extends \Magento\Framework\View\Element\Template
      */
     public function setDefaultOrder($field)
     {
+        $this->loadAvailableOrders();
         if (isset($this->_availableOrder[$field])) {
             $this->_orderField = $field;
         }
@@ -322,6 +310,7 @@ class Toolbar extends \Magento\Framework\View\Element\Template
      */
     public function getAvailableOrders()
     {
+        $this->loadAvailableOrders();
         return $this->_availableOrder;
     }
 
@@ -346,6 +335,7 @@ class Toolbar extends \Magento\Framework\View\Element\Template
      */
     public function addOrderToAvailableOrders($order, $value)
     {
+        $this->loadAvailableOrders();
         $this->_availableOrder[$order] = $value;
         return $this;
     }
@@ -358,6 +348,7 @@ class Toolbar extends \Magento\Framework\View\Element\Template
      */
     public function removeOrderFromAvailableOrders($order)
     {
+        $this->loadAvailableOrders();
         if (isset($this->_availableOrder[$order])) {
             unset($this->_availableOrder[$order]);
         }
@@ -411,7 +402,7 @@ class Toolbar extends \Magento\Framework\View\Element\Template
         if ($mode) {
             return $mode;
         }
-        $defaultMode = $this->_productListHelper->getDefaultViewMode($this->_availableMode);
+        $defaultMode = $this->_productListHelper->getDefaultViewMode($this->getModes());
         $mode = $this->_toolbarModel->getMode();
         if (!$mode || !isset($this->_availableMode[$mode])) {
             $mode = $defaultMode;
@@ -439,6 +430,9 @@ class Toolbar extends \Magento\Framework\View\Element\Template
      */
     public function getModes()
     {
+        if ($this->_availableMode === []) {
+            $this->_availableMode = $this->_productListHelper->getAvailableViewMode();
+        }
         return $this->_availableMode;
     }
 
@@ -450,6 +444,7 @@ class Toolbar extends \Magento\Framework\View\Element\Template
      */
     public function setModes($modes)
     {
+        $this->getModes();
         if (!isset($this->_availableMode)) {
             $this->_availableMode = $modes;
         }
@@ -691,4 +686,30 @@ class Toolbar extends \Magento\Framework\View\Element\Template
         $options = array_replace_recursive($options, $customOptions);
         return json_encode(['productListToolbarForm' => $options]);
     }
+
+    /**
+     * Get order field
+     *
+     * @return null|string
+     */
+    protected function getOrderField()
+    {
+        if ($this->_orderField === null) {
+            $this->_orderField = $this->_productListHelper->getDefaultSortField();
+        }
+        return $this->_orderField;
+    }
+
+    /**
+     * Load Available Orders
+     *
+     * @return $this
+     */
+    private function loadAvailableOrders()
+    {
+        if ($this->_availableOrder === null) {
+            $this->_availableOrder = $this->_catalogConfig->getAttributeUsedForSortByArray();
+        }
+        return $this;
+    }
 }
diff --git a/app/code/Magento/Catalog/Block/Product/View/Options.php b/app/code/Magento/Catalog/Block/Product/View/Options.php
index f80bdede71af34f4440d8cce9ff14da2ebfdf9f0..db3d2a911038295fbcb8942d7c61f0041a2637a5 100644
--- a/app/code/Magento/Catalog/Block/Product/View/Options.php
+++ b/app/code/Magento/Catalog/Block/Product/View/Options.php
@@ -206,19 +206,30 @@ class Options extends \Magento\Framework\View\Element\Template
             /* @var $option \Magento\Catalog\Model\Product\Option */
             $priceValue = 0;
             if ($option->getGroupByType() == \Magento\Catalog\Model\Product\Option::OPTION_GROUP_SELECT) {
-                $_tmpPriceValues = [];
+                $tmpPriceValues = [];
                 foreach ($option->getValues() as $value) {
                     /* @var $value \Magento\Catalog\Model\Product\Option\Value */
                     $id = $value->getId();
-                    $_tmpPriceValues[$id] = $this->_getPriceConfiguration($value);
+                    $tmpPriceValues[$id] = $this->_getPriceConfiguration($value);
                 }
-                $priceValue = $_tmpPriceValues;
+                $priceValue = $tmpPriceValues;
             } else {
                 $priceValue = $this->_getPriceConfiguration($option);
             }
             $config[$option->getId()] = $priceValue;
         }
 
+        $configObj = new \Magento\Framework\Object(
+            [
+                'config' => $config,
+            ]
+        );
+
+        //pass the return array encapsulated in an object for the other modules to be able to alter it eg: weee
+        $this->_eventManager->dispatch('catalog_product_option_price_configuration_after', ['configObj' => $configObj]);
+
+        $config=$configObj->getConfig();
+
         return $this->_jsonEncoder->encode($config);
     }
 
diff --git a/app/code/Magento/Catalog/Model/Observer.php b/app/code/Magento/Catalog/Model/Observer.php
index 39e72883f68add9d3672497199eb7c744480a7db..417a4f61811c99663538fd72e3c790ddc0753f3c 100644
--- a/app/code/Magento/Catalog/Model/Observer.php
+++ b/app/code/Magento/Catalog/Model/Observer.php
@@ -34,7 +34,14 @@ class Observer
      *
      * @var \Magento\Catalog\Model\Layer
      */
-    protected $_catalogLayer;
+    private $_catalogLayer = null;
+
+    /**
+     * Catalog layer resolver
+     *
+     * @var \Magento\Catalog\Model\Layer\Resolver
+     */
+    protected $layerResolver;
 
     /**
      * Store manager
@@ -95,7 +102,7 @@ class Observer
         $this->_categoryResource = $categoryResource;
         $this->_catalogProduct = $catalogProduct;
         $this->_storeManager = $storeManager;
-        $this->_catalogLayer = $layerResolver->get();
+        $this->layerResolver = $layerResolver;
         $this->_catalogCategory = $catalogCategory;
         $this->_catalogData = $catalogData;
         $this->categoryFlatConfig = $categoryFlatState;
@@ -184,11 +191,12 @@ class Observer
      */
     protected function hasActive($category)
     {
-        if (!$this->_catalogLayer) {
+        $catalogLayer = $this->getCatalogLayer();
+        if (!$catalogLayer) {
             return false;
         }
 
-        $currentCategory = $this->_catalogLayer->getCurrentCategory();
+        $currentCategory = $catalogLayer->getCurrentCategory();
         if (!$currentCategory) {
             return false;
         }
@@ -196,4 +204,16 @@ class Observer
         $categoryPathIds = explode(',', $currentCategory->getPathInStore());
         return in_array($category->getId(), $categoryPathIds);
     }
+
+    /**
+     * Get catalog layer
+     * @return \Magento\Catalog\Model\Layer
+     */
+    private function getCatalogLayer()
+    {
+        if ($this->_catalogLayer === null) {
+            $this->_catalogLayer = $this->layerResolver->get();
+        }
+        return $this->_catalogLayer;
+    }
 }
diff --git a/app/code/Magento/Catalog/Model/Product.php b/app/code/Magento/Catalog/Model/Product.php
index ebd9494fe1f842f7e42eba21cdb0c3da4cbd1325..d012f23de3df22b5e130abe2454fe2dc8f030c25 100644
--- a/app/code/Magento/Catalog/Model/Product.php
+++ b/app/code/Magento/Catalog/Model/Product.php
@@ -250,15 +250,25 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements
     protected $metadataService;
 
     /*
-     * @param \Magento\Catalog\Model\ProductLink\ProductLinkManagementInterface
+     * @param \Magento\Catalog\Model\ProductLink\CollectionProvider
      */
-    protected $linkManagement;
+    protected $entityCollectionProvider;
 
     /*
-     * @param \Magento\Catalog\Api\Data\ProductLinkInterfaceFactory $productLinkFactory
+     * @param \Magento\Catalog\Model\Product\LinkTypeProvider
+     */
+    protected $linkProvider;
+
+    /*
+     * @param \Magento\Catalog\Api\Data\ProductLinkInterfaceFactory
      */
     protected $productLinkFactory;
 
+    /*
+     * @param \Magento\Catalog\Api\Data\ProductLinkExtensionFactory
+     */
+    protected $productLinkExtensionFactory;
+
     /**
      * @var \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterfaceFactory
      */
@@ -318,8 +328,10 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements
      * @param Indexer\Product\Eav\Processor $productEavIndexerProcessor
      * @param CategoryRepositoryInterface $categoryRepository
      * @param Product\Image\CacheFactory $imageCacheFactory
-     * @param \Magento\Catalog\Model\ProductLink\Management $linkManagement
-     * @param \Magento\Catalog\Api\Data\ProductLinkInterfaceFactory $productLinkFactory,
+     * @param \Magento\Catalog\Model\ProductLink\CollectionProvider $entityCollectionProvider
+     * @param \Magento\Catalog\Model\Product\LinkTypeProvider $linkTypeProvider
+     * @param \Magento\Catalog\Api\Data\ProductLinkInterfaceFactory $productLinkFactory
+     * @param \Magento\Catalog\Api\Data\ProductLinkExtensionFactory $productLinkExtensionFactory
      * @param \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterfaceFactory $mediaGalleryEntryFactory
      * @param \Magento\Framework\Api\DataObjectHelper $dataObjectHelper
      * @param array $data
@@ -354,8 +366,10 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements
         \Magento\Catalog\Model\Indexer\Product\Eav\Processor $productEavIndexerProcessor,
         CategoryRepositoryInterface $categoryRepository,
         Product\Image\CacheFactory $imageCacheFactory,
-        \Magento\Catalog\Model\ProductLink\Management $linkManagement,
+        \Magento\Catalog\Model\ProductLink\CollectionProvider $entityCollectionProvider,
+        \Magento\Catalog\Model\Product\LinkTypeProvider $linkTypeProvider,
         \Magento\Catalog\Api\Data\ProductLinkInterfaceFactory $productLinkFactory,
+        \Magento\Catalog\Api\Data\ProductLinkExtensionFactory $productLinkExtensionFactory,
         \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterfaceFactory $mediaGalleryEntryFactory,
         \Magento\Framework\Api\DataObjectHelper $dataObjectHelper,
         array $data = []
@@ -380,8 +394,10 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements
         $this->_productEavIndexerProcessor = $productEavIndexerProcessor;
         $this->categoryRepository = $categoryRepository;
         $this->imageCacheFactory = $imageCacheFactory;
-        $this->linkManagement = $linkManagement;
+        $this->entityCollectionProvider = $entityCollectionProvider;
+        $this->linkTypeProvider = $linkTypeProvider;
         $this->productLinkFactory = $productLinkFactory;
+        $this->productLinkExtensionFactory = $productLinkExtensionFactory;
         $this->mediaGalleryEntryFactory = $mediaGalleryEntryFactory;
         $this->dataObjectHelper = $dataObjectHelper;
         parent::__construct(
@@ -1352,23 +1368,34 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements
     public function getProductLinks()
     {
         if (empty($this->_links)) {
-            $productLinks = [];
-
-            $productLinks['related'] = $this->getRelatedProducts();
-            $productLinks['upsell'] = $this->getUpSellProducts();
-            $productLinks['crosssell'] = $this->getCrossSellProducts();
-
             $output = [];
-            foreach ($productLinks as $type => $linkTypeArray) {
-                foreach ($linkTypeArray as $link) {
+            $linkTypes = $this->linkTypeProvider->getLinkTypes();
+            foreach (array_keys($linkTypes) as $linkTypeName) {
+                $collection = $this->entityCollectionProvider->getCollection($this, $linkTypeName);
+                foreach ($collection as $item) {
                     /** @var \Magento\Catalog\Api\Data\ProductLinkInterface $productLink */
                     $productLink = $this->productLinkFactory->create();
                     $productLink->setProductSku($this->getSku())
-                        ->setLinkType($type)
-                        ->setLinkedProductSku($link['sku'])
-                        ->setLinkedProductType($link['type_id'])
-                        ->setPosition($link['position']);
-
+                        ->setLinkType($linkTypeName)
+                        ->setLinkedProductSku($item['sku'])
+                        ->setLinkedProductType($item['type'])
+                        ->setPosition($item['position']);
+                    if (isset($item['custom_attributes'])) {
+                        $productLinkExtension = $productLink->getExtensionAttributes();
+                        if ($productLinkExtension === null) {
+                            $productLinkExtension = $this->productLinkExtensionFactory->create();
+                        }
+                        foreach ($item['custom_attributes'] as $option) {
+                            $name = $option['attribute_code'];
+                            $value = $option['value'];
+                            $setterName = 'set' . ucfirst($name);
+                            // Check if setter exists
+                            if (method_exists($productLinkExtension, $setterName)) {
+                                call_user_func([$productLinkExtension, $setterName], $value);
+                            }
+                        }
+                        $productLink->setExtensionAttributes($productLinkExtension);
+                    }
                     $output[] = $productLink;
                 }
             }
diff --git a/app/code/Magento/Catalog/Model/Product/Type/AbstractType.php b/app/code/Magento/Catalog/Model/Product/Type/AbstractType.php
index 94612dbf200a5f95fc003342e0c114d273366be1..b40b91d5b08b8efa59ff0534e04600c1bfcc33d7 100644
--- a/app/code/Magento/Catalog/Model/Product/Type/AbstractType.php
+++ b/app/code/Magento/Catalog/Model/Product/Type/AbstractType.php
@@ -100,6 +100,13 @@ abstract class AbstractType
      */
     protected $_fileStorageDb;
 
+    /**
+     * Cache key for Product Attributes
+     *
+     * @var string
+     */
+    protected $_cacheProductSetAttributes = '_cache_instance_product_set_attributes';
+
     /**
      * Delete data specific for this product type
      *
@@ -249,9 +256,13 @@ abstract class AbstractType
      */
     public function getSetAttributes($product)
     {
-        return $product->getResource()
-            ->loadAllAttributes($product)
-            ->getSortedAttributes($product->getAttributeSetId());
+        if (!$product->hasData($this->_cacheProductSetAttributes)) {
+            $setAttributes = $product->getResource()
+                ->loadAllAttributes($product)
+                ->getSortedAttributes($product->getAttributeSetId());
+            $product->setData($this->_cacheProductSetAttributes, $setAttributes);
+        }
+        return $product->getData($this->_cacheProductSetAttributes);
     }
 
     /**
diff --git a/app/code/Magento/Catalog/Model/ProductLink/Management.php b/app/code/Magento/Catalog/Model/ProductLink/Management.php
index 558561d22de50af6f402f9201a6138aaba441496..e702a6cde0e41f1a8e3316d5a30be821c620fa0b 100644
--- a/app/code/Magento/Catalog/Model/ProductLink/Management.php
+++ b/app/code/Magento/Catalog/Model/ProductLink/Management.php
@@ -7,7 +7,6 @@
 namespace Magento\Catalog\Model\ProductLink;
 
 use Magento\Catalog\Api\Data;
-use Magento\Catalog\Model\Product\Initialization\Helper\ProductLinks as LinksInitializer;
 use Magento\Framework\Exception\CouldNotSaveException;
 use Magento\Framework\Exception\NoSuchEntityException;
 
@@ -18,26 +17,6 @@ class Management implements \Magento\Catalog\Api\ProductLinkManagementInterface
      */
     protected $productRepository;
 
-    /**
-     * @var CollectionProvider
-     */
-    protected $entityCollectionProvider;
-
-    /**
-     * @var LinksInitializer
-     */
-    protected $linkInitializer;
-
-    /**
-     * @var \Magento\Catalog\Api\Data\ProductLinkInterfaceFactory
-     */
-    protected $productLinkFactory;
-
-    /**
-     * @var \Magento\Catalog\Model\Resource\Product
-     */
-    protected $productResource;
-
     /**
      * @var \Magento\Catalog\Model\Product\LinkTypeProvider
      */
@@ -45,25 +24,13 @@ class Management implements \Magento\Catalog\Api\ProductLinkManagementInterface
 
     /**
      * @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
-     * @param CollectionProvider $collectionProvider
-     * @param \Magento\Catalog\Api\Data\ProductLinkInterfaceFactory $productLinkFactory
-     * @param LinksInitializer $linkInitializer
-     * @param \Magento\Catalog\Model\Resource\Product $productResource
      * @param \Magento\Catalog\Model\Product\LinkTypeProvider $linkTypeProvider
      */
     public function __construct(
         \Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
-        CollectionProvider $collectionProvider,
-        \Magento\Catalog\Api\Data\ProductLinkInterfaceFactory $productLinkFactory,
-        LinksInitializer $linkInitializer,
-        \Magento\Catalog\Model\Resource\Product $productResource,
         \Magento\Catalog\Model\Product\LinkTypeProvider $linkTypeProvider
     ) {
         $this->productRepository = $productRepository;
-        $this->entityCollectionProvider = $collectionProvider;
-        $this->productLinkFactory = $productLinkFactory;
-        $this->productResource = $productResource;
-        $this->linkInitializer = $linkInitializer;
         $this->linkTypeProvider = $linkTypeProvider;
     }
 
@@ -73,27 +40,22 @@ class Management implements \Magento\Catalog\Api\ProductLinkManagementInterface
     public function getLinkedItemsByType($sku, $type)
     {
         $output = [];
-        $product = $this->productRepository->get($sku);
-        try {
-            $collection = $this->entityCollectionProvider->getCollection($product, $type);
-        } catch (NoSuchEntityException $e) {
+
+        $linkTypes = $this->linkTypeProvider->getLinkTypes();
+
+        if (!isset($linkTypes[$type])) {
             throw new NoSuchEntityException(__('Unknown link type: %1', (string)$type));
         }
-        foreach ($collection as $item) {
-            /** @var \Magento\Catalog\Api\Data\ProductLinkInterface $productLink */
-            $productLink = $this->productLinkFactory->create();
-            $productLink->setProductSku($product->getSku())
-                ->setLinkType($type)
-                ->setLinkedProductSku($item['sku'])
-                ->setLinkedProductType($item['type'])
-                ->setPosition($item['position']);
-            if (isset($item['custom_attributes'])) {
-                foreach ($item['custom_attributes'] as $option) {
-                    $productLink->getExtensionAttributes()->setQty($option['value']);
-                }
+        $product = $this->productRepository->get($sku);
+        $links = $product->getProductLinks();
+
+        // Only return the links of type specified
+        foreach ($links as $link) {
+            if ($link->getLinkType() == $type) {
+                $output[] = $link;
             }
-            $output[] = $productLink;
         }
+
         return $output;
     }
 
@@ -111,32 +73,27 @@ class Management implements \Magento\Catalog\Api\ProductLinkManagementInterface
         }
 
         $product = $this->productRepository->get($sku);
-        $assignedSkuList = [];
-        /** @var \Magento\Catalog\Api\Data\ProductLinkInterface $link */
-        foreach ($items as $link) {
-            $assignedSkuList[] = $link->getLinkedProductSku();
-        }
-        $linkedProductIds = $this->productResource->getProductsIdsBySkus($assignedSkuList);
 
-        $links = [];
-        /** @var \Magento\Catalog\Api\Data\ProductLinkInterface[] $items*/
-        foreach ($items as $link) {
-            $data = $link->__toArray();
-            $linkedSku = $link->getLinkedProductSku();
-            if (!isset($linkedProductIds[$linkedSku])) {
-                throw new NoSuchEntityException(
-                    __('Product with SKU "%1" does not exist', $linkedSku)
-                );
+        // Replace only links of the specified type
+        $existingLinks = $product->getProductLinks();
+        $newLinks = [];
+        if (!empty($existingLinks)) {
+            foreach ($existingLinks as $link) {
+                if ($link->getLinkType() != $type) {
+                    $newLinks[] = $link;
+                }
             }
-            $data['product_id'] = $linkedProductIds[$linkedSku];
-            $links[$linkedProductIds[$linkedSku]] = $data;
+            $newLinks = array_merge($newLinks, $items);
+        } else {
+            $newLinks = $items;
         }
-        $this->linkInitializer->initializeLinks($product, [$type => $links]);
+        $product->setProductLinks($newLinks);
         try {
-            $product->save();
+            $this->productRepository->save($product);
         } catch (\Exception $exception) {
             throw new CouldNotSaveException(__('Invalid data provided for linked products'));
         }
+
         return true;
     }
 }
diff --git a/app/code/Magento/Catalog/Model/ProductRepository.php b/app/code/Magento/Catalog/Model/ProductRepository.php
index 40ecc5d2cb3419101374a9d563b52ada19cd9967..8f2e7664c4e3df2c3ebf963cd4122e22a0e730cb 100644
--- a/app/code/Magento/Catalog/Model/ProductRepository.php
+++ b/app/code/Magento/Catalog/Model/ProductRepository.php
@@ -75,6 +75,16 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa
      */
     protected $linkInitializer;
 
+    /*
+     * @param \Magento\Catalog\Model\Product\LinkTypeProvider
+     */
+    protected $linkTypeProvider;
+
+    /*
+     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
+     */
+    protected $storeManager;
+
     /**
      * @var \Magento\Catalog\Api\ProductAttributeRepositoryInterface
      */
@@ -129,6 +139,8 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa
      * @param \Magento\Catalog\Api\ProductAttributeRepositoryInterface $attributeRepository
      * @param Resource\Product $resourceModel
      * @param \Magento\Catalog\Model\Product\Initialization\Helper\ProductLinks $linkInitializer
+     * @param \Magento\Catalog\Model\Product\LinkTypeProvider $linkTypeProvider
+     * @param \Magento\Store\Model\StoreManagerInterface $storeManager,
      * @param \Magento\Framework\Api\FilterBuilder $filterBuilder
      * @param \Magento\Catalog\Api\ProductAttributeRepositoryInterface $metadataServiceInterface
      * @param \Magento\Framework\Api\ExtensibleDataObjectConverter $extensibleDataObjectConverter
@@ -149,6 +161,8 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa
         \Magento\Catalog\Api\ProductAttributeRepositoryInterface $attributeRepository,
         \Magento\Catalog\Model\Resource\Product $resourceModel,
         \Magento\Catalog\Model\Product\Initialization\Helper\ProductLinks $linkInitializer,
+        \Magento\Catalog\Model\Product\LinkTypeProvider $linkTypeProvider,
+        \Magento\Store\Model\StoreManagerInterface $storeManager,
         \Magento\Framework\Api\FilterBuilder $filterBuilder,
         \Magento\Catalog\Api\ProductAttributeRepositoryInterface $metadataServiceInterface,
         \Magento\Framework\Api\ExtensibleDataObjectConverter $extensibleDataObjectConverter,
@@ -166,6 +180,8 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa
         $this->searchCriteriaBuilder = $searchCriteriaBuilder;
         $this->resourceModel = $resourceModel;
         $this->linkInitializer = $linkInitializer;
+        $this->linkTypeProvider = $linkTypeProvider;
+        $this->storeManager = $storeManager;
         $this->attributeRepository = $attributeRepository;
         $this->filterBuilder = $filterBuilder;
         $this->metadataService = $metadataServiceInterface;
@@ -260,6 +276,9 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa
     {
         if ($createNew) {
             $product = $this->productFactory->create();
+            if ($this->storeManager->hasSingleStore()) {
+                $product->setWebsiteIds([$this->storeManager->getStore(true)->getWebsite()->getId()]);
+            }
         } else {
             unset($this->instances[$productData['sku']]);
             $product = $this->get($productData['sku']);
@@ -353,11 +372,12 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa
         }
 
         // Clear all existing product links and then set the ones we want
-        $this->linkInitializer->initializeLinks($product, ['related' => []]);
-        $this->linkInitializer->initializeLinks($product, ['upsell' => []]);
-        $this->linkInitializer->initializeLinks($product, ['crosssell' => []]);
+        $linkTypes = $this->linkTypeProvider->getLinkTypes();
+        foreach (array_keys($linkTypes) as $typeName) {
+            $this->linkInitializer->initializeLinks($product, [$typeName => []]);
+        }
 
-        // Gather each linktype info
+        // Set each linktype info
         if (!empty($newLinks)) {
             $productLinks = [];
             foreach ($newLinks as $link) {
diff --git a/app/code/Magento/Catalog/Model/Resource/Category.php b/app/code/Magento/Catalog/Model/Resource/Category.php
index f99d1b9ee9d2c15cdca6c883cc7ded953973afc7..27d7f8b801df56c735259f20150e53aa1a5d7af4 100644
--- a/app/code/Magento/Catalog/Model/Resource/Category.php
+++ b/app/code/Magento/Catalog/Model/Resource/Category.php
@@ -92,13 +92,36 @@ class Category extends AbstractResource
         $this->_categoryTreeFactory = $categoryTreeFactory;
         $this->_categoryCollectionFactory = $categoryCollectionFactory;
         $this->_eventManager = $eventManager;
-        $this->setType(
-            \Magento\Catalog\Model\Category::ENTITY
-        )->setConnection(
-            $this->_resource->getConnection('catalog_read'),
-            $this->_resource->getConnection('catalog_write')
-        );
-        $this->_categoryProductTable = $this->getTable('catalog_category_product');
+
+        $this->_read  = 'catalog_read';
+        $this->_write = 'catalog_write';
+    }
+
+    /**
+     * Entity type getter and lazy loader
+     *
+     * @return \Magento\Eav\Model\Entity\Type
+     * @throws \Magento\Framework\Exception\LocalizedException
+     */
+    public function getEntityType()
+    {
+        if (empty($this->_type)) {
+            $this->setType(\Magento\Catalog\Model\Category::ENTITY);
+        }
+        return parent::getEntityType();
+    }
+
+    /**
+     * Category product table name getter
+     *
+     * @return string
+     */
+    public function getCategoryProductTable()
+    {
+        if (!$this->_categoryProductTable) {
+            $this->_categoryProductTable = $this->getTable('catalog_category_product');
+        }
+        return $this->_categoryProductTable;
     }
 
     /**
@@ -359,7 +382,7 @@ class Category extends AbstractResource
          */
         if (!empty($delete)) {
             $cond = ['product_id IN(?)' => array_keys($delete), 'category_id=?' => $id];
-            $adapter->delete($this->_categoryProductTable, $cond);
+            $adapter->delete($this->getCategoryProductTable(), $cond);
         }
 
         /**
@@ -374,7 +397,7 @@ class Category extends AbstractResource
                     'position' => (int)$position,
                 ];
             }
-            $adapter->insertMultiple($this->_categoryProductTable, $data);
+            $adapter->insertMultiple($this->getCategoryProductTable(), $data);
         }
 
         /**
@@ -384,7 +407,7 @@ class Category extends AbstractResource
             foreach ($update as $productId => $position) {
                 $where = ['category_id = ?' => (int)$id, 'product_id = ?' => (int)$productId];
                 $bind = ['position' => (int)$position];
-                $adapter->update($this->_categoryProductTable, $bind, $where);
+                $adapter->update($this->getCategoryProductTable(), $bind, $where);
             }
         }
 
@@ -417,7 +440,7 @@ class Category extends AbstractResource
     public function getProductsPosition($category)
     {
         $select = $this->_getWriteAdapter()->select()->from(
-            $this->_categoryProductTable,
+            $this->getCategoryProductTable(),
             ['product_id', 'position']
         )->where(
             'category_id = :category_id'
diff --git a/app/code/Magento/Catalog/Model/Resource/Category/Collection.php b/app/code/Magento/Catalog/Model/Resource/Category/Collection.php
index 2abc203eccbcada147503ce7f5be4400deb898e8..f21ce9f363b51f01a7555d79e3ba39aa89598b53 100644
--- a/app/code/Magento/Catalog/Model/Resource/Category/Collection.php
+++ b/app/code/Magento/Catalog/Model/Resource/Category/Collection.php
@@ -33,7 +33,7 @@ class Collection extends \Magento\Catalog\Model\Resource\Collection\AbstractColl
      *
      * @var string
      */
-    protected $_productTable;
+    private $_productTable;
 
     /**
      * Store id, that we should count products on
@@ -47,7 +47,7 @@ class Collection extends \Magento\Catalog\Model\Resource\Collection\AbstractColl
      *
      * @var string
      */
-    protected $_productWebsiteTable;
+    private $_productWebsiteTable;
 
     /**
      * Load with product count flag
@@ -64,9 +64,6 @@ class Collection extends \Magento\Catalog\Model\Resource\Collection\AbstractColl
     protected function _construct()
     {
         $this->_init('Magento\Catalog\Model\Category', 'Magento\Catalog\Model\Resource\Category');
-
-        $this->_productWebsiteTable = $this->getTable('catalog_product_website');
-        $this->_productTable = $this->getTable('catalog_category_product');
     }
 
     /**
@@ -224,7 +221,7 @@ class Collection extends \Magento\Catalog\Model\Resource\Collection\AbstractColl
             if (!empty($regularIds)) {
                 $select = $this->_conn->select();
                 $select->from(
-                    ['main_table' => $this->_productTable],
+                    ['main_table' => $this->getProductTable()],
                     ['category_id', new \Zend_Db_Expr('COUNT(main_table.product_id)')]
                 )->where(
                     $this->_conn->quoteInto('main_table.category_id IN(?)', $regularIds)
@@ -233,7 +230,7 @@ class Collection extends \Magento\Catalog\Model\Resource\Collection\AbstractColl
                 );
                 if ($websiteId) {
                     $select->join(
-                        ['w' => $this->_productWebsiteTable],
+                        ['w' => $this->getProductWebsiteTable()],
                         'main_table.product_id = w.product_id',
                         []
                     )->where(
@@ -259,7 +256,7 @@ class Collection extends \Magento\Catalog\Model\Resource\Collection\AbstractColl
                     $bind = ['entity_id' => $item->getId(), 'c_path' => $item->getPath() . '/%'];
                     $select = $this->_conn->select();
                     $select->from(
-                        ['main_table' => $this->_productTable],
+                        ['main_table' => $this->getProductTable()],
                         new \Zend_Db_Expr('COUNT(DISTINCT main_table.product_id)')
                     )->joinInner(
                         ['e' => $this->getTable('catalog_category_entity')],
@@ -272,7 +269,7 @@ class Collection extends \Magento\Catalog\Model\Resource\Collection\AbstractColl
                     );
                     if ($websiteId) {
                         $select->join(
-                            ['w' => $this->_productWebsiteTable],
+                            ['w' => $this->getProductWebsiteTable()],
                             'main_table.product_id = w.product_id',
                             []
                         )->where(
@@ -416,4 +413,30 @@ class Collection extends \Magento\Catalog\Model\Resource\Collection\AbstractColl
         $this->setOrder($field, self::SORT_ORDER_ASC);
         return $this;
     }
+
+    /**
+     * Getter for _productWebsiteTable
+     *
+     * @return string
+     */
+    public function getProductWebsiteTable()
+    {
+        if (empty($this->_productWebsiteTable)) {
+            $this->_productWebsiteTable = $this->getTable('catalog_product_website');
+        }
+        return $this->_productWebsiteTable;
+    }
+
+    /**
+     * Getter for _productTable
+     *
+     * @return string
+     */
+    public function getProductTable()
+    {
+        if (empty($this->_productTable)) {
+            $this->_productTable = $this->getTable('catalog_category_product');
+        }
+        return $this->_productTable;
+    }
 }
diff --git a/app/code/Magento/Catalog/Model/Resource/Product.php b/app/code/Magento/Catalog/Model/Resource/Product.php
index 336d8f796577ecabad0284932cc213cabcfb5f28..6f02829d2bc2a7dff4e95b39b7cd20181d5d1903 100644
--- a/app/code/Magento/Catalog/Model/Resource/Product.php
+++ b/app/code/Magento/Catalog/Model/Resource/Product.php
@@ -91,9 +91,48 @@ class Product extends AbstractResource
             $modelFactory,
             $data
         );
-        $this->setType(\Magento\Catalog\Model\Product::ENTITY)->setConnection('catalog_read', 'catalog_write');
-        $this->_productWebsiteTable = $this->getTable('catalog_product_website');
-        $this->_productCategoryTable = $this->getTable('catalog_category_product');
+        $this->_read  = 'catalog_read';
+        $this->_write = 'catalog_write';
+    }
+
+    /**
+     * Entity type getter and lazy loader
+     *
+     * @return \Magento\Eav\Model\Entity\Type
+     * @throws \Magento\Framework\Exception\LocalizedException
+     */
+    public function getEntityType()
+    {
+        if (empty($this->_type)) {
+            $this->setType(\Magento\Catalog\Model\Product::ENTITY);
+        }
+        return parent::getEntityType();
+    }
+
+    /**
+     * Product Website table name getter
+     *
+     * @return string
+     */
+    public function getProductWebsiteTable()
+    {
+        if (!$this->_productWebsiteTable) {
+            $this->_productWebsiteTable = $this->getTable('catalog_product_website');
+        }
+        return $this->_productWebsiteTable;
+    }
+
+    /**
+     * Product Category table name getter
+     *
+     * @return string
+     */
+    public function getProductCategoryTable()
+    {
+        if (!$this->_productCategoryTable) {
+            $this->_productCategoryTable = $this->getTable('catalog_category_product');
+        }
+        return $this->_productCategoryTable;
     }
 
     /**
@@ -123,7 +162,7 @@ class Product extends AbstractResource
         }
 
         $select = $adapter->select()->from(
-            $this->_productWebsiteTable,
+            $this->getProductWebsiteTable(),
             'website_id'
         )->where(
             'product_id = ?',
@@ -142,7 +181,7 @@ class Product extends AbstractResource
     public function getWebsiteIdsByProductIds($productIds)
     {
         $select = $this->_getWriteAdapter()->select()->from(
-            $this->_productWebsiteTable,
+            $this->getProductWebsiteTable(),
             ['product_id', 'website_id']
         )->where(
             'product_id IN (?)',
@@ -171,7 +210,7 @@ class Product extends AbstractResource
         $adapter = $this->_getReadAdapter();
 
         $select = $adapter->select()->from(
-            $this->_productCategoryTable,
+            $this->getProductCategoryTable(),
             'category_id'
         )->where(
             'product_id = ?',
@@ -274,14 +313,14 @@ class Product extends AbstractResource
             foreach ($insert as $websiteId) {
                 $data[] = ['product_id' => (int)$product->getId(), 'website_id' => (int)$websiteId];
             }
-            $adapter->insertMultiple($this->_productWebsiteTable, $data);
+            $adapter->insertMultiple($this->getProductWebsiteTable(), $data);
         }
 
         if (!empty($delete)) {
             foreach ($delete as $websiteId) {
                 $condition = ['product_id = ?' => (int)$product->getId(), 'website_id = ?' => (int)$websiteId];
 
-                $adapter->delete($this->_productWebsiteTable, $condition);
+                $adapter->delete($this->getProductWebsiteTable(), $condition);
             }
         }
 
@@ -329,7 +368,7 @@ class Product extends AbstractResource
                 ];
             }
             if ($data) {
-                $write->insertMultiple($this->_productCategoryTable, $data);
+                $write->insertMultiple($this->getProductCategoryTable(), $data);
             }
         }
 
@@ -337,7 +376,7 @@ class Product extends AbstractResource
             foreach ($delete as $categoryId) {
                 $where = ['product_id = ?' => (int)$object->getId(), 'category_id = ?' => (int)$categoryId];
 
-                $write->delete($this->_productCategoryTable, $where);
+                $write->delete($this->getProductCategoryTable(), $where);
             }
         }
 
diff --git a/app/code/Magento/Catalog/Model/Session.php b/app/code/Magento/Catalog/Model/Session.php
index b61175b11e7da3ff879834074f303590b664b72b..d7a3748c2810bd82a6b856e4d7dfe814cd0401ab 100644
--- a/app/code/Magento/Catalog/Model/Session.php
+++ b/app/code/Magento/Catalog/Model/Session.php
@@ -8,6 +8,6 @@ namespace Magento\Catalog\Model;
 /**
  * Catalog session model
  */
-class Session extends \Magento\Framework\Session\Generic
+class Session extends \Magento\Framework\Session\SessionManager
 {
 }
diff --git a/app/code/Magento/Catalog/Test/Unit/Block/Product/ProductList/ToolbarTest.php b/app/code/Magento/Catalog/Test/Unit/Block/Product/ProductList/ToolbarTest.php
index df66448c160372d82452ebe45b9ac68b7bb08749..d4501bd7d04393062a693c3491482132a7565d7d 100644
--- a/app/code/Magento/Catalog/Test/Unit/Block/Product/ProductList/ToolbarTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Block/Product/ProductList/ToolbarTest.php
@@ -106,9 +106,6 @@ class ToolbarTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
-        $this->catalogConfig->expects($this->any())
-            ->method('getAttributeUsedForSortByArray')
-            ->will($this->returnValue(['name' => [], 'price' => []]));
 
         $context = $this->getMock(
             'Magento\Framework\View\Element\Template\Context',
@@ -133,9 +130,6 @@ class ToolbarTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
-        $this->productListHelper->expects($this->any())
-            ->method('getAvailableViewMode')
-            ->will($this->returnValue(['list' => 'List']));
 
         $this->urlEncoder = $this->getMock('Magento\Framework\Url\EncoderInterface', ['encode'], [], '', false);
         $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
@@ -187,6 +181,9 @@ class ToolbarTest extends \PHPUnit_Framework_TestCase
         $this->model->expects($this->once())
             ->method('getOrder')
             ->will($this->returnValue($order));
+        $this->catalogConfig->expects($this->once())
+            ->method('getAttributeUsedForSortByArray')
+            ->will($this->returnValue(['name' => [], 'price' => []]));
 
         $this->assertEquals($order, $this->block->getCurrentOrder());
     }
@@ -206,6 +203,9 @@ class ToolbarTest extends \PHPUnit_Framework_TestCase
     {
         $mode = 'list';
 
+        $this->productListHelper->expects($this->once())
+            ->method('getAvailableViewMode')
+            ->will($this->returnValue(['list' => 'List']));
         $this->model->expects($this->once())
             ->method('getMode')
             ->will($this->returnValue($mode));
@@ -213,6 +213,40 @@ class ToolbarTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals($mode, $this->block->getCurrentMode());
     }
 
+    public function testGetModes()
+    {
+        $mode = ['list' => 'List'];
+        $this->productListHelper->expects($this->once())
+            ->method('getAvailableViewMode')
+            ->will($this->returnValue($mode));
+
+        $this->assertEquals($mode, $this->block->getModes());
+        $this->assertEquals($mode, $this->block->getModes());
+    }
+
+    /**
+     * @param string[] $mode
+     * @param string[] $expected
+     * @dataProvider setModesDataProvider
+     */
+    public function testSetModes($mode, $expected)
+    {
+        $this->productListHelper->expects($this->once())
+            ->method('getAvailableViewMode')
+            ->will($this->returnValue($mode));
+
+        $block = $this->block->setModes(['mode' => 'mode']);
+        $this->assertEquals($expected, $block->getModes());
+    }
+
+    public function setModesDataProvider()
+    {
+        return [
+            [['list' => 'List'], ['list' => 'List']],
+            [null, ['mode' => 'mode']],
+        ];
+    }
+
     public function testGetLimit()
     {
         $mode = 'list';
@@ -232,6 +266,9 @@ class ToolbarTest extends \PHPUnit_Framework_TestCase
             ->method('getDefaultLimitPerPageValue')
             ->with($this->equalTo('list'))
             ->will($this->returnValue(10));
+        $this->productListHelper->expects($this->any())
+            ->method('getAvailableViewMode')
+            ->will($this->returnValue(['list' => 'List']));
 
         $this->assertEquals($limit, $this->block->getLimit());
     }
@@ -280,4 +317,48 @@ class ToolbarTest extends \PHPUnit_Framework_TestCase
 
         $this->assertTrue($this->block->getPagerHtml());
     }
+
+    public function testSetDefaultOrder()
+    {
+        $this->catalogConfig->expects($this->atLeastOnce())
+            ->method('getAttributeUsedForSortByArray')
+            ->will($this->returnValue(['name' => [], 'price' => []]));
+
+        $this->block->setDefaultOrder('field');
+    }
+
+    public function testGetAvailableOrders()
+    {
+        $data = ['name' => [], 'price' => []];
+        $this->catalogConfig->expects($this->once())
+            ->method('getAttributeUsedForSortByArray')
+            ->will($this->returnValue($data));
+
+        $this->assertEquals($data, $this->block->getAvailableOrders());
+        $this->assertEquals($data, $this->block->getAvailableOrders());
+    }
+
+    public function testAddOrderToAvailableOrders()
+    {
+        $data = ['name' => [], 'price' => []];
+        $this->catalogConfig->expects($this->once())
+            ->method('getAttributeUsedForSortByArray')
+            ->will($this->returnValue($data));
+        $expected = $data;
+        $expected['order'] = 'value';
+        $toolbar = $this->block->addOrderToAvailableOrders('order', 'value');
+        $this->assertEquals($expected, $toolbar->getAvailableOrders());
+    }
+
+    public function testRemoveOrderFromAvailableOrders()
+    {
+        $data = ['name' => [], 'price' => []];
+        $this->catalogConfig->expects($this->once())
+            ->method('getAttributeUsedForSortByArray')
+            ->will($this->returnValue($data));
+        $toolbar = $this->block->removeOrderFromAvailableOrders('order', 'value');
+        $this->assertEquals($data, $toolbar->getAvailableOrders());
+        $toolbar2 = $this->block->removeOrderFromAvailableOrders('name');
+        $this->assertEquals(['price' => []], $toolbar2->getAvailableOrders());
+    }
 }
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/Type/AbstractTypeTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/Type/AbstractTypeTest.php
index 75149c26c8d001cf51956b2ca893ecb326f801d4..0ce39e12fbdc93ee8f2e1d38eff837c5a9b25514 100644
--- a/app/code/Magento/Catalog/Test/Unit/Model/Product/Type/AbstractTypeTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/Type/AbstractTypeTest.php
@@ -119,11 +119,12 @@ class AbstractTypeTest extends \PHPUnit_Framework_TestCase
 
     public function testGetSetAttributes()
     {
-        $this->productResource->expects($this->any())->method('loadAllAttributes')->will(
+        $this->productResource->expects($this->once())->method('loadAllAttributes')->will(
             $this->returnValue($this->productResource)
         );
-        $this->productResource->expects($this->any())->method('getSortedAttributes')->will($this->returnValue(5));
-        $this->model->getSetAttributes($this->product);
+        $this->productResource->expects($this->once())->method('getSortedAttributes')->will($this->returnValue(5));
+        $this->assertEquals(5, $this->model->getSetAttributes($this->product));
+        //Call the method for a second time, the cached copy should be used
         $this->assertEquals(5, $this->model->getSetAttributes($this->product));
     }
 
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ProductLink/ManagementTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ProductLink/ManagementTest.php
index ed28dc6fda78135af0e50f4e57d7db7c656dac67..92c2026f8961c258516299ba309da2cb811c145c 100644
--- a/app/code/Magento/Catalog/Test/Unit/Model/ProductLink/ManagementTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Model/ProductLink/ManagementTest.php
@@ -26,58 +26,21 @@ class ManagementTest extends \PHPUnit_Framework_TestCase
     /**
      * @var \PHPUnit_Framework_MockObject_MockObject
      */
-    protected $collectionProviderMock;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $linkInitializerMock;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $productLinkFactoryMock;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $productResourceMock;
+    protected $productMock;
 
     /**
      * @var \PHPUnit_Framework_MockObject_MockObject
      */
-    protected $productMock;
+    protected $linkTypeProviderMock;
 
     /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\Framework\ObjectManager
      */
-    protected $linkTypeProviderMock;
+    protected $objectManager;
 
     protected function setUp()
     {
         $this->productRepositoryMock = $this->getMock('\Magento\Catalog\Model\ProductRepository', [], [], '', false);
-        $this->productResourceMock = $this->getMock('\Magento\Catalog\Model\Resource\Product', [], [], '', false);
-        $this->collectionProviderMock = $this->getMock(
-            '\Magento\Catalog\Model\ProductLink\CollectionProvider',
-            [],
-            [],
-            '',
-            false
-        );
-        $this->linkInitializerMock = $this->getMock(
-            '\Magento\Catalog\Model\Product\Initialization\Helper\ProductLinks',
-            [],
-            [],
-            '',
-            false
-        );
-        $this->productLinkFactoryMock = $this->getMock(
-            '\Magento\Catalog\Api\Data\ProductLinkInterfaceFactory',
-            ['create'],
-            [],
-            '',
-            false
-        );
         $this->productMock = $this->getMock('Magento\Catalog\Model\Product', [], [], '', false);
 
         $this->linkTypeProviderMock = $this->getMock(
@@ -88,15 +51,11 @@ class ManagementTest extends \PHPUnit_Framework_TestCase
             false
         );
 
-        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
-        $this->model = $objectManager->getObject(
+        $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $this->model = $this->objectManager->getObject(
             'Magento\Catalog\Model\ProductLink\Management',
             [
                 'productRepository' => $this->productRepositoryMock,
-                'collectionProvider' => $this->collectionProviderMock,
-                'productLinkFactory' => $this->productLinkFactoryMock,
-                'linkInitializer' => $this->linkInitializerMock,
-                'productResource' => $this->productResourceMock,
                 'linkTypeProvider' => $this->linkTypeProviderMock
             ]
         );
@@ -104,163 +63,135 @@ class ManagementTest extends \PHPUnit_Framework_TestCase
 
     public function testGetLinkedItemsByType()
     {
-        $productSku = 'product';
-        $linkType = 'link';
+        $productSku = 'Simple Product 1';
+        $linkType = 'related';
         $this->productRepositoryMock->expects($this->once())->method('get')->with($productSku)
             ->willReturn($this->productMock);
-        $item = [
-            'sku' => 'product1',
-            'type' => 'type1',
-            'position' => 'pos1',
-        ];
-        $itemCollection = [$item];
-        $this->collectionProviderMock->expects($this->once())
-            ->method('getCollection')
-            ->with($this->productMock, $linkType)
-            ->willReturn($itemCollection);
-        $this->productMock->expects($this->once())->method('getSku')->willReturn($productSku);
-        $productLinkMock = $this->getMock('\Magento\Catalog\Api\Data\ProductLinkInterface');
-        $productLinkMock->expects($this->once())
-            ->method('setProductSku')
-            ->with($productSku)
-            ->willReturnSelf();
-        $productLinkMock->expects($this->once())
-            ->method('setLinkType')
-            ->with($linkType)
-            ->willReturnSelf();
-        $productLinkMock->expects($this->once())
-            ->method('setLinkedProductSku')
-            ->with($item['sku'])
-            ->willReturnSelf();
-        $productLinkMock->expects($this->once())
-            ->method('setLinkedProductType')
-            ->with($item['type'])
-            ->willReturnSelf();
-        $productLinkMock->expects($this->once())
-            ->method('setPosition')
-            ->with($item['position'])
-            ->willReturnSelf();
-        $this->productLinkFactoryMock->expects($this->once())->method('create')->willReturn($productLinkMock);
-        $this->assertEquals([$productLinkMock], $this->model->getLinkedItemsByType($productSku, $linkType));
+
+        $inputRelatedLink = $this->objectManager->getObject('Magento\Catalog\Model\ProductLink\Link');
+        $inputRelatedLink->setProductSku($productSku);
+        $inputRelatedLink->setLinkType($linkType);
+        $inputRelatedLink->setData("sku", "Simple Product 2");
+        $inputRelatedLink->setData("type_id", "simple");
+        $inputRelatedLink->setPosition(0);
+        $links = [$inputRelatedLink];
+
+        $linkTypes = ['related' => 1, 'upsell' => 4, 'crosssell' => 5, 'associated' => 3];
+        $this->linkTypeProviderMock->expects($this->once())
+            ->method('getLinkTypes')
+            ->willReturn($linkTypes);
+
+        $this->productMock->expects($this->once())->method('getProductLinks')->willReturn($links);
+        $this->assertEquals($links, $this->model->getLinkedItemsByType($productSku, $linkType));
     }
 
     /**
      * @expectedException \Magento\Framework\Exception\NoSuchEntityException
-     * @expectedExceptionMessage Unknown link type: wrong_type
+     * @expectedExceptionMessage Unknown link type: bad type
      */
     public function testGetLinkedItemsByTypeWithWrongType()
     {
-        $productSku = 'product';
-        $linkType = 'wrong_type';
-
-        $this->productRepositoryMock->expects($this->once())->method('get')->with($productSku)
+        $productSku = 'Simple Product 1';
+        $linkType = 'bad type';
+        $this->productRepositoryMock->expects($this->never())->method('get')->with($productSku)
             ->willReturn($this->productMock);
-        $this->collectionProviderMock->expects($this->once())
-            ->method('getCollection')
-            ->with($this->productMock, $linkType)
-            ->willThrowException(new NoSuchEntityException(__('Collection provider is not registered')));
 
+        $inputRelatedLink = $this->objectManager->getObject('Magento\Catalog\Model\ProductLink\Link');
+        $inputRelatedLink->setProductSku($productSku);
+        $inputRelatedLink->setLinkType($linkType);
+        $inputRelatedLink->setData("sku", "Simple Product 2");
+        $inputRelatedLink->setData("type_id", "simple");
+        $inputRelatedLink->setPosition(0);
+        $links = [$inputRelatedLink];
+
+        $linkTypes = ['related' => 1, 'upsell' => 4, 'crosssell' => 5, 'associated' => 3];
+        $this->linkTypeProviderMock->expects($this->once())
+            ->method('getLinkTypes')
+            ->willReturn($linkTypes);
+
+        $this->productMock->expects($this->never())->method('getProductLinks')->willReturn($links);
         $this->model->getLinkedItemsByType($productSku, $linkType);
     }
 
     public function testSetProductLinks()
     {
-        $type = 'type';
-        $linkedProductsMock = [];
-        $linksData = [];
-
-        $this->linkTypeProviderMock->expects($this->once())->method('getLinkTypes')->willReturn([$type => 'link']);
-        for ($i = 0; $i < 2; $i++) {
-            $linkMock = $this->getMockForAbstractClass(
-                '\Magento\Catalog\Api\Data\ProductLinkInterface',
-                [],
-                '',
-                false,
-                false,
-                true,
-                ['getLinkedProductSku', '__toArray']
-            );
-            $linkMock->expects($this->exactly(2))
-                ->method('getLinkedProductSku')
-                ->willReturn('linkedProduct' . $i . 'Sku');
-            $linkMock->expects($this->once())->method('__toArray');
-            $linkedProductsMock[$i] = $linkMock;
-            $linksData['productSku']['link'][] = $linkMock;
-        }
-        $linkedSkuList = ['linkedProduct0Sku', 'linkedProduct1Sku'];
-        $linkedProductIds = ['linkedProduct0Sku' => 1, 'linkedProduct1Sku' => 2];
-
-        $this->productResourceMock->expects($this->once())->method('getProductsIdsBySkus')->with($linkedSkuList)
-            ->willReturn($linkedProductIds);
-        $this->productRepositoryMock->expects($this->once())->method('get')->willReturn($this->productMock);
-        $this->linkInitializerMock->expects($this->once())->method('initializeLinks')
-            ->with($this->productMock, [$type => [
-                1 => ['product_id' => 1],
-                2 => ['product_id' => 2],
-            ]]);
-        $this->productMock->expects($this->once())->method('save');
-        $this->assertTrue($this->model->setProductLinks('', $type, $linkedProductsMock));
+        $productSku = 'Simple Product 1';
+        $linkType = 'related';
+        $this->productRepositoryMock->expects($this->once())->method('get')->with($productSku)
+            ->willReturn($this->productMock);
+
+        $inputRelatedLink = $this->objectManager->getObject('Magento\Catalog\Model\ProductLink\Link');
+        $inputRelatedLink->setProductSku($productSku);
+        $inputRelatedLink->setLinkType($linkType);
+        $inputRelatedLink->setData("sku", "Simple Product 1");
+        $inputRelatedLink->setData("type_id", "related");
+        $inputRelatedLink->setPosition(0);
+        $links = [$inputRelatedLink];
+
+        $linkTypes = ['related' => 1, 'upsell' => 4, 'crosssell' => 5, 'associated' => 3];
+        $this->linkTypeProviderMock->expects($this->once())
+            ->method('getLinkTypes')
+            ->willReturn($linkTypes);
+
+        $this->productMock->expects($this->once())->method('getProductLinks')->willReturn([]);
+        $this->productMock->expects($this->once())->method('setProductLinks')->with($links);
+        $this->assertTrue($this->model->setProductLinks($productSku, $linkType, $links));
     }
 
     /**
      * @expectedException \Magento\Framework\Exception\NoSuchEntityException
-     * @expectedExceptionMessage Provided link type "type2" does not exist
+     * @expectedExceptionMessage Provided link type "bad type" does not exist
      */
     public function testSetProductLinksThrowExceptionIfProductLinkTypeDoesNotExist()
     {
-        $type = 'type';
-        $linkedProductsMock = [];
+        $productSku = 'Simple Product 1';
+        $linkType = 'bad type';
+        $this->productRepositoryMock->expects($this->never())->method('get')->with($productSku)
+            ->willReturn($this->productMock);
+
+        $inputRelatedLink = $this->objectManager->getObject('Magento\Catalog\Model\ProductLink\Link');
+        $inputRelatedLink->setProductSku($productSku);
+        $inputRelatedLink->setLinkType($linkType);
+        $inputRelatedLink->setData("sku", "Simple Product 2");
+        $inputRelatedLink->setData("type_id", "simple");
+        $inputRelatedLink->setPosition(0);
+        $links = [$inputRelatedLink];
 
-        $this->linkTypeProviderMock->expects($this->once())->method('getLinkTypes')->willReturn([$type => 'link']);
-        $this->assertTrue($this->model->setProductLinks('', 'type2', $linkedProductsMock));
+        $linkTypes = ['related' => 1, 'upsell' => 4, 'crosssell' => 5, 'associated' => 3];
+        $this->linkTypeProviderMock->expects($this->once())
+            ->method('getLinkTypes')
+            ->willReturn($linkTypes);
+
+        $this->assertTrue($this->model->setProductLinks('', $linkType, $links));
     }
 
     /**
-     * @dataProvider setProductLinksNoProductExceptionDataProvider
+     * @expectedException \Magento\Framework\Exception\NoSuchEntityException
+     * @expectedExceptionMessage Requested product doesn't exist
      */
-    public function testSetProductLinksNoProductException($exceptionName, $exceptionMessage, $linkedProductIds)
+    public function testSetProductLinksNoProductException()
     {
-        $this->setExpectedException($exceptionName, $exceptionMessage);
-        $linkedProductsMock = [];
-        $type = 'type';
-        $this->linkTypeProviderMock->expects($this->once())->method('getLinkTypes')->willReturn([$type => 'link']);
-        for ($i = 0; $i < 2; $i++) {
-            $productLinkMock = $this->getMock(
-                '\Magento\Catalog\Api\Data\ProductLinkInterface',
-                [
-                    'getLinkedProductSku', 'getProductSku', 'getLinkType',
-                    '__toArray', 'getLinkedProductType', 'getPosition', 'getCustomAttribute', 'getCustomAttributes',
-                    'setCustomAttribute', 'setCustomAttributes', 'getMetadataServiceInterface',
-                    'getExtensionAttributes', 'setExtensionAttributes',
-                    'setLinkedProductSku', 'setProductSku', 'setLinkType', 'setLinkedProductType', 'setPosition'
-                ]
-            );
-            $productLinkMock->expects($this->any())
-                ->method('getLinkedProductSku')
-                ->willReturn('linkedProduct' . $i . 'Sku');
-            $productLinkMock->expects($this->any())->method('getProductSku')->willReturn('productSku');
-            $productLinkMock->expects($this->any())->method('getLinkType')->willReturn('link');
-            $linkedProductsMock[$i] = $productLinkMock;
-        }
-        $linkedSkuList = ['linkedProduct0Sku', 'linkedProduct1Sku'];
-        $this->productResourceMock->expects($this->any())->method('getProductsIdsBySkus')->with($linkedSkuList)
-            ->willReturn($linkedProductIds);
-        $this->model->setProductLinks('', $type, $linkedProductsMock);
-    }
-
-    public function setProductLinksNoProductExceptionDataProvider()
-    {
-        return [
-            [
-                '\Magento\Framework\Exception\NoSuchEntityException',
-                'Product with SKU "linkedProduct0Sku" does not exist',
-                ['linkedProduct1Sku' => 2],
-            ], [
-                '\Magento\Framework\Exception\NoSuchEntityException',
-                'Product with SKU "linkedProduct1Sku" does not exist',
-                ['linkedProduct0Sku' => 1]
-            ]
-        ];
+        $productSku = 'Simple Product 1';
+        $linkType = 'related';
+
+        $inputRelatedLink = $this->objectManager->getObject('Magento\Catalog\Model\ProductLink\Link');
+        $inputRelatedLink->setProductSku($productSku);
+        $inputRelatedLink->setLinkType($linkType);
+        $inputRelatedLink->setData("sku", "Simple Product 2");
+        $inputRelatedLink->setData("type_id", "simple");
+        $inputRelatedLink->setPosition(0);
+        $links = [$inputRelatedLink];
+
+        $linkTypes = ['related' => 1, 'upsell' => 4, 'crosssell' => 5, 'associated' => 3];
+        $this->linkTypeProviderMock->expects($this->once())
+            ->method('getLinkTypes')
+            ->willReturn($linkTypes);
+
+        $this->productRepositoryMock->expects($this->once())
+            ->method('get')
+            ->will($this->throwException(
+                new \Magento\Framework\Exception\NoSuchEntityException(__('Requested product doesn\'t exist'))));
+        $this->model->setProductLinks($productSku, $linkType, $links);
     }
 
     /**
@@ -269,39 +200,27 @@ class ManagementTest extends \PHPUnit_Framework_TestCase
      */
     public function testSetProductLinksInvalidDataException()
     {
-        $type = 'type';
-        $linkedProductsMock = [];
-        $linksData = [];
-        $this->linkTypeProviderMock->expects($this->once())->method('getLinkTypes')->willReturn([$type => 'link']);
-        for ($i = 0; $i < 2; $i++) {
-            $linkMock = $this->getMockForAbstractClass(
-                '\Magento\Catalog\Api\Data\ProductLinkInterface',
-                [],
-                '',
-                false,
-                false,
-                true,
-                ['getLinkedProductSku', '__toArray']
-            );
-            $linkMock->expects($this->exactly(2))
-                ->method('getLinkedProductSku')
-                ->willReturn('linkedProduct' . $i . 'Sku');
-            $linkMock->expects($this->once())->method('__toArray');
-            $linkedProductsMock[$i] = $linkMock;
-            $linksData['productSku']['link'][] = $linkMock;
-        }
-        $linkedSkuList = ['linkedProduct0Sku', 'linkedProduct1Sku'];
-        $linkedProductIds = ['linkedProduct0Sku' => 1, 'linkedProduct1Sku' => 2];
-
-        $this->productResourceMock->expects($this->once())->method('getProductsIdsBySkus')->with($linkedSkuList)
-            ->willReturn($linkedProductIds);
-        $this->productRepositoryMock->expects($this->once())->method('get')->willReturn($this->productMock);
-        $this->linkInitializerMock->expects($this->once())->method('initializeLinks')
-            ->with($this->productMock, [$type => [
-                1 => ['product_id' => 1],
-                2 => ['product_id' => 2],
-            ]]);
-        $this->productMock->expects($this->once())->method('save')->willThrowException(new \Exception());
-        $this->model->setProductLinks('', $type, $linkedProductsMock);
+        $productSku = 'Simple Product 1';
+        $linkType = 'related';
+        $this->productRepositoryMock->expects($this->once())->method('get')->with($productSku)
+            ->willReturn($this->productMock);
+
+        $inputRelatedLink = $this->objectManager->getObject('Magento\Catalog\Model\ProductLink\Link');
+        $inputRelatedLink->setProductSku($productSku);
+        $inputRelatedLink->setLinkType($linkType);
+        $inputRelatedLink->setData("sku", "bad sku");
+        $inputRelatedLink->setData("type_id", "bad type");
+        $inputRelatedLink->setPosition(0);
+        $links = [$inputRelatedLink];
+
+        $linkTypes = ['related' => 1, 'upsell' => 4, 'crosssell' => 5, 'associated' => 3];
+        $this->linkTypeProviderMock->expects($this->once())
+            ->method('getLinkTypes')
+            ->willReturn($linkTypes);
+
+        $this->productMock->expects($this->once())->method('getProductLinks')->willReturn([]);
+
+        $this->productRepositoryMock->expects($this->once())->method('save')->willThrowException(new \Exception());
+        $this->model->setProductLinks($productSku, $linkType, $links);
     }
 }
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php
index a8ba184519d797718c4613f9e5f4c4c8690764bf..35b260532553ee98240c049b12e1116449fbc9d9 100644
--- a/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php
@@ -111,11 +111,19 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase
      */
     protected $contentValidatorMock;
 
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $linkTypeProviderMock;
+
     /**
      * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager
      */
     protected $objectManager;
 
+    /**
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     */
     protected function setUp()
     {
         $this->productFactoryMock = $this->getMock('Magento\Catalog\Model\ProductFactory', ['create'], [], '', false);
@@ -194,6 +202,8 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase
             ->disableOriginalConstructor()
             ->getMock();
         $optionConverter = $this->objectManager->getObject('Magento\Catalog\Model\Product\Option\Converter');
+        $this->linkTypeProviderMock = $this->getMock('Magento\Catalog\Model\Product\LinkTypeProvider',
+            ['getLinkTypes'], [], '', false);
         $this->model = $this->objectManager->getObject(
             'Magento\Catalog\Model\ProductRepository',
             [
@@ -212,6 +222,7 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase
                 'fileSystem' => $this->fileSystemMock,
                 'contentFactory' => $this->contentFactoryMock,
                 'mimeTypeExtensionMap' => $this->mimeTypeExtensionMapMock,
+                'linkTypeProvider' => $this->linkTypeProviderMock
             ]
         );
     }
@@ -847,6 +858,11 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase
         $this->initializedProductMock->setData("product_links", $existingLinks);
 
         if (!empty($newLinks)) {
+            $linkTypes = ['related' => 1, 'upsell' => 4, 'crosssell' => 5, 'associated' => 3];
+            $this->linkTypeProviderMock->expects($this->once())
+                ->method('getLinkTypes')
+                ->willReturn($linkTypes);
+
             $this->initializedProductMock->setData("ignore_links_flag", false);
             $this->resourceModelMock
                 ->expects($this->any())->method('getProductsIdsBySkus')
@@ -859,6 +875,10 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase
             $inputLink->setLinkedProductType($newLinks['linked_product_type']);
             $inputLink->setPosition($newLinks['position']);
 
+            if (isset($newLinks['qty'])) {
+                $inputLink->setQty($newLinks['qty']);
+            }
+
             $this->productData['product_links'] = [$inputLink];
 
             $this->initializedProductMock->expects($this->any())
@@ -898,6 +918,9 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase
                 $outputLink->setLinkedProductSku($link['linked_product_sku']);
                 $outputLink->setLinkedProductType($link['linked_product_type']);
                 $outputLink->setPosition($link['position']);
+                if (isset($link['qty'])) {
+                    $outputLink->setQty($link['qty']);
+                }
 
                 $outputLinks[] = $outputLink;
             }
@@ -913,11 +936,11 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase
         // Scenario 1
         // No existing, new links
         $data['scenario_1'] = [
-            'newLinks' => ["product_sku" => "Simple Product 1", "link_type" => "related", "linked_product_sku" =>
-                "Simple Product 2", "linked_product_type" => "simple", "position" => 0],
+            'newLinks' => ["product_sku" => "Simple Product 1", "link_type" => "associated", "linked_product_sku" =>
+                "Simple Product 2", "linked_product_type" => "simple", "position" => 0, "qty" => 1],
             'existingLinks' => [],
-            'expectedData' => [["product_sku" => "Simple Product 1", "link_type" => "related", "linked_product_sku" =>
-                "Simple Product 2", "linked_product_type" => "simple", "position" => 0]]
+            'expectedData' => [["product_sku" => "Simple Product 1", "link_type" => "associated", "linked_product_sku" =>
+                "Simple Product 2", "linked_product_type" => "simple", "position" => 0, "qty" => 1]]
             ];
 
         // Scenario 2
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ProductTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ProductTest.php
index 4dcd067721f5bc239c97b1aa0141e694fb8a7f07..4cc87c7011c705075f1cb321657748006efc6aa6 100644
--- a/app/code/Magento/Catalog/Test/Unit/Model/ProductTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Model/ProductTest.php
@@ -146,6 +146,16 @@ class ProductTest extends \PHPUnit_Framework_TestCase
      */
     protected $attributeValueFactory;
 
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $linkTypeProviderMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $entityCollectionProviderMock;
+
     /**
      * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
      */
@@ -283,6 +293,11 @@ class ProductTest extends \PHPUnit_Framework_TestCase
         $this->metadataServiceMock = $this->getMock('\Magento\Catalog\Api\ProductAttributeRepositoryInterface');
         $this->attributeValueFactory = $this->getMockBuilder('Magento\Framework\Api\AttributeValueFactory')
             ->disableOriginalConstructor()->getMock();
+        $this->linkTypeProviderMock = $this->getMock('Magento\Catalog\Model\Product\LinkTypeProvider',
+            ['getLinkTypes'], [], '', false);
+        $this->entityCollectionProviderMock = $this->getMock('Magento\Catalog\Model\ProductLink\CollectionProvider',
+            ['getCollection'], [], '', false);
+
         $this->objectManagerHelper = new ObjectManagerHelper($this);
         $this->model = $this->objectManagerHelper->getObject(
             'Magento\Catalog\Model\Product',
@@ -306,6 +321,8 @@ class ProductTest extends \PHPUnit_Framework_TestCase
                 'mediaGalleryEntryFactory' => $this->mediaGalleryEntryFactoryMock,
                 'metadataService' => $this->metadataServiceMock,
                 'customAttributeFactory' => $this->attributeValueFactory,
+                'entityCollectionProvider' => $this->entityCollectionProviderMock,
+                'linkTypeProvider' => $this->linkTypeProviderMock,
                 'data' => ['id' => 1]
             ]
         );
@@ -737,37 +754,43 @@ class ProductTest extends \PHPUnit_Framework_TestCase
      */
     public function testGetProductLinks()
     {
-        $inputLink = $this->objectManagerHelper->getObject('Magento\Catalog\Model\ProductLink\Link');
-        $inputLink->setProductSku("Simple Product 1");
-        $inputLink->setLinkType("related");
-        $inputLink->setData("sku", "Simple Product 2");
-        $inputLink->setData("type_id", "simple");
-        $inputLink->setPosition(0);
-
-        $outputLink = $this->objectManagerHelper->getObject('Magento\Catalog\Model\ProductLink\Link');
-        $outputLink->setProductSku("Simple Product 1");
-        $outputLink->setLinkType("related");
-        $outputLink->setLinkedProductSku("Simple Product 2");
-        $outputLink->setLinkedProductType("simple");
-        $outputLink->setPosition(0);
-
-        $productLinks = [];
-        $this->model->setData('related_products', [$inputLink]);
-        $productLinks[] = $outputLink;
-        $outputLink->setLinkType("upsell");
-        $inputLink->setLinkType("upsell");
-        $this->model->setData('up_sell_products', [$inputLink]);
-        $productLinks[] = $outputLink;
-        $outputLink->setLinkType("crosssell");
-        $inputLink->setLinkType("crosssell");
-        $this->model->setData('cross_sell_products', [$inputLink]);
-        $productLinks[] = $outputLink;
-
-        $productLink = $this->objectManagerHelper->getObject('Magento\Catalog\Model\ProductLink\Link');
-        $this->productLinkFactory->expects($this->atLeastOnce())
-            ->method('create')
-            ->willReturn($productLink);
-
+        $linkTypes = ['related' => 1, 'upsell' => 4, 'crosssell' => 5, 'associated' => 3];
+        $this->linkTypeProviderMock->expects($this->once())
+            ->method('getLinkTypes')
+            ->willReturn($linkTypes);
+
+        $inputRelatedLink = $this->objectManagerHelper->getObject('Magento\Catalog\Model\ProductLink\Link');
+        $inputRelatedLink->setProductSku("Simple Product 1");
+        $inputRelatedLink->setLinkType("related");
+        $inputRelatedLink->setData("sku", "Simple Product 2");
+        $inputRelatedLink->setData("type", "simple");
+        $inputRelatedLink->setPosition(0);
+
+        $outputRelatedLink = $this->objectManagerHelper->getObject('Magento\Catalog\Model\ProductLink\Link');
+        $outputRelatedLink->setProductSku("Simple Product 1");
+        $outputRelatedLink->setLinkType("related");
+        $outputRelatedLink->setLinkedProductSku("Simple Product 2");
+        $outputRelatedLink->setLinkedProductType("simple");
+        $outputRelatedLink->setPosition(0);
+
+        $this->entityCollectionProviderMock->expects($this->at(0))
+            ->method('getCollection')
+            ->with($this->model, 'related')
+            ->willReturn([$inputRelatedLink]);
+        $this->entityCollectionProviderMock->expects($this->at(1))
+            ->method('getCollection')
+            ->with($this->model, 'upsell')
+            ->willReturn([]);
+        $this->entityCollectionProviderMock->expects($this->at(2))
+            ->method('getCollection')
+            ->with($this->model, 'crosssell')
+            ->willReturn([]);
+        $this->entityCollectionProviderMock->expects($this->at(3))
+            ->method('getCollection')
+            ->with($this->model, 'associated')
+            ->willReturn([]);
+
+        $expectedOutput = [$outputRelatedLink];
         $typeInstanceMock = $this->getMock(
             'Magento\ConfigurableProduct\Model\Product\Type\Simple', ["getSku"], [], '', false);
         $typeInstanceMock
@@ -776,8 +799,13 @@ class ProductTest extends \PHPUnit_Framework_TestCase
             ->willReturn("Simple Product 1");
         $this->model->setTypeInstance($typeInstanceMock);
 
+        $productLink1 = $this->objectManagerHelper->getObject('Magento\Catalog\Model\ProductLink\Link');
+        $this->productLinkFactory->expects($this->at(0))
+            ->method('create')
+            ->willReturn($productLink1);
+
         $links = $this->model->getProductLinks();
-        $this->assertEquals($links, $productLinks);
+        $this->assertEquals($links, $expectedOutput);
     }
 
     /**
diff --git a/app/code/Magento/Catalog/composer.json b/app/code/Magento/Catalog/composer.json
index 16e53d937b9199bb77a3828853871a6e287d4060..9aba73d735b3ff1caee1b2a7840d0a37037bb935 100644
--- a/app/code/Magento/Catalog/composer.json
+++ b/app/code/Magento/Catalog/composer.json
@@ -3,37 +3,37 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-eav": "0.74.0-beta6",
-        "magento/module-cms": "0.74.0-beta6",
-        "magento/module-indexer": "0.74.0-beta6",
-        "magento/module-customer": "0.74.0-beta6",
-        "magento/module-theme": "0.74.0-beta6",
-        "magento/module-checkout": "0.74.0-beta6",
-        "magento/module-log": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-widget": "0.74.0-beta6",
-        "magento/module-wishlist": "0.74.0-beta6",
-        "magento/module-tax": "0.74.0-beta6",
-        "magento/module-msrp": "0.74.0-beta6",
-        "magento/module-catalog-inventory": "0.74.0-beta6",
-        "magento/module-directory": "0.74.0-beta6",
-        "magento/module-catalog-rule": "0.74.0-beta6",
-        "magento/module-product-alert": "0.74.0-beta6",
-        "magento/module-url-rewrite": "0.74.0-beta6",
-        "magento/module-catalog-url-rewrite": "0.74.0-beta6",
-        "magento/module-page-cache": "0.74.0-beta6",
-        "magento/module-quote": "0.74.0-beta6",
-        "magento/module-config": "0.74.0-beta6",
-        "magento/module-media-storage": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-eav": "0.74.0-beta7",
+        "magento/module-cms": "0.74.0-beta7",
+        "magento/module-indexer": "0.74.0-beta7",
+        "magento/module-customer": "0.74.0-beta7",
+        "magento/module-theme": "0.74.0-beta7",
+        "magento/module-checkout": "0.74.0-beta7",
+        "magento/module-log": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-widget": "0.74.0-beta7",
+        "magento/module-wishlist": "0.74.0-beta7",
+        "magento/module-tax": "0.74.0-beta7",
+        "magento/module-msrp": "0.74.0-beta7",
+        "magento/module-catalog-inventory": "0.74.0-beta7",
+        "magento/module-directory": "0.74.0-beta7",
+        "magento/module-catalog-rule": "0.74.0-beta7",
+        "magento/module-product-alert": "0.74.0-beta7",
+        "magento/module-url-rewrite": "0.74.0-beta7",
+        "magento/module-catalog-url-rewrite": "0.74.0-beta7",
+        "magento/module-page-cache": "0.74.0-beta7",
+        "magento/module-quote": "0.74.0-beta7",
+        "magento/module-config": "0.74.0-beta7",
+        "magento/module-media-storage": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "suggest": {
-        "magento/module-cookie": "0.74.0-beta6"
+        "magento/module-cookie": "0.74.0-beta7"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Catalog/etc/di.xml b/app/code/Magento/Catalog/etc/di.xml
index acd741fdbbe66d5c107a3d24ce3d99a5ec716b52..8a4efe5a2b862b4be9e489a7a9c01b186ad08b0c 100644
--- a/app/code/Magento/Catalog/etc/di.xml
+++ b/app/code/Magento/Catalog/etc/di.xml
@@ -98,6 +98,7 @@
     <type name="Magento\Catalog\Model\Product">
         <arguments>
             <argument name="catalogProductStatus" xsi:type="object">Magento\Catalog\Model\Product\Attribute\Source\Status\Proxy</argument>
+            <argument name="productLink" xsi:type="object">Magento\Catalog\Model\Product\Link\Proxy</argument>
         </arguments>
     </type>
     <type name="Magento\Catalog\Model\Resource\Product\Collection">
@@ -398,6 +399,11 @@
             <argument name="validatorFile" xsi:type="object">Magento\Catalog\Model\Product\Option\Type\File\ValidatorFile\Proxy</argument>
         </arguments>
     </type>
+    <type name="Magento\Catalog\Model\Attribute\Config">
+        <arguments>
+            <argument name="dataStorage" xsi:type="object">Magento\Catalog\Model\Attribute\Config\Data\Proxy</argument>
+        </arguments>
+    </type>
     <virtualType name="Magento\Catalog\Model\Layer\Search\Context" type="Magento\Catalog\Model\Layer\Context">
         <arguments>
             <argument name="collectionProvider" xsi:type="object">Magento\Catalog\Model\Layer\Search\ItemCollectionProvider</argument>
@@ -464,4 +470,9 @@
     <type name="Magento\Catalog\Api\ProductRepositoryInterface">
         <plugin name="transactionWrapper" type="\Magento\Catalog\Model\Plugin\ProductRepository\TransactionWrapper" sortOrder="-1"/>
     </type>
+    <type name="Magento\Catalog\Model\CategoryRepository">
+        <arguments>
+            <argument name="categoryResource" xsi:type="object">Magento\Catalog\Model\Resource\Category\Proxy</argument>
+        </arguments>
+    </type>
 </config>
diff --git a/app/code/Magento/Catalog/view/adminhtml/web/catalog/product.js b/app/code/Magento/Catalog/view/adminhtml/web/catalog/product.js
index df3cc6b9694987e9e382d8e348db0fd2f95d9915..ec4e6efab5be63b5539f5a25ab5c449cebe1a04b 100644
--- a/app/code/Magento/Catalog/view/adminhtml/web/catalog/product.js
+++ b/app/code/Magento/Catalog/view/adminhtml/web/catalog/product.js
@@ -3,14 +3,18 @@
  * See COPYING.txt for license details.
  */
 require([
-    "jquery",
-    "prototype"
-], function(jQuery){
+    'jquery'
+], function ($) {
+    'use strict';
 
     window.Product = {};
 
+    function byId(id) {
+        return document.getElementById(id);
+    }
+
     function toogleFieldEditMode(toogleIdentifier, fieldContainer) {
-        if ($(toogleIdentifier).checked) {
+        if (byId(toogleIdentifier).checked) {
             enableFieldEditMode(fieldContainer);
         } else {
             disableFieldEditMode(fieldContainer);
@@ -18,47 +22,53 @@ require([
     }
 
     function disableFieldEditMode(fieldContainer) {
-        $(fieldContainer).disabled = true;
-        if ($(fieldContainer + '_hidden')) {
-            $(fieldContainer + '_hidden').disabled = true;
+        byId(fieldContainer).disabled = true;
+
+        if (byId(fieldContainer + '_hidden')) {
+            byId(fieldContainer + '_hidden').disabled = true;
         }
     }
 
     function enableFieldEditMode(fieldContainer) {
-        $(fieldContainer).disabled = false;
-        if ($(fieldContainer + '_hidden')) {
-            $(fieldContainer + '_hidden').disabled = false;
+        byId(fieldContainer).disabled = false;
+
+        if (byId(fieldContainer + '_hidden')) {
+            byId(fieldContainer + '_hidden').disabled = false;
         }
     }
 
     function onCompleteDisableInited() {
-        jQuery.each(jQuery('[data-disable]'), function () {
-            var item = jQuery(this).data('disable');
+        $.each($('[data-disable]'), function () {
+            var item = $(this).data('disable');
             disableFieldEditMode(item);
         });
     }
 
     function onUrlkeyChanged(urlKey) {
-        urlKey = $(urlKey);
-        var hidden = urlKey.next('input[type=hidden]');
-        var chbx = urlKey.next('input[type=checkbox]');
+        urlKey = byId(urlKey);
+        var hidden = $(urlKey).next('input[type=hidden]')[0];
+        var chbx = $(urlKey).next('input[type=checkbox]')[0];
         var oldValue = chbx.value;
-        chbx.disabled = (oldValue == urlKey.value);
+
+        chbx.disabled = (oldValue === urlKey.value);
         hidden.disabled = chbx.disabled;
     }
 
     function onCustomUseParentChanged(element) {
-        var useParent = (element.value == 1) ? true : false;
-        element.up(2).select('input', 'select', 'textarea').each(function (el) {
-            if (element.id != el.id) {
+        var useParent = (element.value === 1) ? true : false,
+            parent = $(element).parent().parent();
+
+        parent.find('input, select, textarea').each(function (i, el) {
+            if (element.id !== el.id) {
                 el.disabled = useParent;
             }
         });
-        element.up(2).select('img').each(function (el) {
+
+        parent.find('img').each(function (i, el) {
             if (useParent) {
-                el.hide();
+                $(el).hide();
             } else {
-                el.show();
+                $(el).show();
             }
         });
     }
@@ -67,5 +77,5 @@ require([
     window.onUrlkeyChanged = onUrlkeyChanged;
     window.toogleFieldEditMode = toogleFieldEditMode;
 
-    Event.observe(window, 'load', onCompleteDisableInited);
-});
\ No newline at end of file
+    $(window).load(onCompleteDisableInited);
+});
diff --git a/app/code/Magento/Catalog/view/base/web/js/price-box.js b/app/code/Magento/Catalog/view/base/web/js/price-box.js
index 667a30836e529533ce04c77b9f5605668852b04b..eed8ac4b9752c2eabcf80175699cc778d7d491c0 100644
--- a/app/code/Magento/Catalog/view/base/web/js/price-box.js
+++ b/app/code/Magento/Catalog/view/base/web/js/price-box.js
@@ -190,7 +190,7 @@ define([
             if (_.isEmpty(prices)) {
                 priceHolders.each(function (index, element) {
                     var type = $(element).data('priceType'),
-                        amount = $(element).data('priceAmount');
+                        amount = parseFloat($(element).data('priceAmount'));
 
                     if (type && amount) {
                         prices[type] = {
diff --git a/app/code/Magento/CatalogImportExport/Model/Export/Product.php b/app/code/Magento/CatalogImportExport/Model/Export/Product.php
index 15ab59aaab2b3b5e2b694f685e7d7523fcb5c565..72810dc82611f66c38e19f027215af9cd063721f 100644
--- a/app/code/Magento/CatalogImportExport/Model/Export/Product.php
+++ b/app/code/Magento/CatalogImportExport/Model/Export/Product.php
@@ -802,7 +802,7 @@ class Product extends \Magento\ImportExport\Model\Export\Entity\AbstractEntity
                 }
             }
         } catch (\Exception $e) {
-            $this->_logger->logException($e);
+            $this->_logger->critical($e);
         }
         return $exportData;
     }
diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Proxy/Product/Resource.php b/app/code/Magento/CatalogImportExport/Model/Import/Proxy/Product/Resource.php
index a71fe9dcc496215b69d7573c094c6762a8be4c4d..0f68ad9e99503a7932d2407dd79bd15d55c870f5 100644
--- a/app/code/Magento/CatalogImportExport/Model/Import/Proxy/Product/Resource.php
+++ b/app/code/Magento/CatalogImportExport/Model/Import/Proxy/Product/Resource.php
@@ -13,23 +13,4 @@ namespace Magento\CatalogImportExport\Model\Import\Proxy\Product;
 
 class Resource extends \Magento\Catalog\Model\Resource\Product
 {
-    /**
-     * Product to category table.
-     *
-     * @return string
-     */
-    public function getProductCategoryTable()
-    {
-        return $this->_productCategoryTable;
-    }
-
-    /**
-     * Product to website table.
-     *
-     * @return string
-     */
-    public function getProductWebsiteTable()
-    {
-        return $this->_productWebsiteTable;
-    }
 }
diff --git a/app/code/Magento/CatalogImportExport/composer.json b/app/code/Magento/CatalogImportExport/composer.json
index ee8f34355558e63ab22dc08089041e4bdc99c3a4..83d1e2e075da3a7a18b94418bb619feb0d8f86ad 100644
--- a/app/code/Magento/CatalogImportExport/composer.json
+++ b/app/code/Magento/CatalogImportExport/composer.json
@@ -3,20 +3,20 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/module-eav": "0.74.0-beta6",
-        "magento/module-import-export": "0.74.0-beta6",
-        "magento/module-indexer": "0.74.0-beta6",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-catalog-inventory": "0.74.0-beta6",
-        "magento/module-media-storage": "0.74.0-beta6",
-        "magento/module-customer": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/module-eav": "0.74.0-beta7",
+        "magento/module-import-export": "0.74.0-beta7",
+        "magento/module-indexer": "0.74.0-beta7",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-catalog-inventory": "0.74.0-beta7",
+        "magento/module-media-storage": "0.74.0-beta7",
+        "magento/module-customer": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "ext-ctype": "*",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/CatalogInventory/Api/Data/StockItemInterface.php b/app/code/Magento/CatalogInventory/Api/Data/StockItemInterface.php
index 46163c26be6d3df33831a35e9344333ffeaef7ef..0a620ce1562d529959ce09af000bc2f3b9923b7a 100644
--- a/app/code/Magento/CatalogInventory/Api/Data/StockItemInterface.php
+++ b/app/code/Magento/CatalogInventory/Api/Data/StockItemInterface.php
@@ -55,7 +55,7 @@ interface StockItemInterface extends ExtensibleDataInterface
     const CUSTOMER_GROUP_ID = 'customer_group_id';
 
     /**
-     * @return int
+     * @return int|null
      */
     public function getItemId();
 
@@ -66,7 +66,7 @@ interface StockItemInterface extends ExtensibleDataInterface
     public function setItemId($itemId);
 
     /**
-     * @return int
+     * @return int|null
      */
     public function getProductId();
 
@@ -79,7 +79,7 @@ interface StockItemInterface extends ExtensibleDataInterface
     /**
      * Retrieve Website Id
      *
-     * @return int
+     * @return int|null
      */
     public function getWebsiteId();
 
@@ -94,7 +94,7 @@ interface StockItemInterface extends ExtensibleDataInterface
     /**
      * Retrieve stock identifier
      *
-     * @return int
+     * @return int|null
      */
     public function getStockId();
 
diff --git a/app/code/Magento/CatalogInventory/Model/Plugin/AfterProductLoad.php b/app/code/Magento/CatalogInventory/Model/Plugin/AfterProductLoad.php
new file mode 100644
index 0000000000000000000000000000000000000000..3d6c9d404afe0e0e4594ef8f467c630575c69fab
--- /dev/null
+++ b/app/code/Magento/CatalogInventory/Model/Plugin/AfterProductLoad.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CatalogInventory\Model\Plugin;
+
+class AfterProductLoad
+{
+    /**
+     * @var \Magento\CatalogInventory\Api\StockRegistryInterface
+     */
+    protected $stockRegistry;
+
+    /**
+     * @var \Magento\Catalog\Api\Data\ProductExtensionFactory
+     */
+    protected $productExtensionFactory;
+
+    /**
+     * @param \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry
+     * @param \Magento\Catalog\Api\Data\ProductExtensionFactory $productExtensionFactory
+     */
+    public function __construct(
+        \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry,
+        \Magento\Catalog\Api\Data\ProductExtensionFactory $productExtensionFactory
+    ) {
+        $this->stockRegistry = $stockRegistry;
+        $this->productExtensionFactory = $productExtensionFactory;
+    }
+
+    /**
+     * Add stock item information to the product's extension attributes
+     *
+     * @param \Magento\Catalog\Model\Product $product
+     * @return \Magento\Catalog\Model\Product
+     */
+    public function afterLoad(\Magento\Catalog\Model\Product $product)
+    {
+        $productExtension = $product->getExtensionAttributes();
+        if ($productExtension === null) {
+            $productExtension = $this->productExtensionFactory->create();
+        }
+        // stockItem := \Magento\CatalogInventory\Api\Data\StockItemInterface
+        $productExtension->setStockItem($this->stockRegistry->getStockItem($product->getId()));
+        $product->setExtensionAttributes($productExtension);
+        return $product;
+    }
+}
diff --git a/app/code/Magento/CatalogInventory/Model/Plugin/AroundProductRepositorySave.php b/app/code/Magento/CatalogInventory/Model/Plugin/AroundProductRepositorySave.php
new file mode 100644
index 0000000000000000000000000000000000000000..0b222de117c9e84cb9aea4c009889f57ccbb8c80
--- /dev/null
+++ b/app/code/Magento/CatalogInventory/Model/Plugin/AroundProductRepositorySave.php
@@ -0,0 +1,95 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CatalogInventory\Model\Plugin;
+
+class AroundProductRepositorySave
+{
+    /**
+     * @var \Magento\CatalogInventory\Api\StockRegistryInterface
+     */
+    protected $stockRegistry;
+
+    /**
+     * @var \Magento\Store\Model\StoreManagerInterface
+     */
+    protected $storeManager;
+
+    /**
+     * @param \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry
+     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
+     */
+    public function __construct(
+        \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry,
+        \Magento\Store\Model\StoreManagerInterface $storeManager
+    ) {
+        $this->stockRegistry = $stockRegistry;
+        $this->storeManager = $storeManager;
+    }
+
+    /**
+     * @param \Magento\Catalog\Api\ProductRepositoryInterface $subject
+     * @param callable $proceed
+     * @param \Magento\Catalog\Api\Data\ProductInterface $product
+     * @param bool $saveOptions
+     * @return \Magento\Catalog\Api\Data\ProductInterface
+     * @throws \Magento\Framework\Exception\CouldNotSaveException
+     */
+    public function aroundSave(
+        \Magento\Catalog\Api\ProductRepositoryInterface $subject,
+        \Closure $proceed,
+        \Magento\Catalog\Api\Data\ProductInterface $product,
+        $saveOptions = false
+    ) {
+        /** @var \Magento\Catalog\Api\Data\ProductInterface $result */
+        $result = $proceed($product, $saveOptions);
+
+        /* @var \Magento\CatalogInventory\Api\Data\StockItemInterface $stockItem */
+        $stockItem = $this->getStockItemToBeUpdated($product);
+        if ($stockItem == null) {
+            return $result;
+        }
+
+        // set fields that the customer should not care about
+        $stockItem->setProductId($result->getId());
+        $stockItem->setWebsiteId($this->storeManager->getStore($result->getStoreId())->getWebsiteId());
+
+        $this->stockRegistry->updateStockItemBySku($result->getSku(), $stockItem);
+
+        // since we just saved a portion of the product, force a reload of it before returning it
+        return $subject->get($result->getSku(), false, $result->getStoreId(), true);
+    }
+
+    /**
+     * Return the stock item that needs to be updated.
+     * If the stock item does not need to be updated, return null.
+     *
+     * @param \Magento\Catalog\Api\Data\ProductInterface $product
+     * @return \Magento\CatalogInventory\Api\Data\StockItemInterface|null
+     */
+    protected function getStockItemToBeUpdated($product)
+    {
+        // from the API, all the data we care about will exist as extension attributes of the original product
+        $extendedAttributes = $product->getExtensionAttributes();
+        if ($extendedAttributes !== null) {
+            $stockItem = $extendedAttributes->getStockItem();
+            if ($stockItem != null) {
+                return $stockItem;
+            }
+        }
+
+        // we have no new stock item information to update, however we need to ensure that the product does have some
+        // stock item information present.  On a newly created product, it will not have any stock item info.
+        $stockItem = $this->stockRegistry->getStockItem($product->getId());
+        if ($stockItem->getItemId() != null) {
+            // we already have stock item info, so we return null since nothing more needs to be updated
+            return null;
+        }
+
+        return $stockItem;
+    }
+}
diff --git a/app/code/Magento/CatalogInventory/Model/Stock/Item.php b/app/code/Magento/CatalogInventory/Model/Stock/Item.php
index cb622e904c6bbab1838275d66a5f9129e6640a24..15fb84875aafeac95108233e7f4ea482fc295a26 100644
--- a/app/code/Magento/CatalogInventory/Model/Stock/Item.php
+++ b/app/code/Magento/CatalogInventory/Model/Stock/Item.php
@@ -239,11 +239,11 @@ class Item extends AbstractExtensibleModel implements StockItemInterface
     }
 
     /**
-     * @return int Timestamp
+     * @return string Timestamp
      */
     public function getLowStockDate()
     {
-        return (int) $this->_getData(static::LOW_STOCK_DATE);
+        return $this->_getData(static::LOW_STOCK_DATE);
     }
 
     /**
diff --git a/app/code/Magento/CatalogInventory/Model/StockManagement.php b/app/code/Magento/CatalogInventory/Model/StockManagement.php
index 1f50b8b5dceaa3b64ff14c83044ac6e62f7e85cb..3d5fee6d9cef90eb8bfcf98d78b6c45e68c0bca2 100644
--- a/app/code/Magento/CatalogInventory/Model/StockManagement.php
+++ b/app/code/Magento/CatalogInventory/Model/StockManagement.php
@@ -84,7 +84,7 @@ class StockManagement implements StockManagementInterface
             $orderedQty = $items[$productId];
             $stockItem = $this->stockRegistryProvider->getStockItem($productId, $websiteId);
             $canSubtractQty = $stockItem->getItemId() && $this->canSubtractQty($stockItem);
-            if (!$canSubtractQty || !$this->stockConfiguration->isQty($this->getProductType($productId))) {
+            if (!$canSubtractQty || !$this->stockConfiguration->isQty($lockedItemRecord['type_id'])) {
                 continue;
             }
             if (!$stockItem->hasAdminArea()
diff --git a/app/code/Magento/CatalogInventory/Model/StockRegistry.php b/app/code/Magento/CatalogInventory/Model/StockRegistry.php
index fefbf9f34899f031a374d551e390b24235d3f9c0..f32aeb2104b686091e06120271c462ec33542f08 100644
--- a/app/code/Magento/CatalogInventory/Model/StockRegistry.php
+++ b/app/code/Magento/CatalogInventory/Model/StockRegistry.php
@@ -15,6 +15,8 @@ use Magento\CatalogInventory\Model\Spi\StockRegistryProviderInterface;
 
 /**
  * Class StockRegistry
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
 class StockRegistry implements StockRegistryInterface
 {
@@ -185,9 +187,7 @@ class StockRegistry implements StockRegistryInterface
         $origStockItem = $this->getStockItem($productId, $websiteId);
         $data = $stockItem->getData();
         if ($origStockItem->getItemId()) {
-            if (isset($data['item_id'])) {
-                unset($data['item_id']);
-            }
+            unset($data['item_id']);
         }
         $origStockItem->addData($data);
         $origStockItem->setProductId($productId);
diff --git a/app/code/Magento/CatalogInventory/Test/Unit/Model/Plugin/AfterProductLoadTest.php b/app/code/Magento/CatalogInventory/Test/Unit/Model/Plugin/AfterProductLoadTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..77b8985cac84c3d21bb9eeb7a598ea9138c366d6
--- /dev/null
+++ b/app/code/Magento/CatalogInventory/Test/Unit/Model/Plugin/AfterProductLoadTest.php
@@ -0,0 +1,104 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+// @codingStandardsIgnoreFile
+
+namespace Magento\CatalogInventory\Test\Unit\Model\Plugin;
+
+class AfterProductLoadTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\CatalogInventory\Model\Plugin\AfterProductLoad
+     */
+    protected $plugin;
+
+    /**
+     * @var \Magento\Catalog\Api\Data\ProductInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productMock;
+
+    /**
+     * @var \Magento\Catalog\Api\Data\ProductExtensionFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productExtensionFactoryMock;
+
+    /**
+     * @var \Magento\Catalog\Api\Data\ProductExtension|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productExtensionMock;
+
+    protected function setUp()
+    {
+        $stockRegistryMock = $this->getMock('\Magento\CatalogInventory\Api\StockRegistryInterface');
+        $this->productExtensionFactoryMock = $this->getMockBuilder('\Magento\Catalog\Api\Data\ProductExtensionFactory')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->plugin = new \Magento\CatalogInventory\Model\Plugin\AfterProductLoad(
+            $stockRegistryMock,
+            $this->productExtensionFactoryMock
+        );
+
+        $productId = 5494;
+        $stockItemMock = $this->getMock('\Magento\CatalogInventory\Api\Data\StockItemInterface');
+
+        $stockRegistryMock->expects($this->once())
+            ->method('getStockItem')
+            ->with($productId)
+            ->willReturn($stockItemMock);
+
+        $this->productExtensionMock = $this->getMockBuilder('\Magento\Catalog\Api\Data\ProductExtension')
+            ->setMethods(['setStockItem'])
+            ->getMock();
+        $this->productExtensionMock->expects($this->once())
+            ->method('setStockItem')
+            ->with($stockItemMock)
+            ->willReturnSelf();
+
+        $this->productMock = $this->getMockBuilder('\Magento\Catalog\Model\Product')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->productMock->expects($this->once())
+            ->method('setExtensionAttributes')
+            ->with($this->productExtensionMock)
+            ->willReturnSelf();
+        $this->productMock->expects(($this->once()))
+            ->method('getId')
+            ->will($this->returnValue($productId));
+    }
+
+    public function testAfterLoad()
+    {
+        // test when extension attributes are not (yet) present in the product
+        $this->productMock->expects($this->once())
+            ->method('getExtensionAttributes')
+            ->willReturn(null);
+        $this->productExtensionFactoryMock->expects($this->once())
+            ->method('create')
+            ->willReturn($this->productExtensionMock);
+
+        $this->assertEquals(
+            $this->productMock,
+            $this->plugin->afterLoad($this->productMock)
+        );
+    }
+
+    public function testAfterLoadWithExistingExtensionAttributes()
+    {
+        // test when extension attributes already exist
+        $this->productMock->expects($this->once())
+            ->method('getExtensionAttributes')
+            ->willReturn($this->productExtensionMock);
+        $this->productExtensionFactoryMock->expects($this->never())
+            ->method('create');
+
+        $this->assertEquals(
+            $this->productMock,
+            $this->plugin->afterLoad($this->productMock)
+        );
+    }
+}
diff --git a/app/code/Magento/CatalogInventory/Test/Unit/Model/Plugin/AroundProductRepositorySaveTest.php b/app/code/Magento/CatalogInventory/Test/Unit/Model/Plugin/AroundProductRepositorySaveTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..95560e7ce7be3144937120e89eb40f41484b7586
--- /dev/null
+++ b/app/code/Magento/CatalogInventory/Test/Unit/Model/Plugin/AroundProductRepositorySaveTest.php
@@ -0,0 +1,176 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+// @codingStandardsIgnoreFile
+
+namespace Magento\CatalogInventory\Test\Unit\Model\Plugin;
+
+class AroundProductRepositorySaveTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\CatalogInventory\Model\Plugin\AroundProductRepositorySave
+     */
+    protected $plugin;
+
+    /**
+     * @var \Magento\CatalogInventory\Api\Data\StockItemInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $stockItemMock;
+
+    /**
+     * @var \Magento\Catalog\Api\Data\ProductInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productMock;
+
+    /**
+     * @var \Magento\Catalog\Api\Data\ProductInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $savedProductMock;
+
+    /**
+     * @var \Magento\CatalogInventory\Api\StockRegistryInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $stockRegistry;
+
+    /**
+     * @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $storeManager;
+
+    /**
+     * @var \Magento\Catalog\Api\Data\ProductExtension|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productExtensionMock;
+
+    /**
+     * @var \Magento\Catalog\Api\ProductRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productRepositoryMock;
+
+    /**
+     * @var \Closure
+     */
+    protected $closureMock;
+
+    public function setUp()
+    {
+        $this->stockRegistry = $this->getMock('\Magento\CatalogInventory\Api\StockRegistryInterface');
+        $this->storeManager = $this->getMock('\Magento\Store\Model\StoreManagerInterface');
+
+        $this->plugin = new \Magento\CatalogInventory\Model\Plugin\AroundProductRepositorySave(
+            $this->stockRegistry,
+            $this->storeManager
+        );
+
+        $this->productExtensionMock = $this->getMockBuilder('\Magento\Catalog\Api\Data\ProductExtension')
+            ->setMethods(['getStockItem'])
+            ->getMock();
+        $this->productRepositoryMock = $this->getMock('Magento\Catalog\Api\ProductRepositoryInterface');
+        $this->productMock = $this->getMock('\Magento\Catalog\Api\Data\ProductInterface');
+        $this->savedProductMock = $this->getMock('\Magento\Catalog\Api\Data\ProductInterface');
+        $this->closureMock = function () {
+            return $this->savedProductMock;
+        };
+        $this->stockItemMock = $this->getMock('\Magento\CatalogInventory\Api\Data\StockItemInterface');
+    }
+
+    public function testAroundSaveWhenProductHasNoStockItemNeedingToBeUpdated()
+    {
+        // pretend we have no extension attributes at all
+        $this->productMock->expects($this->once())
+            ->method('getExtensionAttributes')
+            ->willReturn(null);
+        $this->productExtensionMock->expects($this->never())->method('getStockItem');
+
+        // pretend that the product already has existing stock item information
+        $this->stockRegistry->expects($this->once())->method('getStockItem')->willReturn($this->stockItemMock);
+        $this->stockItemMock->expects($this->once())->method('getItemId')->willReturn(1);
+        $this->stockItemMock->expects($this->never())->method('setProductId');
+        $this->stockItemMock->expects($this->never())->method('setWebsiteId');
+
+        // expect that there are no changes to the existing stock item information
+        $this->assertEquals(
+            $this->savedProductMock,
+            $this->plugin->aroundSave($this->productRepositoryMock, $this->closureMock, $this->productMock)
+        );
+    }
+
+    public function testAroundSaveWhenProductHasNoPersistentStockItemInfo()
+    {
+        // pretend we do have extension attributes, but none for 'stock_item'
+        $this->productMock->expects($this->once())
+            ->method('getExtensionAttributes')
+            ->willReturn($this->productExtensionMock);
+        $this->productExtensionMock->expects($this->once())
+            ->method('getStockItem')
+            ->willReturn(null);
+
+        $storeMock = $this->getMockBuilder('\Magento\Store\Model\Store')
+            ->disableOriginalConstructor()->getMock();
+        $storeMock->expects($this->once())->method('getWebsiteId')->willReturn(1);
+        $this->storeManager->expects($this->once())->method('getStore')->willReturn($storeMock);
+
+        $this->stockRegistry->expects($this->once())->method('getStockItem')->willReturn($this->stockItemMock);
+        $this->stockRegistry->expects($this->once())->method('updateStockItemBySku');
+
+        $this->stockItemMock->expects($this->once())->method('getItemId')->willReturn(null);
+        $this->stockItemMock->expects($this->once())->method('setProductId');
+        $this->stockItemMock->expects($this->once())->method('setWebsiteId');
+
+        $newProductMock = $this->getMockBuilder('Magento\Catalog\Api\Data\ProductInterface')
+            ->disableOriginalConstructor()->getMock();
+        $this->productRepositoryMock->expects($this->once())->method('get')->willReturn($newProductMock);
+
+        $this->assertEquals(
+            $newProductMock,
+            $this->plugin->aroundSave($this->productRepositoryMock, $this->closureMock, $this->productMock)
+        );
+    }
+
+    public function testAroundSave()
+    {
+        $productId = 5494;
+        $websiteId = 1;
+        $storeId = 2;
+        $sku = 'my product that needs saving';
+
+        $this->productMock->expects($this->once())
+            ->method('getExtensionAttributes')
+            ->willReturn($this->productExtensionMock);
+        $this->productExtensionMock->expects($this->once())
+            ->method('getStockItem')
+            ->willReturn($this->stockItemMock);
+
+        $storeMock = $this->getMockBuilder('\Magento\Store\Model\Store')
+            ->disableOriginalConstructor()->getMock();
+        $storeMock->expects($this->once())->method('getWebsiteId')->willReturn($websiteId);
+        $this->storeManager->expects($this->once())->method('getStore')->with($storeId)->willReturn($storeMock);
+
+        $this->savedProductMock->expects(($this->once()))->method('getId')->willReturn($productId);
+        $this->savedProductMock->expects(($this->atLeastOnce()))->method('getStoreId')->willReturn($storeId);
+        $this->savedProductMock->expects($this->atLeastOnce())->method('getSku')->willReturn($sku);
+
+        $this->stockItemMock->expects($this->once())->method('setProductId')->with($productId);
+        $this->stockItemMock->expects($this->once())->method('setWebsiteId')->with($websiteId);
+
+        $this->stockRegistry->expects($this->once())
+            ->method('updateStockItemBySku')
+            ->with($sku, $this->stockItemMock);
+
+        $newProductMock = $this->getMockBuilder('Magento\Catalog\Api\Data\ProductInterface')
+            ->disableOriginalConstructor()->getMock();
+        $this->productRepositoryMock->expects($this->once())
+            ->method('get')
+            ->with($sku, false, $storeId, true)
+            ->willReturn($newProductMock);
+
+        $this->assertEquals(
+            $newProductMock,
+            $this->plugin->aroundSave($this->productRepositoryMock, $this->closureMock, $this->productMock)
+        );
+    }
+}
diff --git a/app/code/Magento/CatalogInventory/Test/Unit/Model/Stock/ItemTest.php b/app/code/Magento/CatalogInventory/Test/Unit/Model/Stock/ItemTest.php
index 20de61fbf3ba19c6851e47bc016e3ee38e82d9eb..f6cfa8b4e7e6643d3b4df80ae83fe79bd57dd0fc 100644
--- a/app/code/Magento/CatalogInventory/Test/Unit/Model/Stock/ItemTest.php
+++ b/app/code/Magento/CatalogInventory/Test/Unit/Model/Stock/ItemTest.php
@@ -395,4 +395,12 @@ class ItemTest extends \PHPUnit_Framework_TestCase
             [0, $this->storeId],
         ];
     }
+
+    public function testGetLowStockDate()
+    {
+        // ensure we do *not* return '2015' due to casting to an int
+        $date = '2015-4-17';
+        $this->item->setLowStockDate($date);
+        $this->assertEquals($date, $this->item->getLowStockDate());
+    }
 }
diff --git a/app/code/Magento/CatalogInventory/composer.json b/app/code/Magento/CatalogInventory/composer.json
index 129c2285172ca06dabdd98cb51dcc1a6ba9fdad7..b7209d2df90f07c288bdaa1eca809222777c6678 100644
--- a/app/code/Magento/CatalogInventory/composer.json
+++ b/app/code/Magento/CatalogInventory/composer.json
@@ -3,18 +3,18 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-config": "0.74.0-beta6",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/module-customer": "0.74.0-beta6",
-        "magento/module-indexer": "0.74.0-beta6",
-        "magento/module-eav": "0.74.0-beta6",
-        "magento/module-quote": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-config": "0.74.0-beta7",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/module-customer": "0.74.0-beta7",
+        "magento/module-indexer": "0.74.0-beta7",
+        "magento/module-eav": "0.74.0-beta7",
+        "magento/module-quote": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/CatalogInventory/etc/di.xml b/app/code/Magento/CatalogInventory/etc/di.xml
index 11c98534f732718a84bb3cde28379c3f76137b61..b1ad4a03847bbd997e93dc255b0d7de325f11f9d 100644
--- a/app/code/Magento/CatalogInventory/etc/di.xml
+++ b/app/code/Magento/CatalogInventory/etc/di.xml
@@ -52,4 +52,15 @@
     <type name="Magento\Catalog\Block\Product\View">
         <plugin name="quantityValidators" type="Magento\CatalogInventory\Block\Plugin\ProductView" />
     </type>
+    <type name="Magento\CatalogInventory\Model\Configuration">
+        <arguments>
+            <argument name="config" xsi:type="object">Magento\Catalog\Model\ProductTypes\Config\Proxy</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Catalog\Model\Product">
+        <plugin name="catalogInventoryAfterLoad" type="\Magento\CatalogInventory\Model\Plugin\AfterProductLoad"/>
+    </type>
+    <type name="Magento\Catalog\Api\ProductRepositoryInterface">
+        <plugin name="catalogInventoryAroundSave" type="\Magento\CatalogInventory\Model\Plugin\AroundProductRepositorySave"/>
+    </type>
 </config>
diff --git a/app/code/Magento/CatalogInventory/etc/service_data_attributes.xml b/app/code/Magento/CatalogInventory/etc/service_data_attributes.xml
new file mode 100644
index 0000000000000000000000000000000000000000..587b98b401a0981d8ca14b75242f0adac67312a2
--- /dev/null
+++ b/app/code/Magento/CatalogInventory/etc/service_data_attributes.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Api/etc/service_data_attributes.xsd">
+    <extension_attributes for="Magento\Catalog\Api\Data\ProductInterface">
+        <attribute code="stock_item" type="Magento\CatalogInventory\Api\Data\StockItemInterface">
+            <resources>
+                <resource ref="Magento_CatalogInventory::cataloginventory"/>
+            </resources>
+        </attribute>
+    </extension_attributes>
+</config>
diff --git a/app/code/Magento/CatalogRule/composer.json b/app/code/Magento/CatalogRule/composer.json
index 321bbcd7334b631b6f630452474b2ae25f5a265c..b3192cfcc8459c4f74fa8c68076c255add2719b3 100644
--- a/app/code/Magento/CatalogRule/composer.json
+++ b/app/code/Magento/CatalogRule/composer.json
@@ -3,19 +3,19 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-rule": "0.74.0-beta6",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/module-customer": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-eav": "0.74.0-beta6",
-        "magento/module-indexer": "0.74.0-beta6",
-        "magento/module-import-export": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-rule": "0.74.0-beta7",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/module-customer": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-eav": "0.74.0-beta7",
+        "magento/module-indexer": "0.74.0-beta7",
+        "magento/module-import-export": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/CatalogSearch/composer.json b/app/code/Magento/CatalogSearch/composer.json
index d9f2822e173203097515ba797209fdbb4a4c8a64..39e60cdc03a9c5e15623e4744e874cb04360f601 100644
--- a/app/code/Magento/CatalogSearch/composer.json
+++ b/app/code/Magento/CatalogSearch/composer.json
@@ -3,20 +3,20 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/module-search": "0.74.0-beta6",
-        "magento/module-customer": "0.74.0-beta6",
-        "magento/module-directory": "0.74.0-beta6",
-        "magento/module-indexer": "0.74.0-beta6",
-        "magento/module-eav": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-theme": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/module-search": "0.74.0-beta7",
+        "magento/module-customer": "0.74.0-beta7",
+        "magento/module-directory": "0.74.0-beta7",
+        "magento/module-indexer": "0.74.0-beta7",
+        "magento/module-eav": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-theme": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/CatalogUrlRewrite/composer.json b/app/code/Magento/CatalogUrlRewrite/composer.json
index 2488990a45e7570de05a47be2802787cb2fe1395..2e9cc77143f5017b3fc59b6257edd8789592fcef 100644
--- a/app/code/Magento/CatalogUrlRewrite/composer.json
+++ b/app/code/Magento/CatalogUrlRewrite/composer.json
@@ -3,18 +3,18 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/module-catalog-import-export": "0.74.0-beta6",
-        "magento/module-eav": "0.74.0-beta6",
-        "magento/module-import-export": "0.74.0-beta6",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-url-rewrite": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/module-catalog-import-export": "0.74.0-beta7",
+        "magento/module-eav": "0.74.0-beta7",
+        "magento/module-import-export": "0.74.0-beta7",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-url-rewrite": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/CatalogWidget/composer.json b/app/code/Magento/CatalogWidget/composer.json
index e92c896cb1a574e1aa912d5cc378bb8c70aead25..6600bf5ff65cec1c7f2915dcceb4d5812048bcdb 100644
--- a/app/code/Magento/CatalogWidget/composer.json
+++ b/app/code/Magento/CatalogWidget/composer.json
@@ -3,19 +3,19 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/module-widget": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-rule": "0.74.0-beta6",
-        "magento/module-eav": "0.74.0-beta6",
-        "magento/module-customer": "0.74.0-beta6",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-wishlist": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/module-widget": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-rule": "0.74.0-beta7",
+        "magento/module-eav": "0.74.0-beta7",
+        "magento/module-customer": "0.74.0-beta7",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-wishlist": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Centinel/composer.json b/app/code/Magento/Centinel/composer.json
index 584771858a87c0b5d497fd4ff33d11d890b28892..fba6a6e8c1b5af2c4b3f933e8ca57cd319447f4f 100644
--- a/app/code/Magento/Centinel/composer.json
+++ b/app/code/Magento/Centinel/composer.json
@@ -3,15 +3,15 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-checkout": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-sales": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-checkout": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-sales": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Checkout/Controller/Onepage/SaveOrder.php b/app/code/Magento/Checkout/Controller/Onepage/SaveOrder.php
index 04141e448fec992be6bc53f0afa82b41d6dedd2d..7249f26f18540c606d9716bbc55b17ef2312adc8 100644
--- a/app/code/Magento/Checkout/Controller/Onepage/SaveOrder.php
+++ b/app/code/Magento/Checkout/Controller/Onepage/SaveOrder.php
@@ -5,6 +5,7 @@
  */
 namespace Magento\Checkout\Controller\Onepage;
 
+use Magento\Framework\Object;
 use Magento\Framework\Exception\PaymentException;
 
 class SaveOrder extends \Magento\Checkout\Controller\Onepage
@@ -26,16 +27,17 @@ class SaveOrder extends \Magento\Checkout\Controller\Onepage
             return $this->_ajaxRedirectResponse();
         }
 
-        $result = [];
+        $result = new Object();
         try {
             $agreementsValidator = $this->_objectManager->get('Magento\Checkout\Model\Agreements\AgreementsValidator');
             if (!$agreementsValidator->isValid(array_keys($this->getRequest()->getPost('agreement', [])))) {
-                $result['success'] = false;
-                $result['error'] = true;
-                $result['error_messages'] = __(
-                    'Please agree to all the terms and conditions before placing the order.'
+                $result->setData('success', false);
+                $result->setData('error', true);
+                $result->setData(
+                    'error_messages',
+                    __('Please agree to all the terms and conditions before placing the order.')
                 );
-                return $this->resultJsonFactory->create()->setData($result);
+                return $this->resultJsonFactory->create()->setData($result->getData());
             }
 
             $data = $this->getRequest()->getPost('payment', []);
@@ -54,25 +56,34 @@ class SaveOrder extends \Magento\Checkout\Controller\Onepage
             $this->getOnepage()->saveOrder();
 
             $redirectUrl = $this->getOnepage()->getCheckout()->getRedirectUrl();
-            $result['success'] = true;
-            $result['error'] = false;
+            $result->setData('success', true);
+            $result->setData('error', false);
         } catch (PaymentException $e) {
             $message = $e->getMessage();
             if (!empty($message)) {
-                $result['error_messages'] = $message;
+                $result->setData('error_messages', $message);
             }
-            $result['goto_section'] = 'payment';
-            $result['update_section'] = ['name' => 'payment-method', 'html' => $this->_getPaymentMethodsHtml()];
+            $result->setData('goto_section', 'payment');
+            $result->setData(
+                'update_section',
+                [
+                    'name' => 'payment-method',
+                    'html' => $this->_getPaymentMethodsHtml()
+                ]
+            );
         } catch (\Magento\Framework\Exception\LocalizedException $e) {
             $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($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();
+            $result->setData(
+                'success',
+                false
+            );
+            $result->setData('error', true);
+            $result->setData('error_messages', $e->getMessage());
             $gotoSection = $this->getOnepage()->getCheckout()->getGotoSection();
             if ($gotoSection) {
-                $result['goto_section'] = $gotoSection;
+                $result->setData('goto_section', $gotoSection);
                 $this->getOnepage()->getCheckout()->setGotoSection(null);
             }
 
@@ -80,10 +91,13 @@ class SaveOrder extends \Magento\Checkout\Controller\Onepage
             if ($updateSection) {
                 if (isset($this->_sectionUpdateFunctions[$updateSection])) {
                     $updateSectionFunction = $this->_sectionUpdateFunctions[$updateSection];
-                    $result['update_section'] = [
-                        'name' => $updateSection,
-                        'html' => $this->{$updateSectionFunction}(),
-                    ];
+                    $result->setData(
+                        'update_section',
+                        [
+                            'name' => $updateSection,
+                            'html' => $this->{$updateSectionFunction}(),
+                        ]
+                    );
                 }
                 $this->getOnepage()->getCheckout()->setUpdateSection(null);
             }
@@ -91,18 +105,29 @@ class SaveOrder extends \Magento\Checkout\Controller\Onepage
             $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($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.');
+            $result->setData('success', false);
+            $result->setData('error', true);
+            $result->setData(
+                'error_messages',
+                __('Something went wrong processing your order. Please try again later.')
+            );
         }
         /**
          * 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;
+            $result->setData('redirect', $redirectUrl);
         }
 
-        return $this->resultJsonFactory->create()->setData($result);
+        $this->_eventManager->dispatch(
+            'checkout_controller_onepage_saveOrder',
+            [
+                'result' => $result,
+                'action' => $this
+            ]
+        );
+
+        return $this->resultJsonFactory->create()->setData($result->getData());
     }
 }
diff --git a/app/code/Magento/Checkout/Model/Session.php b/app/code/Magento/Checkout/Model/Session.php
index 0f7d18e41355b5ffbae94f02f0f6272485d59cbd..da634e082756d1e8be81769a6af6dc32a6874fbe 100644
--- a/app/code/Magento/Checkout/Model/Session.php
+++ b/app/code/Magento/Checkout/Model/Session.php
@@ -90,6 +90,7 @@ class Session extends \Magento\Framework\Session\SessionManager
      * @param \Magento\Framework\Session\StorageInterface $storage
      * @param \Magento\Framework\Stdlib\CookieManagerInterface $cookieManager
      * @param \Magento\Framework\Stdlib\Cookie\CookieMetadataFactory $cookieMetadataFactory
+     * @param \Magento\Framework\App\State $appState
      * @param \Magento\Sales\Model\OrderFactory $orderFactory
      * @param \Magento\Customer\Model\Session $customerSession
      * @param \Magento\Quote\Model\QuoteRepository $quoteRepository
@@ -97,6 +98,7 @@ class Session extends \Magento\Framework\Session\SessionManager
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
      * @param \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository
+     * @throws \Magento\Framework\Exception\SessionException
      * @SuppressWarnings(PHPMD.ExcessiveParameterList)
      */
     public function __construct(
@@ -108,6 +110,7 @@ class Session extends \Magento\Framework\Session\SessionManager
         \Magento\Framework\Session\StorageInterface $storage,
         \Magento\Framework\Stdlib\CookieManagerInterface $cookieManager,
         \Magento\Framework\Stdlib\Cookie\CookieMetadataFactory $cookieMetadataFactory,
+        \Magento\Framework\App\State $appState,
         \Magento\Sales\Model\OrderFactory $orderFactory,
         \Magento\Customer\Model\Session $customerSession,
         \Magento\Quote\Model\QuoteRepository $quoteRepository,
@@ -131,9 +134,9 @@ class Session extends \Magento\Framework\Session\SessionManager
             $validator,
             $storage,
             $cookieManager,
-            $cookieMetadataFactory
+            $cookieMetadataFactory,
+            $appState
         );
-        $this->start();
     }
 
     /**
diff --git a/app/code/Magento/Checkout/Test/Unit/Controller/Onepage/SaveOrderTest.php b/app/code/Magento/Checkout/Test/Unit/Controller/Onepage/SaveOrderTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..cef6ff863cc8d50289d6d12c92e9bfc4421f07e6
--- /dev/null
+++ b/app/code/Magento/Checkout/Test/Unit/Controller/Onepage/SaveOrderTest.php
@@ -0,0 +1,322 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Checkout\Test\Unit\Controller\Onepage;
+
+use Magento\Checkout\Controller\Onepage\SaveOrder;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+
+/**
+ * Class SaveOrderTest
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
+class SaveOrderTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var SaveOrder
+     */
+    protected $controller;
+
+    /**
+     * @var \Magento\Framework\Data\Form\FormKey\Validator|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $formKeyValidatorMock;
+
+    /**
+     * @var \Magento\Framework\App\Action\Context|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $contextMock;
+
+    /**
+     * @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $requestMock;
+
+    /**
+     * @var \Magento\Framework\App\ResponseInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $responseMock;
+
+    /**
+     * @var \Magento\Framework\ObjectManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $objectManagerMock;
+
+    /**
+     * @var \Magento\Framework\Controller\Result\RedirectFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $resultRedirectFactoryMock;
+
+    /**
+     * @var \Magento\Framework\Controller\Result\RawFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $resultRawFactoryMock;
+
+    /**
+     * @var \Magento\Framework\Controller\Result\JsonFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $resultJsonFactoryMock;
+
+    /**
+     * @var \Magento\Framework\Event\ManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $eventManagerMock;
+
+    /**
+     * @var \Magento\Checkout\Model\Type\Onepage|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $onepageMock;
+
+    /**
+     * @var \Magento\Checkout\Model\Agreements\AgreementsValidator|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $agreementsValidatorMock;
+
+    /**
+     * @var \Magento\Quote\Model\Quote|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $quoteMock;
+
+    /**
+     * Set up
+     *
+     * @return void
+     */
+    protected function setUp()
+    {
+        $helper = new ObjectManager($this);
+
+        $contextMock = $this->getMockBuilder('Magento\Framework\App\Action\Context')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->requestMock = $this->getMockBuilder('Magento\Framework\App\RequestInterface')
+            ->disableOriginalConstructor()
+            ->setMethods(['getPost'])
+            ->getMockForAbstractClass();
+        $this->responseMock = $this->getMockBuilder('Magento\Framework\App\ResponseInterface')
+            ->disableOriginalConstructor()
+            ->getMockForAbstractClass();
+        $this->objectManagerMock = $this->getMockBuilder('Magento\Framework\ObjectManagerInterface')
+            ->disableOriginalConstructor()
+            ->getMockForAbstractClass();
+        $this->formKeyValidatorMock = $this->getMockBuilder('Magento\Framework\Data\Form\FormKey\Validator')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->resultRedirectFactoryMock = $this->getMockBuilder('Magento\Framework\Controller\Result\RedirectFactory')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->resultRawFactoryMock = $this->getMockBuilder('Magento\Framework\Controller\Result\RawFactory')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->resultJsonFactoryMock = $this->getMockBuilder('Magento\Framework\Controller\Result\JsonFactory')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->eventManagerMock = $this->getMockBuilder('Magento\Framework\Event\ManagerInterface')
+            ->disableOriginalConstructor()
+            ->getMockForAbstractClass();
+        $this->onepageMock = $this->getMockBuilder('Magento\Checkout\Model\Type\Onepage')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->agreementsValidatorMock = $this->getMockBuilder('Magento\Checkout\Model\Agreements\AgreementsValidator')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->quoteMock = $this->getMockBuilder('Magento\Quote\Model\Quote')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $contextMock->expects($this->once())
+            ->method('getRequest')
+            ->willReturn($this->requestMock);
+        $contextMock->expects($this->once())
+            ->method('getResponse')
+            ->willReturn($this->responseMock);
+        $contextMock->expects($this->once())
+            ->method('getObjectManager')
+            ->willReturn($this->objectManagerMock);
+        $contextMock->expects($this->once())
+            ->method('getResultRedirectFactory')
+            ->willReturn($this->resultRedirectFactoryMock);
+        $contextMock->expects($this->once())
+            ->method('getEventManager')
+            ->willReturn($this->eventManagerMock);
+
+        $this->controller = $helper->getObject(
+            'Magento\Checkout\Controller\Onepage\SaveOrder',
+            [
+                'context' => $contextMock,
+                'formKeyValidator' => $this->formKeyValidatorMock,
+                'resultRawFactory' => $this->resultRawFactoryMock,
+                'resultJsonFactory' => $this->resultJsonFactoryMock,
+            ]
+        );
+    }
+
+    /**
+     * Test method execution _expireAjax (call hasItems === false)
+     *
+     * @return void
+     */
+    protected function expireAjaxFlowHasItemsFalse()
+    {
+        $this->onepageMock->expects($this->atLeastOnce())
+            ->method('getQuote')
+            ->willReturn($this->quoteMock);
+
+        $this->quoteMock->expects($this->once())
+            ->method('hasItems')
+            ->willReturn(false);
+        $this->quoteMock->expects($this->never())
+            ->method('getHasError')
+            ->willReturn(true);
+        $this->quoteMock->expects($this->never())
+            ->method('validateMinimumAmount')
+            ->willReturn(false);
+
+        $this->requestMock->expects($this->never())
+            ->method('getActionName');
+    }
+
+    /**
+     * Test for execute method
+     *
+     * @return void
+     */
+    public function testExecuteWithSuccessOrderSave()
+    {
+        $testData = $this->getExecuteWithSuccessOrderSaveTestData();
+
+
+        $redirectMock = $this->getMockBuilder('Magento\Framework\Controller\Result\Redirect')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $paymentMock = $this->getMockBuilder('Magento\Quote\Model\Quote\Payment')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $checkoutMock = $this->getMockBuilder('Magento\Checkout\Model\Session')
+            ->disableOriginalConstructor()
+            ->setMethods(['getRedirectUrl'])
+            ->getMock();
+        $resultJsonMock = $this->getMockBuilder('Magento\Framework\Controller\Result\Json')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $redirectMock->expects($this->never())
+            ->method('setPath')
+            ->with('*/*/')
+            ->willReturn('redirect');
+
+        $this->formKeyValidatorMock->expects($this->once())
+            ->method('validate')
+            ->with($this->requestMock)
+            ->willReturn(true);
+
+        $this->resultRedirectFactoryMock->expects($this->never())
+            ->method('create')
+            ->willReturn($redirectMock);
+
+        $this->objectManagerMock->expects($this->atLeastOnce())
+            ->method('get')
+            ->willReturnMap($testData['objectManager.get']);
+
+        // call _expireAjax method
+        $this->expireAjaxFlowHasItemsFalse();
+
+        $this->requestMock->expects($this->atLeastOnce())
+            ->method('getPost')
+            ->willReturnMap($testData['request.getPost']);
+
+        $this->agreementsValidatorMock->expects($this->once())
+            ->method('isValid')
+            ->with($testData['agreementsValidator.isValid'])
+            ->willReturn(true);
+
+        $this->quoteMock->expects($this->atLeastOnce())
+            ->method('getPayment')
+            ->willReturn($paymentMock);
+
+        $paymentMock->expects($this->once())
+            ->method('setQuote')
+            ->with($this->quoteMock);
+        $paymentMock->expects($this->once())
+            ->method('importData')
+            ->with($testData['payment.importData']);
+
+        $this->onepageMock->expects($this->once())
+            ->method('saveOrder');
+        $this->onepageMock->expects($this->once())
+            ->method('getCheckout')
+            ->willReturn($checkoutMock);
+
+        $checkoutMock->expects($this->once())
+            ->method('getRedirectUrl')
+            ->willReturn(null);
+
+        $this->eventManagerMock->expects($this->once())
+            ->method('dispatch')
+            ->withConsecutive(
+                $this->equalTo('checkout_controller_onepage_saveOrder'),
+                $this->countOf(2)
+            );
+
+        $this->resultJsonFactoryMock->expects($this->once())
+            ->method('create')
+            ->willReturn($resultJsonMock);
+
+        $resultJsonMock->expects($this->once())
+            ->method('setData')
+            ->with($testData['resultJson.setData'])
+            ->willReturnSelf();
+
+        $this->assertEquals($resultJsonMock, $this->controller->execute());
+    }
+
+    /**
+     * Get data for test testExecuteWithSuccessOrderSave
+     *
+     * @return array
+     */
+    protected function getExecuteWithSuccessOrderSaveTestData()
+    {
+        $data = [
+            'payment-key-1' => 'payment-value-1',
+            'checks' => [
+                \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,
+            ]
+        ];
+        $testKey = 'test-key-1';
+
+        return [
+            'resultJson.setData' => [
+                'success' => 1,
+                'error' => false
+            ],
+            'request.getPost' => [
+                [
+                    'agreement',
+                    [],
+                    [
+                        $testKey => 'test-value-1'
+                    ]
+                ],
+                [
+                    'payment',
+                    [],
+                    $data
+                ],
+            ],
+            'payment.importData' => $data,
+            'agreementsValidator.isValid' => [$testKey],
+            'objectManager.get' => [
+                ['Magento\Checkout\Model\Type\Onepage', $this->onepageMock],
+                ['Magento\Checkout\Model\Agreements\AgreementsValidator', $this->agreementsValidatorMock],
+            ]
+        ];
+    }
+}
diff --git a/app/code/Magento/Checkout/composer.json b/app/code/Magento/Checkout/composer.json
index 266290632764108d9de90c7d0d6a60a447173e5e..8d4be858de464bba4a902109399ecb0da8c843c6 100644
--- a/app/code/Magento/Checkout/composer.json
+++ b/app/code/Magento/Checkout/composer.json
@@ -3,32 +3,32 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-sales": "0.74.0-beta6",
-        "magento/module-catalog-inventory": "0.74.0-beta6",
-        "magento/module-config": "0.74.0-beta6",
-        "magento/module-customer": "0.74.0-beta6",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/module-payment": "0.74.0-beta6",
-        "magento/module-shipping": "0.74.0-beta6",
-        "magento/module-tax": "0.74.0-beta6",
-        "magento/module-directory": "0.74.0-beta6",
-        "magento/module-eav": "0.74.0-beta6",
-        "magento/module-gift-message": "0.74.0-beta6",
-        "magento/module-wishlist": "0.74.0-beta6",
-        "magento/module-page-cache": "0.74.0-beta6",
-        "magento/module-theme": "0.74.0-beta6",
-        "magento/module-msrp": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
-        "magento/module-ui": "0.74.0-beta6",
-        "magento/module-quote": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-sales": "0.74.0-beta7",
+        "magento/module-catalog-inventory": "0.74.0-beta7",
+        "magento/module-config": "0.74.0-beta7",
+        "magento/module-customer": "0.74.0-beta7",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/module-payment": "0.74.0-beta7",
+        "magento/module-shipping": "0.74.0-beta7",
+        "magento/module-tax": "0.74.0-beta7",
+        "magento/module-directory": "0.74.0-beta7",
+        "magento/module-eav": "0.74.0-beta7",
+        "magento/module-gift-message": "0.74.0-beta7",
+        "magento/module-wishlist": "0.74.0-beta7",
+        "magento/module-page-cache": "0.74.0-beta7",
+        "magento/module-theme": "0.74.0-beta7",
+        "magento/module-msrp": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
+        "magento/module-ui": "0.74.0-beta7",
+        "magento/module-quote": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "suggest": {
-        "magento/module-cookie": "0.74.0-beta6"
+        "magento/module-cookie": "0.74.0-beta7"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js b/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js
index d3c3a264b88d814fd8123aa84bc1df10d3828aa6..31e16ff05c81bd932e7250420acce9e270f46aa4 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js
@@ -60,11 +60,13 @@ define([
          * @private
          */
         _isOverflowed: function() {
-            var list = $(this.options.minicart.list);
+            var list = $(this.options.minicart.list),
+                cssOverflowClass = 'overflowed';
+
             if (this.scrollHeight > list.innerHeight()) {
-                list.parent().addClass('overflowed');
+                list.parent().addClass(cssOverflowClass);
             } else {
-                list.parent().removeClass('overflowed');
+                list.parent().removeClass(cssOverflowClass);
             }
         },
 
@@ -238,9 +240,9 @@ define([
             this.scrollHeight = 0;
             target.children().each(function() {
                 if (counter-- > 0) {
-                    height += $(this).height() - 15;
+                    height += $(this).height();
                 }
-                self.scrollHeight += $(this).height() - 15;
+                self.scrollHeight += $(this).height();
             });
 
             target.remove();
diff --git a/app/code/Magento/CheckoutAgreements/composer.json b/app/code/Magento/CheckoutAgreements/composer.json
index 4693f5b11aa25b57cde6a425594a965b1355de7f..4d3341593e7fd0dce401014d7bac7ab32909f36f 100644
--- a/app/code/Magento/CheckoutAgreements/composer.json
+++ b/app/code/Magento/CheckoutAgreements/composer.json
@@ -3,14 +3,14 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-checkout": "0.74.0-beta6",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-checkout": "0.74.0-beta7",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Cms/Block/Adminhtml/Block/Widget/Chooser.php b/app/code/Magento/Cms/Block/Adminhtml/Block/Widget/Chooser.php
index fed2f67da6f177806559e463deb8fda56a2fbb3f..11a83c181d64f504d267524440423a30c90b2970 100644
--- a/app/code/Magento/Cms/Block/Adminhtml/Block/Widget/Chooser.php
+++ b/app/code/Magento/Cms/Block/Adminhtml/Block/Widget/Chooser.php
@@ -81,7 +81,7 @@ class Chooser extends \Magento\Backend\Block\Widget\Grid\Extended
         if ($element->getValue()) {
             $block = $this->_blockFactory->create()->load($element->getValue());
             if ($block->getId()) {
-                $chooser->setLabel($block->getTitle());
+                $chooser->setLabel($this->escapeHtml($block->getTitle()));
             }
         }
 
diff --git a/app/code/Magento/Cms/Block/Adminhtml/Page/Widget/Chooser.php b/app/code/Magento/Cms/Block/Adminhtml/Page/Widget/Chooser.php
index addaf3f4926b8e05f48833b16e540eb73ad295ef..54c169c890a9b8f8901203bff0a9a3a6d4e69275 100644
--- a/app/code/Magento/Cms/Block/Adminhtml/Page/Widget/Chooser.php
+++ b/app/code/Magento/Cms/Block/Adminhtml/Page/Widget/Chooser.php
@@ -98,7 +98,7 @@ class Chooser extends \Magento\Backend\Block\Widget\Grid\Extended
         if ($element->getValue()) {
             $page = $this->_pageFactory->create()->load((int)$element->getValue());
             if ($page->getId()) {
-                $chooser->setLabel($page->getTitle());
+                $chooser->setLabel($this->escapeHtml($page->getTitle()));
             }
         }
 
diff --git a/app/code/Magento/Cms/Controller/Adminhtml/AbstractMassDelete.php b/app/code/Magento/Cms/Controller/Adminhtml/AbstractMassDelete.php
index defddb18779229876ae60ca59e9b40491885aedf..68cf470787c9c520135bf878c674abd922414aae 100755
--- a/app/code/Magento/Cms/Controller/Adminhtml/AbstractMassDelete.php
+++ b/app/code/Magento/Cms/Controller/Adminhtml/AbstractMassDelete.php
@@ -1,6 +1,5 @@
 <?php
 /**
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
@@ -21,7 +20,7 @@ class AbstractMassDelete extends \Magento\Backend\App\Action
     /**
      * Redirect url
      */
-    const REDIRECT_URL = '*/*/index';
+    const REDIRECT_URL = '*/*/';
 
     /**
      * Resource collection
@@ -45,17 +44,17 @@ class AbstractMassDelete extends \Magento\Backend\App\Action
      */
     public function execute()
     {
-        $data = $this->getRequest()->getParam('massaction', '[]');
-        $data = json_decode($data, true);
+        $selected = $this->getRequest()->getParam('selected');
+        $excluded = $this->getRequest()->getParam('excluded');
 
-        if (isset($data['all_selected']) && $data['all_selected'] === true) {
-            if (!empty($data['excluded'])) {
-                $this->excludedDelete($data['excluded']);
+        if (isset($excluded)) {
+            if (!empty($excluded)) {
+                $this->excludedDelete($excluded);
             } else {
                 $this->deleteAll();
             }
-        } elseif (!empty($data['selected'])) {
-            $this->selectedDelete($data['selected']);
+        } elseif (!empty($selected)) {
+            $this->selectedDelete($selected);
         } else {
             $this->messageManager->addError(__('Please select item(s).'));
         }
diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Page/MassDelete.php b/app/code/Magento/Cms/Controller/Adminhtml/Page/MassDelete.php
index a87024f3ea1e622f46e7f1d540e5f9081932bcaf..b255b784a1ac9358e53238425db74b889432eb99 100644
--- a/app/code/Magento/Cms/Controller/Adminhtml/Page/MassDelete.php
+++ b/app/code/Magento/Cms/Controller/Adminhtml/Page/MassDelete.php
@@ -1,6 +1,5 @@
 <?php
 /**
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
diff --git a/app/code/Magento/Cms/Model/Block/DataProvider.php b/app/code/Magento/Cms/Model/Block/DataProvider.php
new file mode 100644
index 0000000000000000000000000000000000000000..71994a060b0812b0997fc3c4b026e5ae2b3c206c
--- /dev/null
+++ b/app/code/Magento/Cms/Model/Block/DataProvider.php
@@ -0,0 +1,221 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Cms\Model\Block;
+
+use Magento\Cms\Model\Resource\Block\Collection;
+use Magento\Cms\Model\Resource\Block\CollectionFactory;
+use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface;
+
+/**
+ * Class DataProvider
+ */
+class DataProvider implements DataProviderInterface
+{
+    /**
+     * @var string
+     */
+    protected $primaryFieldName;
+
+    /**
+     * @var string
+     */
+    protected $requestFieldName;
+
+    /**
+     * @var CollectionFactory
+     */
+    protected $collectionFactory;
+
+    /**
+     * @var Collection
+     */
+    protected $collection;
+
+    /**
+     * Provider configuration data
+     *
+     * @var array
+     */
+    protected $data = [];
+
+    /**
+     * @param string $primaryFieldName
+     * @param string $requestFieldName
+     * @param CollectionFactory $collectionFactory
+     * @param array $meta
+     * @param array $data
+     */
+    public function __construct(
+        $primaryFieldName,
+        $requestFieldName,
+        CollectionFactory $collectionFactory,
+        array $meta = [],
+        array $data = []
+    ) {
+        $this->primaryFieldName = $primaryFieldName;
+        $this->requestFieldName = $requestFieldName;
+        $this->collection = $collectionFactory->create();
+        $this->meta = $meta;
+        $this->data = $data;
+    }
+
+    /**
+     * @return array
+     */
+    public function getMeta()
+    {
+        return $this->meta;
+    }
+
+    /**
+     * @param string $fieldSetName
+     * @param string $fieldName
+     * @return array
+     */
+    public function getFieldMetaInfo($fieldSetName, $fieldName)
+    {
+        return isset($this->meta[$fieldSetName]['fields'][$fieldName])
+            ? $this->meta[$fieldSetName]['fields'][$fieldName]
+            : [];
+    }
+
+    /**
+     * Get data
+     *
+     * @return array
+     */
+    public function getData()
+    {
+        return $this->collection->toArray();
+    }
+
+    /**
+     * Get field name in request
+     *
+     * @return string
+     */
+    public function getRequestFieldName()
+    {
+        return $this->requestFieldName;
+    }
+
+    /**
+     * Get primary field name
+     *
+     * @return string
+     */
+    public function getPrimaryFieldName()
+    {
+        return $this->primaryFieldName;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function addFilter($field, $condition = null)
+    {
+        $this->collection->addFieldToFilter($field, $condition);
+    }
+
+    /**
+     * Add field to select
+     *
+     * @param string|array $field
+     * @param string|null $alias
+     * @return void
+     */
+    public function addField($field, $alias = null)
+    {
+        $this->collection->addFieldToSelect($field, $alias);
+    }
+
+    /**
+     * Add ORDER BY to the end or to the beginning
+     *
+     * @param string $field
+     * @param string $direction
+     * @return void
+     */
+    public function addOrder($field, $direction)
+    {
+        $this->collection->addOrder($field, $direction);
+    }
+
+    /**
+     * Set Query limit
+     *
+     * @param int $offset
+     * @param int $size
+     * @return void
+     */
+    public function setLimit($offset, $size)
+    {
+        $this->collection->setPageSize($size);
+        $this->collection->setCurPage($offset);
+    }
+
+    /**
+     * Removes field from select
+     *
+     * @param string|null $field
+     * @param bool $isAlias Alias identifier
+     * @return void
+     */
+    public function removeField($field, $isAlias = false)
+    {
+        $this->collection->removeFieldFromSelect($field, $isAlias);
+    }
+
+    /**
+     * Removes all fields from select
+     *
+     * @return void
+     */
+    public function removeAllFields()
+    {
+        $this->collection->removeAllFieldsFromSelect();
+    }
+
+    /**
+     * Retrieve count of loaded items
+     *
+     * @return int
+     */
+    public function count()
+    {
+        return $this->collection->count();
+    }
+
+    /**
+     * Get config data
+     *
+     * @return mixed
+     */
+    public function getConfigData()
+    {
+        return isset($this->data['config']) ? $this->data['config'] : [];
+    }
+
+    /**
+     * Set data
+     *
+     * @param mixed $config
+     * @return void
+     */
+    public function setConfigData($config)
+    {
+        $this->data['config'] = $config;
+    }
+
+    /**
+     * @param string $fieldSetName
+     * @return array
+     */
+    public function getFieldsMetaInfo($fieldSetName)
+    {
+        return isset($this->meta[$fieldSetName]['fields']) ? $this->meta[$fieldSetName]['fields'] : [];
+    }
+}
diff --git a/app/code/Magento/Cms/Model/Page/DataProvider.php b/app/code/Magento/Cms/Model/Page/DataProvider.php
new file mode 100644
index 0000000000000000000000000000000000000000..4797ffbe28c84f086f2a45cb8b084db9ccd2389b
--- /dev/null
+++ b/app/code/Magento/Cms/Model/Page/DataProvider.php
@@ -0,0 +1,228 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Cms\Model\Page;
+
+use Magento\Cms\Model\Resource\Page\Collection;
+use Magento\Cms\Model\Resource\Page\CollectionFactory;
+use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface;
+
+/**
+ * Class DataProvider
+ */
+class DataProvider implements DataProviderInterface
+{
+    /**
+     * @var string
+     */
+    protected $primaryFieldName;
+
+    /**
+     * @var string
+     */
+    protected $requestFieldName;
+
+    /**
+     * @var CollectionFactory
+     */
+    protected $collectionFactory;
+
+    /**
+     * @var Collection
+     */
+    protected $collection;
+
+    /**
+     * @var array
+     */
+    protected $meta = [];
+
+    /**
+     * Provider configuration data
+     *
+     * @var array
+     */
+    protected $data = [];
+
+    /**
+     * @param string $primaryFieldName
+     * @param string $requestFieldName
+     * @param CollectionFactory $collectionFactory
+     * @param array $meta
+     * @param array $data
+     */
+    public function __construct(
+        $primaryFieldName,
+        $requestFieldName,
+        CollectionFactory $collectionFactory,
+        array $meta = [],
+        array $data = []
+    ) {
+        $this->primaryFieldName = $primaryFieldName;
+        $this->requestFieldName = $requestFieldName;
+
+        $this->collection = $collectionFactory->create();
+        $this->collection->setFirstStoreFlag(true);
+        $this->meta = $meta;
+        $this->data = $data;
+    }
+
+    /**
+     * @return array
+     */
+    public function getMeta()
+    {
+        return $this->meta;
+    }
+
+    /**
+     * Get data
+     *
+     * @return array
+     */
+    public function getData()
+    {
+        return $this->collection->toArray();
+    }
+
+    /**
+     * @param string $fieldSetName
+     * @param string $fieldName
+     * @return array
+     */
+    public function getFieldMetaInfo($fieldSetName, $fieldName)
+    {
+        return isset($this->meta[$fieldSetName]['fields'][$fieldName])
+            ? $this->meta[$fieldSetName]['fields'][$fieldName]
+            : [];
+    }
+
+    /**
+     * Get field name in request
+     *
+     * @return string
+     */
+    public function getRequestFieldName()
+    {
+        return $this->requestFieldName;
+    }
+
+    /**
+     * Get primary field name
+     *
+     * @return string
+     */
+    public function getPrimaryFieldName()
+    {
+        return $this->primaryFieldName;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function addFilter($field, $condition = null)
+    {
+        $this->collection->addFieldToFilter($field, $condition);
+    }
+
+    /**
+     * Add field to select
+     *
+     * @param string|array $field
+     * @param string|null $alias
+     * @return void
+     */
+    public function addField($field, $alias = null)
+    {
+        $this->collection->addFieldToSelect($field, $alias);
+    }
+
+    /**
+     * self::setOrder() alias
+     *
+     * @param string $field
+     * @param string $direction
+     * @return void
+     */
+    public function addOrder($field, $direction)
+    {
+        $this->collection->addOrder($field, $direction);
+    }
+
+    /**
+     * Set Query limit
+     *
+     * @param int $offset
+     * @param int $size
+     * @return void
+     */
+    public function setLimit($offset, $size)
+    {
+        $this->collection->setPageSize($size);
+        $this->collection->setCurPage($offset);
+    }
+
+    /**
+     * Removes field from select
+     *
+     * @param string|null $field
+     * @param bool $isAlias Alias identifier
+     * @return void
+     */
+    public function removeField($field, $isAlias = false)
+    {
+        $this->collection->removeFieldFromSelect($field, $isAlias);
+    }
+
+    /**
+     * Removes all fields from select
+     *
+     * @return void
+     */
+    public function removeAllFields()
+    {
+        $this->collection->removeAllFieldsFromSelect();
+    }
+
+    /**
+     * Retrieve count of loaded items
+     *
+     * @return int
+     */
+    public function count()
+    {
+        return $this->collection->count();
+    }
+
+    /**
+     * Get config data
+     *
+     * @return mixed
+     */
+    public function getConfigData()
+    {
+        return isset($this->data['config']) ? $this->data['config'] : [];
+    }
+
+    /**
+     * Set data
+     *
+     * @param mixed $config
+     * @return void
+     */
+    public function setConfigData($config)
+    {
+        $this->data['config'] = $config;
+    }
+
+    /**
+     * @param string $fieldSetName
+     * @return array
+     */
+    public function getFieldsMetaInfo($fieldSetName)
+    {
+        return isset($this->meta[$fieldSetName]['fields']) ? $this->meta[$fieldSetName]['fields'] : [];
+    }
+}
diff --git a/app/code/Magento/Cms/Ui/DataProvider/Page/Options/IsActive.php b/app/code/Magento/Cms/Model/Page/Source/IsActive.php
similarity index 57%
rename from app/code/Magento/Cms/Ui/DataProvider/Page/Options/IsActive.php
rename to app/code/Magento/Cms/Model/Page/Source/IsActive.php
index 4934fc0297f229360d249ee23fe43dda37be7599..7c9d153e5a5a5d8cb363e4830c8e096f82cb92d3 100644
--- a/app/code/Magento/Cms/Ui/DataProvider/Page/Options/IsActive.php
+++ b/app/code/Magento/Cms/Model/Page/Source/IsActive.php
@@ -3,14 +3,14 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-namespace Magento\Cms\Ui\DataProvider\Page\Options;
+namespace Magento\Cms\Model\Page\Source;
 
-use Magento\Ui\Component\Listing\OptionsInterface;
+use Magento\Framework\Data\OptionSourceInterface;
 
 /**
  * Class IsActive
  */
-class IsActive implements OptionsInterface
+class IsActive implements OptionSourceInterface
 {
     /**
      * @var \Magento\Cms\Model\Page
@@ -30,19 +30,18 @@ class IsActive implements OptionsInterface
     /**
      * Get options
      *
-     * @param array $options
      * @return array
      */
-    public function getOptions(array $options = [])
+    public function toOptionArray()
     {
-        $newOptions = $this->cmsPage->getAvailableStatuses();
-        foreach ($newOptions as $key => $value) {
-            $newOptions[$key] = [
+        $options = [];
+        $availableOptions = $this->cmsPage->getAvailableStatuses();
+        foreach ($availableOptions as $key => $value) {
+            $options[$key] = [
                 'label' => $value,
                 'value' => $key,
             ];
         }
-
-        return array_merge_recursive($newOptions, $options);
+        return $options;
     }
 }
diff --git a/app/code/Magento/Cms/Ui/DataProvider/Page/Options/PageLayout.php b/app/code/Magento/Cms/Model/Page/Source/PageLayout.php
similarity index 55%
rename from app/code/Magento/Cms/Ui/DataProvider/Page/Options/PageLayout.php
rename to app/code/Magento/Cms/Model/Page/Source/PageLayout.php
index 7a053e0fd3948891f3fa1d10aa5e690d586aecf6..32e8878dbe5b277ea401f09a6098cddeae4eeef8 100644
--- a/app/code/Magento/Cms/Ui/DataProvider/Page/Options/PageLayout.php
+++ b/app/code/Magento/Cms/Model/Page/Source/PageLayout.php
@@ -3,21 +3,26 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-namespace Magento\Cms\Ui\DataProvider\Page\Options;
+namespace Magento\Cms\Model\Page\Source;
 
+use Magento\Framework\Data\OptionSourceInterface;
 use Magento\Framework\View\Model\PageLayout\Config\BuilderInterface;
-use Magento\Ui\Component\Listing\OptionsInterface;
 
 /**
  * Class PageLayout
  */
-class PageLayout implements OptionsInterface
+class PageLayout implements OptionSourceInterface
 {
     /**
      * @var \Magento\Framework\View\Model\PageLayout\Config\BuilderInterface
      */
     protected $pageLayoutBuilder;
 
+    /**
+     * @var array
+     */
+    protected $options;
+
     /**
      * Constructor
      *
@@ -31,19 +36,23 @@ class PageLayout implements OptionsInterface
     /**
      * Get options
      *
-     * @param array $options
      * @return array
      */
-    public function getOptions(array $options = [])
+    public function toOptionArray()
     {
-        $newOptions = $this->pageLayoutBuilder->getPageLayoutsConfig()->getOptions();
-        foreach ($newOptions as $key => $value) {
-            $newOptions[$key] = [
+        if ($this->options !== null) {
+            return $this->options;
+        }
+        $options = [];
+        $configOptions = $this->pageLayoutBuilder->getPageLayoutsConfig()->getOptions();
+        foreach ($configOptions as $key => $value) {
+            $options[$key] = [
                 'label' => $value,
                 'value' => $key,
             ];
         }
+        $this->options = $options;
 
-        return array_merge_recursive($newOptions, $options);
+        return $this->options;
     }
 }
diff --git a/app/code/Magento/Cms/Test/Unit/Block/Adminhtml/Block/Widget/ChooserTest.php b/app/code/Magento/Cms/Test/Unit/Block/Adminhtml/Block/Widget/ChooserTest.php
index 0c075194e3330d099d7bb12b2427b971621f8a81..55761dae44ac94230eb126aa182e22394aaf1d32 100644
--- a/app/code/Magento/Cms/Test/Unit/Block/Adminhtml/Block/Widget/ChooserTest.php
+++ b/app/code/Magento/Cms/Test/Unit/Block/Adminhtml/Block/Widget/ChooserTest.php
@@ -35,6 +35,11 @@ class ChooserTest extends \PHPUnit_Framework_TestCase
      */
     protected $urlBuilderMock;
 
+    /**
+     * @var \Magento\Framework\Escaper|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $escaper;
+
     /**
      * @var \Magento\Cms\Model\BlockFactory|\PHPUnit_Framework_MockObject_MockObject
      */
@@ -66,6 +71,14 @@ class ChooserTest extends \PHPUnit_Framework_TestCase
         $this->urlBuilderMock = $this->getMockBuilder('Magento\Framework\UrlInterface')
             ->disableOriginalConstructor()
             ->getMock();
+        $this->escaper = $this->getMockBuilder('Magento\Framework\Escaper')
+            ->disableOriginalConstructor()
+            ->setMethods(
+                [
+                    'escapeHtml',
+                ]
+            )
+            ->getMock();
         $this->blockFactoryMock = $this->getMockBuilder('Magento\Cms\Model\BlockFactory')
             ->setMethods(
                 [
@@ -90,6 +103,7 @@ class ChooserTest extends \PHPUnit_Framework_TestCase
                 [
                     'getTitle',
                     'load',
+                    'getId',
                 ]
             )
             ->getMock();
@@ -112,15 +126,16 @@ class ChooserTest extends \PHPUnit_Framework_TestCase
         $this->context = $objectManager->getObject(
             'Magento\Backend\Block\Template\Context',
             [
-                'layout' => $this->layoutMock,
+                'layout'     => $this->layoutMock,
                 'mathRandom' => $this->mathRandomMock,
-                'urlBuilder' => $this->urlBuilderMock
+                'urlBuilder' => $this->urlBuilderMock,
+                'escaper'    => $this->escaper,
             ]
         );
         $this->this = $objectManager->getObject(
             'Magento\Cms\Block\Adminhtml\Block\Widget\Chooser',
             [
-                'context' => $this->context,
+                'context'      => $this->context,
                 'blockFactory' => $this->blockFactoryMock
             ]
         );
@@ -135,13 +150,14 @@ class ChooserTest extends \PHPUnit_Framework_TestCase
      */
     public function testPrepareElementHtml($elementValue, $modelBlockId)
     {
-        $elementId = 1;
-        $uniqId = '126hj4h3j73hk7b347jhkl37gb34';
-        $sourceUrl = 'cms/block_widget/chooser/126hj4h3j73hk7b347jhkl37gb34';
-        $config = ['key1' => 'value1'];
-        $fieldsetId = 2;
-        $html = 'some html';
-        $title = 'some title';
+        $elementId    = 1;
+        $uniqId       = '126hj4h3j73hk7b347jhkl37gb34';
+        $sourceUrl    = 'cms/block_widget/chooser/126hj4h3j73hk7b347jhkl37gb34';
+        $config       = ['key1' => 'value1'];
+        $fieldsetId   = 2;
+        $html         = 'some html';
+        $title        = 'some "><img src=y onerror=prompt(document.domain)>; title';
+        $titleEscaped = 'some &quot;&gt;&lt;img src=y onerror=prompt(document.domain)&gt;; title';
 
         $this->this->setConfig($config);
         $this->this->setFieldsetId($fieldsetId);
@@ -197,13 +213,18 @@ class ChooserTest extends \PHPUnit_Framework_TestCase
         $this->modelBlockMock->expects($this->any())
             ->method('getTitle')
             ->willReturn($title);
-        $this->chooserMock->expects($this->any())
-            ->method('setLabel')
-            ->with($title)
-            ->willReturnSelf();
         $this->chooserMock->expects($this->atLeastOnce())
             ->method('toHtml')
             ->willReturn($html);
+        if (!empty($elementValue) && !empty($modelBlockId)) {
+            $this->escaper->expects(($this->atLeastOnce()))
+                ->method('escapeHtml')
+                ->willReturn($titleEscaped);
+            $this->chooserMock->expects($this->atLeastOnce())
+                ->method('setLabel')
+                ->with($titleEscaped)
+                ->willReturnSelf();
+        }
         $this->elementMock->expects($this->atLeastOnce())
             ->method('setData')
             ->with('after_element_html', $html)
diff --git a/app/code/Magento/Cms/Test/Unit/Block/Adminhtml/Page/Widget/ChooserTest.php b/app/code/Magento/Cms/Test/Unit/Block/Adminhtml/Page/Widget/ChooserTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..75107bcb42de11db287607e49595aa6fecfd637b
--- /dev/null
+++ b/app/code/Magento/Cms/Test/Unit/Block/Adminhtml/Page/Widget/ChooserTest.php
@@ -0,0 +1,271 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Cms\Test\Unit\Block\Adminhtml\Page\Widget;
+
+/**
+ * @covers \Magento\Cms\Block\Adminhtml\Page\Widget\Chooser
+ */
+class ChooserTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Cms\Block\Adminhtml\Page\Widget\Chooser
+     */
+    protected $this;
+
+    /**
+     * @var \Magento\Backend\Block\Template\Context
+     */
+    protected $context;
+
+    /**
+     * @var \Magento\Framework\Math\Random|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $mathRandomMock;
+
+    /**
+     * @var \Magento\Framework\UrlInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $urlBuilderMock;
+
+    /**
+     * @var \Magento\Framework\Escaper|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $escaper;
+
+    /**
+     * @var \Magento\Cms\Model\Page|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $cmsPageMock;
+
+    /**
+     * @var \Magento\Framework\View\LayoutInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $layoutMock;
+
+    /**
+     * @var \Magento\Cms\Model\PageFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $pageFactoryMock;
+
+    /**
+     * @var \Magento\Framework\Data\Form\Element\AbstractElement|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $elementMock;
+
+    /**
+     * @var \Magento\Framework\View\Element\BlockInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $chooserMock;
+
+    protected function setUp()
+    {
+        $this->layoutMock = $this->getMockBuilder('Magento\Framework\View\LayoutInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->mathRandomMock = $this->getMockBuilder('Magento\Framework\Math\Random')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->urlBuilderMock = $this->getMockBuilder('Magento\Framework\UrlInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->escaper = $this->getMockBuilder('Magento\Framework\Escaper')
+            ->disableOriginalConstructor()
+            ->setMethods(
+                [
+                    'escapeHtml',
+                ]
+            )
+            ->getMock();
+        $this->pageFactoryMock = $this->getMockBuilder('Magento\Cms\Model\PageFactory')
+            ->setMethods(
+                [
+                    'create',
+                ]
+            )
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->elementMock = $this->getMockBuilder('Magento\Framework\Data\Form\Element\AbstractElement')
+            ->disableOriginalConstructor()
+            ->setMethods(
+                [
+                    'getId',
+                    'getValue',
+                    'setData',
+                ]
+            )
+            ->getMock();
+        $this->cmsPageMock = $this->getMockBuilder('Magento\Cms\Model\Page')
+            ->disableOriginalConstructor()
+            ->setMethods(
+                [
+                    'getTitle',
+                    'load',
+                    'getId',
+                ]
+            )
+            ->getMock();
+        $this->chooserMock = $this->getMockBuilder('Magento\Framework\View\Element\BlockInterface')
+            ->disableOriginalConstructor()
+            ->setMethods(
+                [
+                    'setElement',
+                    'setConfig',
+                    'setFieldsetId',
+                    'setSourceUrl',
+                    'setUniqId',
+                    'setLabel',
+                    'toHtml',
+                ]
+            )
+            ->getMock();
+
+        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $this->context = $objectManager->getObject(
+            'Magento\Backend\Block\Template\Context',
+            [
+                'layout'     => $this->layoutMock,
+                'mathRandom' => $this->mathRandomMock,
+                'urlBuilder' => $this->urlBuilderMock,
+                'escaper'    => $this->escaper,
+            ]
+        );
+        $this->this = $objectManager->getObject(
+            'Magento\Cms\Block\Adminhtml\Page\Widget\Chooser',
+            [
+                'context'     => $this->context,
+                'pageFactory' => $this->pageFactoryMock
+            ]
+        );
+    }
+
+    /**
+     * @covers \Magento\Cms\Block\Adminhtml\Block\Widget\Chooser::prepareElementHtml
+     *
+     * @param string $elementValue
+     * @param integer|null $cmsPageId
+     *
+     * @dataProvider prepareElementHtmlDataProvider
+     */
+    public function testPrepareElementHtml($elementValue, $cmsPageId)
+    {
+        //$elementValue = 12345;
+        //$cmsPageId    = 1;
+        $elementId    = 1;
+        $uniqId       = '126hj4h3j73hk7b347jhkl37gb34';
+        $sourceUrl    = 'cms/page_widget/chooser/126hj4h3j73hk7b347jhkl37gb34';
+        $config       = ['key1' => 'value1'];
+        $fieldsetId   = 2;
+        $html         = 'some html';
+        $title        = 'some "><img src=y onerror=prompt(document.domain)>; title';
+        $titleEscaped = 'some &quot;&gt;&lt;img src=y onerror=prompt(document.domain)&gt;; title';
+
+        $this->this->setConfig($config);
+        $this->this->setFieldsetId($fieldsetId);
+
+        $this->elementMock->expects($this->atLeastOnce())
+            ->method('getId')
+            ->willReturn($elementId);
+        $this->mathRandomMock->expects($this->atLeastOnce())
+            ->method('getUniqueHash')
+            ->with($elementId)
+            ->willReturn($uniqId);
+        $this->urlBuilderMock->expects($this->atLeastOnce())
+            ->method('getUrl')
+            ->with('cms/page_widget/chooser', ['uniq_id' => $uniqId])
+            ->willReturn($sourceUrl);
+        $this->layoutMock->expects($this->atLeastOnce())
+            ->method('createBlock')
+            ->with('Magento\Widget\Block\Adminhtml\Widget\Chooser')
+            ->willReturn($this->chooserMock);
+        $this->chooserMock->expects($this->atLeastOnce())
+            ->method('setElement')
+            ->with($this->elementMock)
+            ->willReturnSelf();
+        $this->chooserMock->expects($this->atLeastOnce())
+            ->method('setConfig')
+            ->with($config)
+            ->willReturnSelf();
+        $this->chooserMock->expects($this->atLeastOnce())
+            ->method('setFieldsetId')
+            ->with($fieldsetId)
+            ->willReturnSelf();
+        $this->chooserMock->expects($this->atLeastOnce())
+            ->method('setSourceUrl')
+            ->with($sourceUrl)
+            ->willReturnSelf();
+        $this->chooserMock->expects($this->atLeastOnce())
+            ->method('setUniqId')
+            ->with($uniqId)
+            ->willReturnSelf();
+        $this->elementMock->expects($this->atLeastOnce())
+            ->method('getValue')
+            ->willReturn($elementValue);
+        $this->pageFactoryMock->expects($this->any())
+            ->method('create')
+            ->willReturn($this->cmsPageMock);
+        $this->cmsPageMock->expects($this->any())
+            ->method('load')
+            ->with((int)$elementValue)
+            ->willReturnSelf();
+        $this->cmsPageMock->expects($this->any())
+            ->method('getId')
+            ->willReturn($cmsPageId);
+        $this->cmsPageMock->expects($this->any())
+            ->method('getTitle')
+            ->willReturn($title);
+        $this->chooserMock->expects($this->atLeastOnce())
+            ->method('toHtml')
+            ->willReturn($html);
+        if (!empty($elementValue) && !empty($cmsPageId)) {
+            $this->escaper->expects(($this->atLeastOnce()))
+                ->method('escapeHtml')
+                ->willReturn($titleEscaped);
+            $this->chooserMock->expects($this->atLeastOnce())
+                ->method('setLabel')
+                ->with($titleEscaped)
+                ->willReturnSelf();
+        }
+        $this->elementMock->expects($this->atLeastOnce())
+            ->method('setData')
+            ->with('after_element_html', $html)
+            ->willReturnSelf();
+
+        $this->assertEquals($this->elementMock, $this->this->prepareElementHtml($this->elementMock));
+    }
+
+    public function prepareElementHtmlDataProvider()
+    {
+        return [
+            'elementValue NOT EMPTY, modelBlockId NOT EMPTY' => [
+                'elementValue' => 'some value',
+                'cmsPageId' => 1,
+            ],
+            'elementValue NOT EMPTY, modelBlockId IS EMPTY' => [
+                'elementValue' => 'some value',
+                'cmsPageId' => null,
+            ],
+            'elementValue IS EMPTY, modelBlockId NEVER REACHED' => [
+                'elementValue' => '',
+                'cmsPageId' => 1,
+            ]
+        ];
+    }
+
+    /**
+     * @covers \Magento\Cms\Block\Adminhtml\Page\Widget\Chooser::getGridUrl
+     */
+    public function testGetGridUrl()
+    {
+        $url = 'some url';
+
+        $this->urlBuilderMock->expects($this->atLeastOnce())
+            ->method('getUrl')
+            ->with('cms/page_widget/chooser', ['_current' => true])
+            ->willReturn($url);
+
+        $this->assertEquals($url, $this->this->getGridUrl());
+    }
+}
diff --git a/app/code/Magento/Cms/Ui/Component/Listing/Column/BlockActions.php b/app/code/Magento/Cms/Ui/Component/Listing/Column/BlockActions.php
new file mode 100644
index 0000000000000000000000000000000000000000..ecdf19a805f4cda93e6528a07b47cde1c2b97e14
--- /dev/null
+++ b/app/code/Magento/Cms/Ui/Component/Listing/Column/BlockActions.php
@@ -0,0 +1,66 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Cms\Ui\Component\Listing\Column;
+
+use Magento\Framework\UrlInterface;
+use Magento\Framework\View\Element\UiComponent\ContextInterface;
+use Magento\Framework\View\Element\UiComponentFactory;
+use Magento\Ui\Component\Listing\Columns\Column;
+
+/**
+ * Class BlockActions
+ */
+class BlockActions extends Column
+{
+    /**
+     * Url path
+     */
+    const URL_PATH = 'cms/block/edit';
+
+    /**
+     * @var UrlInterface
+     */
+    protected $urlBuilder;
+
+    /**
+     * Constructor
+     *
+     * @param ContextInterface $context
+     * @param UiComponentFactory $uiComponentFactory
+     * @param UrlInterface $urlBuilder
+     * @param array $components
+     * @param array $data
+     */
+    public function __construct(
+        ContextInterface $context,
+        UiComponentFactory $uiComponentFactory,
+        UrlInterface $urlBuilder,
+        array $components = [],
+        array $data = []
+    ) {
+        $this->urlBuilder = $urlBuilder;
+        parent::__construct($context, $uiComponentFactory, $components, $data);
+    }
+
+    /**
+     * @param array $items
+     * @return array
+     */
+    public function prepareItems(array & $items)
+    {
+        foreach ($items as & $item) {
+            if (isset($item['block_id'])) {
+                $item[$this->getData('name')] = [
+                    'edit' => [
+                        'href' => $this->urlBuilder->getUrl(static::URL_PATH, ['block_id' => $item['block_id']]),
+                        'label' => __('Edit'),
+                    ]
+                ];
+            }
+        }
+        return $items;
+    }
+}
diff --git a/app/code/Magento/Cms/Ui/Component/Listing/Column/PageActions.php b/app/code/Magento/Cms/Ui/Component/Listing/Column/PageActions.php
new file mode 100644
index 0000000000000000000000000000000000000000..2a8140c0923cf2ac52304dc6ad67f8a2240e773a
--- /dev/null
+++ b/app/code/Magento/Cms/Ui/Component/Listing/Column/PageActions.php
@@ -0,0 +1,86 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Cms\Ui\Component\Listing\Column;
+
+use Magento\Framework\View\Element\UiComponent\ContextInterface;
+use Magento\Framework\View\Element\UiComponentFactory;
+use Magento\Ui\Component\Listing\Columns\Column;
+use Magento\Cms\Block\Adminhtml\Page\Grid\Renderer\Action\UrlBuilder;
+use Magento\Framework\UrlInterface;
+
+/**
+ * Class PageActions
+ */
+class PageActions extends Column
+{
+    /**
+     * Url path
+     */
+    const URL_PATH = 'cms/page/edit';
+
+    /**
+     * @var UrlBuilder
+     */
+    protected $actionUrlBuilder;
+
+    /**
+     * @var UrlInterface
+     */
+    protected $urlBuilder;
+
+
+    /**
+     * Constructor
+     *
+     * @param ContextInterface $context
+     * @param UiComponentFactory $uiComponentFactory
+     * @param UrlBuilder $actionUrlBuilder
+     * @param UrlInterface $urlBuilder
+     * @param array $components
+     * @param array $data
+     */
+    public function __construct(
+        ContextInterface $context,
+        UiComponentFactory $uiComponentFactory,
+        UrlBuilder $actionUrlBuilder,
+        UrlInterface $urlBuilder,
+        array $components = [],
+        array $data = []
+    ) {
+        $this->urlBuilder = $urlBuilder;
+        $this->actionUrlBuilder = $actionUrlBuilder;
+        parent::__construct($context, $uiComponentFactory, $components, $data);
+    }
+
+    /**
+     * @param array $items
+     * @return array
+     */
+    public function prepareItems(array & $items)
+    {
+        foreach ($items as & $item) {
+            if (isset($item['page_id'])) {
+                $item[$this->getData('name')]['edit'] = [
+                    'href' => $this->urlBuilder->getUrl(static::URL_PATH, ['page_id' => $item['page_id']]),
+                    'label' => __('Edit'),
+                    'hidden' => true
+                ];
+            }
+            if (isset($item['identifier'])) {
+                $item[$this->getData('name')]['preview'] = [
+                    'href' => $this->actionUrlBuilder->getUrl(
+                        $item['identifier'],
+                        isset($item['_first_store_id']) ? $item['_first_store_id'] : null,
+                        isset($item['store_code']) ? $item['store_code'] : null
+                    ),
+                    'label' => __('Preview')
+                ];
+            }
+        }
+
+        return $items;
+    }
+}
diff --git a/app/code/Magento/Cms/composer.json b/app/code/Magento/Cms/composer.json
index 9ee9de410e132ace5520da29bfb9f6edc89fb4c7..9b0c037e3e12103a5985b9972867b36512e3c63c 100644
--- a/app/code/Magento/Cms/composer.json
+++ b/app/code/Magento/Cms/composer.json
@@ -3,20 +3,20 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-theme": "0.74.0-beta6",
-        "magento/module-widget": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/module-email": "0.74.0-beta6",
-        "magento/module-ui": "0.74.0-beta6",
-        "magento/module-variable": "0.74.0-beta6",
-        "magento/module-media-storage": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-theme": "0.74.0-beta7",
+        "magento/module-widget": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/module-email": "0.74.0-beta7",
+        "magento/module-ui": "0.74.0-beta7",
+        "magento/module-variable": "0.74.0-beta7",
+        "magento/module-media-storage": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Cms/view/adminhtml/layout/cms_block_index.xml b/app/code/Magento/Cms/view/adminhtml/layout/cms_block_index.xml
index 2e9d8a6ea0b25b06093db7dfb319d280866d1fac..dbdf185d5083e02bd98847af6d282fc1f0de91b3 100644
--- a/app/code/Magento/Cms/view/adminhtml/layout/cms_block_index.xml
+++ b/app/code/Magento/Cms/view/adminhtml/layout/cms_block_index.xml
@@ -8,7 +8,8 @@
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
     <body>
         <referenceContainer name="content">
-            <ui_component name="cms_block_listing" component="listing"/>
+            <uiComponent name="cms_block_listing"/>
         </referenceContainer>
+        <referenceContainer name="admin.scope.col.wrap" htmlClass="admin__old" /> <!-- ToDo UI: remove this wrapper with old styles removal. The class name "admin__old" is for tests only, we shouldn't use it in any way -->
     </body>
 </page>
diff --git a/app/code/Magento/Cms/view/adminhtml/layout/cms_block_listing.xml b/app/code/Magento/Cms/view/adminhtml/layout/cms_block_listing.xml
index 6f1975adb97cd11e5032ed1b455183ac0a653f31..22788b865327bc82bdaa19f196bcbb469bdaeea1 100644
--- a/app/code/Magento/Cms/view/adminhtml/layout/cms_block_listing.xml
+++ b/app/code/Magento/Cms/view/adminhtml/layout/cms_block_listing.xml
@@ -92,14 +92,6 @@
                         </item>
                     </item>
                 </argument>
-                <argument name="row_data_provider" xsi:type="array">
-                    <item name="actions" xsi:type="array">
-                        <item name="class" xsi:type="string">Magento\Cms\Ui\DataProvider\Block\Row\Actions</item>
-                    </item>
-                    <item name="store_id" xsi:type="array">
-                        <item name="class" xsi:type="string">Magento\Store\Ui\DataProvider\Row</item>
-                    </item>
-                </argument>
             </arguments>
         </referenceBlock>
         <referenceBlock name="sorting">
diff --git a/app/code/Magento/Cms/view/adminhtml/layout/cms_page_index.xml b/app/code/Magento/Cms/view/adminhtml/layout/cms_page_index.xml
index a63fe9f63f08d305c5595171900176096473e033..b5fbe5373d4f837ce76412ae4d417d182eae26d9 100644
--- a/app/code/Magento/Cms/view/adminhtml/layout/cms_page_index.xml
+++ b/app/code/Magento/Cms/view/adminhtml/layout/cms_page_index.xml
@@ -6,9 +6,10 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
+    <update handle="styles"/>
     <body>
         <referenceContainer name="content">
-            <ui_component name="cms_page_listing" component="listing"/>
+            <uiComponent name="cms_page_listing"/>
         </referenceContainer>
     </body>
 </page>
diff --git a/app/code/Magento/Cms/view/adminhtml/layout/cms_page_listing.xml b/app/code/Magento/Cms/view/adminhtml/layout/cms_page_listing.xml
index bebf23cacd86b98d4f7e4f6c3af734c4cba77515..55a8f042883487aa8d6e88524a7e6cbf1ebe6bf6 100644
--- a/app/code/Magento/Cms/view/adminhtml/layout/cms_page_listing.xml
+++ b/app/code/Magento/Cms/view/adminhtml/layout/cms_page_listing.xml
@@ -89,14 +89,6 @@
                         </item>
                     </item>
                 </argument>
-                <argument name="row_data_provider" xsi:type="array">
-                    <item name="actions" xsi:type="array">
-                        <item name="class" xsi:type="string">Magento\Cms\Ui\DataProvider\Page\Row\Actions</item>
-                    </item>
-                    <item name="store_id" xsi:type="array">
-                        <item name="class" xsi:type="string">Magento\Store\Ui\DataProvider\Row</item>
-                    </item>
-                </argument>
             </arguments>
         </referenceBlock>
         <referenceBlock name="massactions">
diff --git a/app/code/Magento/Cms/view/adminhtml/ui_component/cms_block_listing.xml b/app/code/Magento/Cms/view/adminhtml/ui_component/cms_block_listing.xml
new file mode 100644
index 0000000000000000000000000000000000000000..da8c5b01d5ea6cd2ff079669e6404ab400fa8dad
--- /dev/null
+++ b/app/code/Magento/Cms/view/adminhtml/ui_component/cms_block_listing.xml
@@ -0,0 +1,383 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Ui/etc/ui_configuration.xsd">
+    <argument name="context" xsi:type="configurableObject">
+        <argument name="class" xsi:type="string">Magento\Framework\View\Element\UiComponent\Context</argument>
+        <argument name="namespace" xsi:type="string">cms_block_listing</argument>
+    </argument>
+    <argument name="data" xsi:type="array">
+        <item name="js_config" xsi:type="array">
+            <item name="config" xsi:type="array">
+                <item name="provider" xsi:type="string">cms_block_listing.cms_block_listing_data_source</item>
+            </item>
+            <item name="deps" xsi:type="string">cms_block_listing.cms_block_listing_data_source</item>
+        </item>
+        <item name="spinner" xsi:type="string">cms_block_columns</item>
+        <item name="buttons" xsi:type="array">
+            <item name="add" xsi:type="array">
+                <item name="name" xsi:type="string">add</item>
+                <item name="label" xsi:type="string" translate="true">Add New Block</item>
+                <item name="class" xsi:type="string">primary</item>
+                <item name="url" xsi:type="string">*/*/new</item>
+            </item>
+        </item>
+    </argument>
+    <container name="listing_top">
+        <argument name="data" xsi:type="array">
+            <item name="config" xsi:type="array">
+                <item name="template" xsi:type="string">ui/grid/toolbar</item>
+            </item>
+        </argument>
+        <container name="default_view">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="component" xsi:type="string">Magento_Ui/js/grid/controls/view</item>
+                    <item name="displayArea" xsi:type="string">dataGridActions</item>
+                </item>
+            </argument>
+        </container>
+        <container name="columns_controls">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="component" xsi:type="string">Magento_Ui/js/grid/controls/columns</item>
+                    <item name="displayArea" xsi:type="string">dataGridActions</item>
+                </item>
+            </argument>
+        </container>      
+        <filters name="listing_filters">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="displayArea" xsi:type="string">dataGridFilters</item>
+                    <item name="dataScope" xsi:type="string">params.filters</item>
+                </item>
+            </argument>
+            <filterRange name="block_id">
+                <argument name="data" xsi:type="array">
+                    <item name="config" xsi:type="array">
+                        <item name="dataScope" xsi:type="string">block_id</item>
+                        <item name="label" xsi:type="string" translate="true">ID</item>
+                    </item>
+                </argument>
+                <filterInput name="from">
+                    <argument name="data" xsi:type="array">
+                        <item name="config" xsi:type="array">
+                            <item name="dataScope" xsi:type="string">from</item>
+                            <item name="label" xsi:type="string" translate="true">from</item>
+                            <item name="placeholder" xsi:type="string" translate="true">From</item>
+                        </item>
+                    </argument>
+                </filterInput>
+                <filterInput name="to">
+                    <argument name="data" xsi:type="array">
+                        <item name="config" xsi:type="array">
+                            <item name="dataScope" xsi:type="string">to</item>
+                            <item name="label" xsi:type="string" translate="true">to</item>
+                            <item name="placeholder" xsi:type="string" translate="true">To</item>
+                        </item>
+                    </argument>
+                </filterInput>
+            </filterRange>
+            <filterInput name="title">
+                <argument name="data" xsi:type="array">
+                    <item name="config" xsi:type="array">
+                        <item name="dataScope" xsi:type="string">title</item>
+                        <item name="label" xsi:type="string" translate="true">Title</item>
+                    </item>
+                </argument>
+            </filterInput>
+            <filterInput name="identifier">
+                <argument name="data" xsi:type="array">
+                    <item name="config" xsi:type="array">
+                        <item name="dataScope" xsi:type="string">identifier</item>
+                        <item name="label" xsi:type="string" translate="true">Identifier</item>
+                    </item>
+                </argument>
+            </filterInput>
+            <filterSelect name="store_id">
+                <argument name="optionsProvider" xsi:type="configurableObject">
+                    <argument name="class" xsi:type="string">Magento\Store\Ui\Component\Listing\Column\Store\Options</argument>
+                </argument>
+                <argument name="data" xsi:type="array">
+                    <item name="config" xsi:type="array">
+                        <item name="caption" xsi:type="string" translate="true">Select...</item>
+                        <item name="dataScope" xsi:type="string">store_id</item>
+                        <item name="label" xsi:type="string" translate="true">Store View</item>
+                    </item>
+                </argument>
+            </filterSelect>
+            <filterSelect name="is_active">
+                <argument name="data" xsi:type="array">
+                    <item name="config" xsi:type="array">
+                        <item name="caption" xsi:type="string" translate="true">Select...</item>
+                        <item name="label" xsi:type="string" translate="true">Status</item>
+                        <item name="dataScope" xsi:type="string">is_active</item>
+                        <item name="options" xsi:type="array">
+                            <item name="disable" xsi:type="array">
+                                <item name="value" xsi:type="string">0</item>
+                                <item name="label" xsi:type="string" translate="true">Disabled</item>
+                            </item>
+                            <item name="enable" xsi:type="array">
+                                <item name="value" xsi:type="string">1</item>
+                                <item name="label" xsi:type="string" translate="true">Enabled</item>
+                            </item>
+                        </item>
+                    </item>
+                </argument>
+            </filterSelect>
+            <filterRange name="creation_time"  class="Magento\Ui\Component\Filters\Type\DateRange">
+                <argument name="data" xsi:type="array">
+                    <item name="config" xsi:type="array">
+                        <item name="dataScope" xsi:type="string">creation_time</item>
+                        <item name="label" xsi:type="string" translate="true">Created</item>
+                    </item>
+                </argument>
+                <filterDate name="from">
+                    <argument name="data" xsi:type="array">
+                        <item name="config" xsi:type="array">
+                            <item name="dataScope" xsi:type="string">from</item>
+                            <item name="label" xsi:type="string" translate="true">From</item>
+                            <item name="placeholder" xsi:type="string" translate="true">From</item>
+                        </item>
+                    </argument>
+                </filterDate>
+                <filterDate name="to">
+                    <argument name="data" xsi:type="array">
+                        <item name="config" xsi:type="array">
+                            <item name="dataScope" xsi:type="string">to</item>
+                            <item name="label" xsi:type="string" translate="true">To</item>
+                            <item name="placeholder" xsi:type="string" translate="true">To</item>
+                        </item>
+                    </argument>
+                </filterDate>
+            </filterRange>
+            <filterRange name="update_time" class="Magento\Ui\Component\Filters\Type\DateRange">
+                <argument name="data" xsi:type="array">
+                    <item name="config" xsi:type="array">
+                        <item name="dataScope" xsi:type="string">update_time</item>
+                        <item name="label" xsi:type="string" translate="true">Modified</item>
+                    </item>
+                </argument>
+                <filterDate name="from">
+                    <argument name="data" xsi:type="array">
+                        <item name="config" xsi:type="array">
+                            <item name="dataScope" xsi:type="string">from</item>
+                            <item name="label" xsi:type="string" translate="true">From</item>
+                            <item name="placeholder" xsi:type="string" translate="true">From</item>
+                        </item>
+                    </argument>
+                </filterDate>
+                <filterDate name="to">
+                    <argument name="data" xsi:type="array">
+                        <item name="config" xsi:type="array">
+                            <item name="dataScope" xsi:type="string">to</item>
+                            <item name="label" xsi:type="string" translate="true">To</item>
+                            <item name="placeholder" xsi:type="string" translate="true">To</item>
+                        </item>
+                    </argument>
+                </filterDate>
+            </filterRange>
+        </filters>
+        <massaction name="listing_massaction">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="displayArea" xsi:type="string">bottom</item>
+                    <item name="actions" xsi:type="array">
+                        <item name="delete" xsi:type="array">
+                            <item name="confirm" xsi:type="string" translate="true">Are you sure you want to perform this action?</item>
+                            <item name="type" xsi:type="string">delete</item>
+                            <item name="label" xsi:type="string" translate="true">Delete</item>
+                            <item name="url" xsi:type="string">cms/block/massDelete</item>
+                        </item>
+                    </item>
+                    <item name="indexField" xsi:type="string">block_id</item>
+                </item>
+            </argument>
+        </massaction>
+        <paging name="listing_paging">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="displayArea" xsi:type="string">bottom</item>
+                    <item name="options" xsi:type="array">
+                        <item name="20" xsi:type="array">
+                            <item name="value" xsi:type="number">20</item>
+                            <item name="label" xsi:type="string" translate="true">20</item>
+                        </item>
+                        <item name="30" xsi:type="array">
+                            <item name="value" xsi:type="number">30</item>
+                            <item name="label" xsi:type="string" translate="true">30</item>
+                        </item>
+                        <item name="50" xsi:type="array">
+                            <item name="value" xsi:type="number">50</item>
+                            <item name="label" xsi:type="string" translate="true">50</item>
+                        </item>
+                        <item name="100" xsi:type="array">
+                            <item name="value" xsi:type="number">100</item>
+                            <item name="label" xsi:type="string" translate="true">100</item>
+                        </item>
+                        <item name="200" xsi:type="array">
+                            <item name="value" xsi:type="number">200</item>
+                            <item name="label" xsi:type="string" translate="true">200</item>
+                        </item>
+                    </item>
+                </item>
+            </argument>
+        </paging>
+    </container>    
+    <dataSource name="cms_block_listing_data_source">
+        <argument name="dataProvider" xsi:type="configurableObject">
+            <argument name="class" xsi:type="string">Magento\Cms\Model\Block\DataProvider</argument>
+            <argument name="primaryFieldName" xsi:type="string">block_id</argument>
+            <argument name="requestFieldName" xsi:type="string">id</argument>
+            <argument name="meta" xsi:type="array">
+                <item name="cms_page" xsi:type="array">
+                    <item name="config" xsi:type="array">
+                        <item name="label" xsi:type="string" translate="true">CMS Page</item>
+                    </item>
+                </item>
+            </argument>
+        </argument>
+        <argument name="data" xsi:type="array">
+            <item name="js_config" xsi:type="array">
+                <item name="component" xsi:type="string">Magento_Ui/js/grid/provider</item>
+            </item>
+            <item name="config" xsi:type="array">
+                <item name="update_url" xsi:type="string">mui/index/render</item>
+            </item>
+        </argument>
+    </dataSource>
+    <columns name="cms_block_columns">
+        <argument name="data" xsi:type="array">
+            <item name="config" xsi:type="array">
+                <item name="childDefaults" xsi:type="array">
+                    <item name="actionField" xsi:type="string">actions</item>
+                    <item name="clickAction" xsi:type="string">edit</item>
+                    <item name="appendTo" xsi:type="string">cms_block_listing.cms_block_listing.listing_top.columns_controls</item>
+                </item>
+            </item>
+        </argument>
+        <column name="ids" class="Magento\Ui\Component\MassAction\Columns\Column">
+            <argument name="data" xsi:type="array">
+                <item name="js_config" xsi:type="array">
+                    <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/multiselect</item>
+                </item>
+                <item name="config" xsi:type="array">
+                    <item name="indexField" xsi:type="string">block_id</item>
+                    <item name="appendTo" xsi:type="boolean">false</item>
+                </item>
+            </argument>
+        </column>
+        <column name="block_id">
+            <argument name="data" xsi:type="array">
+                <item name="js_config" xsi:type="array">
+                    <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/sortable</item>
+                </item>
+                <item name="config" xsi:type="array">
+                    <item name="dataType" xsi:type="string">text</item>
+                    <item name="sorting" xsi:type="string">asc</item>
+                    <item name="align" xsi:type="string">left</item>
+                    <item name="label" xsi:type="string" translate="true">ID</item>
+                </item>
+            </argument>
+        </column>
+        <column name="title">
+            <argument name="data" xsi:type="array">
+                <item name="js_config" xsi:type="array">
+                    <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/sortable</item>
+                </item>
+                <item name="config" xsi:type="array">
+                    <item name="dataType" xsi:type="string">text</item>
+                    <item name="align" xsi:type="string">left</item>
+                    <item name="label" xsi:type="string" translate="true">Title</item>
+                </item>
+            </argument>
+        </column>
+        <column name="identifier">
+            <argument name="data" xsi:type="array">
+                <item name="js_config" xsi:type="array">
+                    <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/sortable</item>
+                </item>
+                <item name="config" xsi:type="array">
+                    <item name="dataType" xsi:type="string">text</item>
+                    <item name="align" xsi:type="string">left</item>
+                    <item name="label" xsi:type="string" translate="true">Identifier</item>
+                </item>
+            </argument>
+        </column>
+        <column name="store_id" class="Magento\Store\Ui\Component\Listing\Column\Store">
+            <argument name="data" xsi:type="array">
+                <item name="js_config" xsi:type="array">
+                    <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/select</item>
+                </item>
+                <item name="config" xsi:type="array">
+                    <item name="sortable" xsi:type="boolean">false</item>
+                    <item name="dataType" xsi:type="string">text</item>
+                    <item name="align" xsi:type="string">left</item>
+                    <item name="label" xsi:type="string" translate="true">Store View</item>
+                </item>
+            </argument>
+        </column>
+        <column name="is_active">
+            <argument name="data" xsi:type="array">
+                <item name="js_config" xsi:type="array">
+                    <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/select</item>
+                </item>
+                <item name="options" xsi:type="array">
+                    <item name="disable" xsi:type="array">
+                        <item name="value" xsi:type="string">0</item>
+                        <item name="label" xsi:type="string" translate="true">Disabled</item>
+                    </item>
+                    <item name="enable" xsi:type="array">
+                        <item name="value" xsi:type="string">1</item>
+                        <item name="label" xsi:type="string" translate="true">Enabled</item>
+                    </item>
+                </item>
+                <item name="config" xsi:type="array">
+                    <item name="dataType" xsi:type="string">select</item>
+                    <item name="align" xsi:type="string">left</item>
+                    <item name="label" xsi:type="string" translate="true">Status</item>
+                </item>
+            </argument>
+        </column>
+        <column name="creation_time">
+            <argument name="data" xsi:type="array">
+                <item name="js_config" xsi:type="array">
+                    <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/date</item>
+                </item>
+                <item name="config" xsi:type="array">
+                    <item name="dataType" xsi:type="string">date</item>
+                    <item name="align" xsi:type="string">left</item>
+                    <item name="label" xsi:type="string" translate="true">Created</item>
+                </item>
+            </argument>
+        </column>
+        <column name="update_time">
+            <argument name="data" xsi:type="array">
+                <item name="js_config" xsi:type="array">
+                    <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/date</item>
+                </item>
+                <item name="config" xsi:type="array">
+                    <item name="dataType" xsi:type="string">date</item>
+                    <item name="align" xsi:type="string">left</item>
+                    <item name="label" xsi:type="string" translate="true">Modified</item>
+                </item>
+            </argument>
+        </column>
+        <column name="actions" class="Magento\Cms\Ui\Component\Listing\Column\BlockActions">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="dataType" xsi:type="string">actions</item>
+                    <item name="align" xsi:type="string">left</item>
+                    <item name="label" xsi:type="string" translate="true">Action</item>
+                    <item name="data_type" xsi:type="string">actions</item>
+                    <item name="filterable" xsi:type="boolean">false</item>
+                    <item name="sortable" xsi:type="boolean">false</item>
+                </item>
+            </argument>
+        </column>
+    </columns>
+</listing>
diff --git a/app/code/Magento/Cms/view/adminhtml/ui_component/cms_page_listing.xml b/app/code/Magento/Cms/view/adminhtml/ui_component/cms_page_listing.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3e67e0ef1235c458b18a948d2a369db408b1a698
--- /dev/null
+++ b/app/code/Magento/Cms/view/adminhtml/ui_component/cms_page_listing.xml
@@ -0,0 +1,399 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Ui/etc/ui_configuration.xsd">
+    <argument name="context" xsi:type="configurableObject">
+        <argument name="class" xsi:type="string">Magento\Framework\View\Element\UiComponent\Context</argument>
+        <argument name="namespace" xsi:type="string">cms_page_listing</argument>
+    </argument>
+    <argument name="data" xsi:type="array">
+        <item name="js_config" xsi:type="array">
+            <item name="config" xsi:type="array">
+                <item name="provider" xsi:type="string">cms_page_listing.cms_page_listing_data_source</item>
+            </item>
+            <item name="deps" xsi:type="string">cms_page_listing.cms_page_listing_data_source</item>
+        </item>
+        <item name="spinner" xsi:type="string">cms_page_columns</item>
+        <item name="buttons" xsi:type="array">
+            <item name="add" xsi:type="array">
+                <item name="name" xsi:type="string">add</item>
+                <item name="label" xsi:type="string" translate="true">Add New Page</item>
+                <item name="class" xsi:type="string">primary</item>
+                <item name="url" xsi:type="string">*/*/new</item>
+            </item>
+        </item>
+    </argument>
+    <dataSource name="cms_page_listing_data_source">
+        <argument name="dataProvider" xsi:type="configurableObject">
+            <argument name="class" xsi:type="string">Magento\Cms\Model\Page\DataProvider</argument>
+            <argument name="primaryFieldName" xsi:type="string">block_id</argument>
+            <argument name="requestFieldName" xsi:type="string">id</argument>
+            <argument name="meta" xsi:type="array">
+                <item name="cms_block" xsi:type="array">
+                    <item name="config" xsi:type="array">
+                        <item name="label" xsi:type="string" translate="true">CMS Block</item>
+                    </item>
+                </item>
+            </argument>
+        </argument>
+        <argument name="data" xsi:type="array">
+            <item name="js_config" xsi:type="array">
+                <item name="component" xsi:type="string">Magento_Ui/js/grid/provider</item>
+            </item>
+            <item name="config" xsi:type="array">
+                <item name="update_url" xsi:type="string">mui/index/render</item>
+            </item>
+        </argument>
+    </dataSource>
+    <container name="listing_top">
+        <argument name="data" xsi:type="array">
+            <item name="config" xsi:type="array">
+                <item name="template" xsi:type="string">ui/grid/toolbar</item>
+            </item>
+        </argument>
+        <container name="default_view">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="component" xsi:type="string">Magento_Ui/js/grid/controls/view</item>
+                    <item name="displayArea" xsi:type="string">dataGridActions</item>
+                </item>
+            </argument>
+        </container>
+        <container name="columns_controls">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="component" xsi:type="string">Magento_Ui/js/grid/controls/columns</item>
+                    <item name="displayArea" xsi:type="string">dataGridActions</item>
+                </item>
+            </argument>
+        </container>
+        <filters name="listing_filters">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="displayArea" xsi:type="string">dataGridFilters</item>
+                    <item name="dataScope" xsi:type="string">params.filters</item>
+                </item>
+            </argument>
+            <filterRange name="page_id">
+                <argument name="data" xsi:type="array">
+                    <item name="config" xsi:type="array">
+                        <item name="dataScope" xsi:type="string">page_id</item>
+                        <item name="label" xsi:type="string" translate="true">ID</item>
+                    </item>
+                </argument>
+                <filterInput name="from">
+                    <argument name="data" xsi:type="array">
+                        <item name="config" xsi:type="array">
+                            <item name="dataScope" xsi:type="string">from</item>
+                            <item name="label" xsi:type="string" translate="true">from</item>
+                            <item name="placeholder" xsi:type="string" translate="true">From</item>
+                        </item>
+                    </argument>
+                </filterInput>
+                <filterInput name="to">
+                    <argument name="data" xsi:type="array">
+                        <item name="config" xsi:type="array">
+                            <item name="dataScope" xsi:type="string">to</item>
+                            <item name="label" xsi:type="string" translate="true">to</item>
+                            <item name="placeholder" xsi:type="string" translate="true">To</item>
+                        </item>
+                    </argument>
+                </filterInput>
+            </filterRange>
+            <filterInput name="title">
+                <argument name="data" xsi:type="array">
+                    <item name="config" xsi:type="array">
+                        <item name="dataScope" xsi:type="string">title</item>
+                        <item name="label" xsi:type="string" translate="true">Title</item>
+                    </item>
+                </argument>
+            </filterInput>
+            <filterInput name="identifier">
+                <argument name="data" xsi:type="array">
+                    <item name="config" xsi:type="array">
+                        <item name="dataScope" xsi:type="string">identifier</item>
+                        <item name="label" xsi:type="string" translate="true">URL Key</item>
+                    </item>
+                </argument>
+            </filterInput>
+            <filterSelect name="page_layout">
+                <argument name="optionsProvider" xsi:type="configurableObject">
+                    <argument name="class" xsi:type="string">Magento\Cms\Model\Page\Source\PageLayout</argument>
+                </argument>
+                <argument name="data" xsi:type="array">
+                    <item name="config" xsi:type="array">
+                        <item name="dataScope" xsi:type="string">page_layout</item>
+                        <item name="label" xsi:type="string" translate="true">Layout</item>
+                        <item name="caption" xsi:type="string" translate="true">Select...</item>
+                    </item>
+                </argument>
+            </filterSelect>
+            <filterSelect name="store_id">
+                <argument name="optionsProvider" xsi:type="configurableObject">
+                    <argument name="class" xsi:type="string">Magento\Store\Ui\Component\Listing\Column\Store\Options</argument>
+                </argument>
+                <argument name="data" xsi:type="array">
+                    <item name="config" xsi:type="array">
+                        <item name="dataScope" xsi:type="string">store_id</item>
+                        <item name="caption" xsi:type="string" translate="true">Select...</item>
+                        <item name="label" xsi:type="string" translate="true">Store View</item>
+                    </item>
+                </argument>
+            </filterSelect>
+            <filterSelect name="is_active">
+                <argument name="data" xsi:type="array">
+                    <item name="config" xsi:type="array">
+                        <item name="dataScope" xsi:type="string">is_active</item>
+                        <item name="label" xsi:type="string" translate="true">Status</item>
+                        <item name="caption" xsi:type="string" translate="true">Select...</item>
+                        <item name="options" xsi:type="array">
+                            <item name="disable" xsi:type="array">
+                                <item name="value" xsi:type="string">0</item>
+                                <item name="label" xsi:type="string" translate="true">Disabled</item>
+                            </item>
+                            <item name="enable" xsi:type="array">
+                                <item name="value" xsi:type="string">1</item>
+                                <item name="label" xsi:type="string" translate="true">Enabled</item>
+                            </item>
+                        </item>
+                    </item>
+                </argument>
+            </filterSelect>
+            <filterRange name="creation_time" class="Magento\Ui\Component\Filters\Type\DateRange">
+                <argument name="data" xsi:type="array">
+                    <item name="config" xsi:type="array">
+                        <item name="dataScope" xsi:type="string">creation_time</item>
+                        <item name="label" xsi:type="string" translate="true">Created</item>
+                    </item>
+                </argument>
+                <filterDate name="from">
+                    <argument name="data" xsi:type="array">
+                        <item name="config" xsi:type="array">
+                            <item name="dataScope" xsi:type="string">from</item>
+                            <item name="label" xsi:type="string" translate="true">from</item>
+                            <item name="placeholder" xsi:type="string" translate="true">From</item>
+                        </item>
+                    </argument>
+                </filterDate>
+                <filterDate name="to">
+                    <argument name="data" xsi:type="array">
+                        <item name="config" xsi:type="array">
+                            <item name="dataScope" xsi:type="string">to</item>
+                            <item name="label" xsi:type="string" translate="true">to</item>
+                            <item name="placeholder" xsi:type="string" translate="true">To</item>
+                        </item>
+                    </argument>
+                </filterDate>
+            </filterRange>
+            <filterRange name="update_time" class="Magento\Ui\Component\Filters\Type\DateRange">
+                <argument name="data" xsi:type="array">
+                    <item name="config" xsi:type="array">
+                        <item name="dataScope" xsi:type="string">update_time</item>
+                        <item name="label" xsi:type="string" translate="true">Modified</item>
+                    </item>
+                </argument>
+                <filterDate name="from">
+                    <argument name="data" xsi:type="array">
+                        <item name="config" xsi:type="array">
+                            <item name="dataScope" xsi:type="string">from</item>
+                            <item name="label" xsi:type="string" translate="true">from</item>
+                            <item name="placeholder" xsi:type="string" translate="true">From</item>
+                        </item>
+                    </argument>
+                </filterDate>
+                <filterDate name="to">
+                    <argument name="data" xsi:type="array">
+                        <item name="config" xsi:type="array">
+                            <item name="dataScope" xsi:type="string">to</item>
+                            <item name="label" xsi:type="string" translate="true">to</item>
+                            <item name="placeholder" xsi:type="string" translate="true">To</item>
+                        </item>
+                    </argument>
+                </filterDate>
+            </filterRange>
+        </filters>
+        <massaction name="listing_massaction">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="displayArea" xsi:type="string">bottom</item>
+                    <item name="actions" xsi:type="array">
+                        <item name="delete" xsi:type="array">
+                            <item name="confirm" xsi:type="string" translate="true">Delete selected items?</item>
+                            <item name="type" xsi:type="string">delete</item>
+                            <item name="label" xsi:type="string" translate="true">Delete</item>
+                            <item name="url" xsi:type="string">cms/page/massDelete</item>
+                        </item>
+                    </item>
+                    <item name="indexField" xsi:type="string">page_id</item>
+                </item>
+            </argument>
+        </massaction>
+        <paging name="listing_paging">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="displayArea" xsi:type="string">bottom</item>
+                    <item name="options" xsi:type="array">
+                        <item name="20" xsi:type="array">
+                            <item name="value" xsi:type="number">20</item>
+                            <item name="label" xsi:type="string" translate="true">20</item>
+                        </item>
+                        <item name="30" xsi:type="array">
+                            <item name="value" xsi:type="number">30</item>
+                            <item name="label" xsi:type="string" translate="true">30</item>
+                        </item>
+                        <item name="50" xsi:type="array">
+                            <item name="value" xsi:type="number">50</item>
+                            <item name="label" xsi:type="string" translate="true">50</item>
+                        </item>
+                        <item name="100" xsi:type="array">
+                            <item name="value" xsi:type="number">100</item>
+                            <item name="label" xsi:type="string" translate="true">100</item>
+                        </item>
+                        <item name="200" xsi:type="array">
+                            <item name="value" xsi:type="number">200</item>
+                            <item name="label" xsi:type="string" translate="true">200</item>
+                        </item>
+                    </item>
+                </item>
+            </argument>
+        </paging>
+    </container>    
+    <columns name="cms_page_columns">
+        <argument name="data" xsi:type="array">
+            <item name="config" xsi:type="array">
+                <item name="childDefaults" xsi:type="array">
+                    <item name="actionField" xsi:type="string">actions</item>
+                    <item name="clickAction" xsi:type="string">edit</item>
+                    <item name="appendTo" xsi:type="string">cms_page_listing.cms_page_listing.listing_top.columns_controls</item>
+                </item>
+            </item>
+        </argument>
+        <column name="ids" class="Magento\Ui\Component\MassAction\Columns\Column">
+            <argument name="data" xsi:type="array">
+                <item name="js_config" xsi:type="array">
+                    <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/multiselect</item>
+                </item>
+                <item name="config" xsi:type="array">
+                    <item name="indexField" xsi:type="string">page_id</item>
+                    <item name="appendTo" xsi:type="string"></item>
+                </item>
+            </argument>
+        </column>
+        <column name="page_id">
+            <argument name="data" xsi:type="array">
+                <item name="js_config" xsi:type="array">
+                    <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/sortable</item>
+                </item>
+                <item name="config" xsi:type="array">
+                    <item name="dataType" xsi:type="string">text</item>
+                    <item name="sorting" xsi:type="string">asc</item>
+                    <item name="align" xsi:type="string">left</item>
+                    <item name="label" xsi:type="string" translate="true">ID</item>
+                </item>
+            </argument>
+        </column>
+        <column name="title">
+            <argument name="data" xsi:type="array">
+                <item name="js_config" xsi:type="array">
+                    <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/sortable</item>
+                </item>
+                <item name="config" xsi:type="array">
+                    <item name="dataType" xsi:type="string">text</item>
+                    <item name="align" xsi:type="string">left</item>
+                    <item name="label" xsi:type="string" translate="true">Title</item>
+                </item>
+            </argument>
+        </column>
+        <column name="identifier">
+            <argument name="data" xsi:type="array">
+                <item name="js_config" xsi:type="array">
+                    <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/sortable</item>
+                </item>
+                <item name="config" xsi:type="array">
+                    <item name="dataType" xsi:type="string">text</item>
+                    <item name="align" xsi:type="string">left</item>
+                    <item name="label" xsi:type="string" translate="true">URL Key</item>
+                </item>
+            </argument>
+        </column>
+        <column name="page_layout">
+            <argument name="data" xsi:type="array">
+                <item name="options" xsi:type="object">Magento\Cms\Model\Page\Source\PageLayout</item>
+                <item name="js_config" xsi:type="array">
+                    <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/select</item>
+                </item>
+                <item name="config" xsi:type="array">
+                    <item name="dataType" xsi:type="string">select</item>
+                    <item name="align" xsi:type="string">left</item>
+                    <item name="label" xsi:type="string" translate="true">Layout</item>
+                </item>
+            </argument>
+        </column>
+        <column name="store_id" class="Magento\Store\Ui\Component\Listing\Column\Store">
+            <argument name="data" xsi:type="array">
+                <item name="js_config" xsi:type="array">
+                    <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/sortable</item>
+                </item>
+                <item name="config" xsi:type="array">
+                    <item name="sortable" xsi:type="boolean">false</item>
+                    <item name="dataType" xsi:type="string">text</item>
+                    <item name="align" xsi:type="string">left</item>
+                    <item name="label" xsi:type="string" translate="true">Store View</item>
+                </item>
+            </argument>
+        </column>
+        <column name="is_active">
+            <argument name="data" xsi:type="array">
+                <item name="options" xsi:type="object">Magento\Cms\Model\Page\Source\IsActive</item>
+                <item name="js_config" xsi:type="array">
+                    <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/select</item>
+                </item>
+                <item name="config" xsi:type="array">
+                    <item name="dataType" xsi:type="string">select</item>
+                    <item name="align" xsi:type="string">left</item>
+                    <item name="label" xsi:type="string" translate="true">Status</item>
+                </item>
+            </argument>
+        </column>
+        <column name="creation_time">
+            <argument name="data" xsi:type="array">
+                <item name="js_config" xsi:type="array">
+                    <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/date</item>
+                </item>
+                <item name="config" xsi:type="array">
+                    <item name="dataType" xsi:type="string">date</item>
+                    <item name="align" xsi:type="string">left</item>
+                    <item name="label" xsi:type="string" translate="true">Created</item>
+                </item>
+            </argument>
+        </column>
+        <column name="update_time">
+            <argument name="data" xsi:type="array">
+                <item name="js_config" xsi:type="array">
+                    <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/date</item>
+                </item>
+                <item name="config" xsi:type="array">
+                    <item name="dataType" xsi:type="string">date</item>
+                    <item name="align" xsi:type="string">left</item>
+                    <item name="label" xsi:type="string" translate="true">Modified</item>
+                </item>
+            </argument>
+        </column>
+        <column name="actions" class="Magento\Cms\Ui\Component\Listing\Column\PageActions">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="dataType" xsi:type="string">actions</item>
+                    <item name="align" xsi:type="string">left</item>
+                    <item name="label" xsi:type="string" translate="true">Action</item>
+                    <item name="data_type" xsi:type="string">actions</item>
+                    <item name="filterable" xsi:type="boolean">false</item>
+                    <item name="sortable" xsi:type="boolean">false</item>
+                </item>
+            </argument>
+        </column>
+    </columns>
+</listing>
diff --git a/app/code/Magento/CmsUrlRewrite/composer.json b/app/code/Magento/CmsUrlRewrite/composer.json
index 06f0e19df1fb840dd3dde3e6028ab68dda347b3a..6723b56a38eefe51d91034c726c045e014d25550 100644
--- a/app/code/Magento/CmsUrlRewrite/composer.json
+++ b/app/code/Magento/CmsUrlRewrite/composer.json
@@ -3,14 +3,14 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-cms": "0.74.0-beta6",
-        "magento/module-url-rewrite": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-cms": "0.74.0-beta7",
+        "magento/module-url-rewrite": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Config/Model/Config/Backend/File.php b/app/code/Magento/Config/Model/Config/Backend/File.php
index e7a119f79af9f0bf78d8f459ff0d30875abd097b..a08ed7d4f23894640e6592728f9a2c6a8eb1432b 100644
--- a/app/code/Magento/Config/Model/Config/Backend/File.php
+++ b/app/code/Magento/Config/Model/Config/Backend/File.php
@@ -5,6 +5,7 @@
  */
 namespace Magento\Config\Model\Config\Backend;
 
+use Magento\Framework\App\Config\ScopeConfigInterface;
 use Magento\Framework\App\Filesystem\DirectoryList;
 use Magento\Framework\Filesystem;
 
@@ -196,7 +197,7 @@ class File extends \Magento\Framework\App\Config\Value
     protected function _prependScopeInfo($path)
     {
         $scopeInfo = $this->getScope();
-        if (\Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT != $this->getScope()) {
+        if (ScopeConfigInterface::SCOPE_TYPE_DEFAULT != $this->getScope()) {
             $scopeInfo .= '/' . $this->getScopeId();
         }
         return $scopeInfo . '/' . $path;
@@ -213,7 +214,7 @@ class File extends \Magento\Framework\App\Config\Value
     protected function _appendScopeInfo($path)
     {
         $path .= '/' . $this->getScope();
-        if (\Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT != $this->getScope()) {
+        if (ScopeConfigInterface::SCOPE_TYPE_DEFAULT != $this->getScope()) {
             $path .= '/' . $this->getScopeId();
         }
         return $path;
diff --git a/app/code/Magento/Config/Model/Config/Backend/Locale.php b/app/code/Magento/Config/Model/Config/Backend/Locale.php
index 0881afdebfc3839d52d0c27de0052ae6a8bd68b1..3d057fd6df864d23061ba4d1d762e265482eb595 100644
--- a/app/code/Magento/Config/Model/Config/Backend/Locale.php
+++ b/app/code/Magento/Config/Model/Config/Backend/Locale.php
@@ -9,6 +9,8 @@
  */
 namespace Magento\Config\Model\Config\Backend;
 
+use Magento\Framework\App\Config\ScopeConfigInterface;
+
 class Locale extends \Magento\Framework\App\Config\Value
 {
     /**
@@ -91,7 +93,7 @@ class Locale extends \Magento\Framework\App\Config\Value
                     }
 
                     switch ($data->getScope()) {
-                        case \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT:
+                        case ScopeConfigInterface::SCOPE_TYPE_DEFAULT:
                             $scopeName = __('Default scope');
                             break;
 
diff --git a/app/code/Magento/Config/Model/Config/ScopeDefiner.php b/app/code/Magento/Config/Model/Config/ScopeDefiner.php
index 893496d874009b9834fc2f1821057283ba01e323..f69e9dd96d2eb820a87a9d1f5905445df9c576df 100644
--- a/app/code/Magento/Config/Model/Config/ScopeDefiner.php
+++ b/app/code/Magento/Config/Model/Config/ScopeDefiner.php
@@ -5,6 +5,7 @@
  */
 namespace Magento\Config\Model\Config;
 
+use Magento\Framework\App\Config\ScopeConfigInterface;
 use Magento\Store\Model\ScopeInterface as StoreScopeInterface;
 
 /**
@@ -38,6 +39,6 @@ class ScopeDefiner
             'store'
         ) ? StoreScopeInterface::SCOPE_STORE : ($this->_request->getParam(
             'website'
-        ) ? StoreScopeInterface::SCOPE_WEBSITE : \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT);
+        ) ? StoreScopeInterface::SCOPE_WEBSITE : ScopeConfigInterface::SCOPE_TYPE_DEFAULT);
     }
 }
diff --git a/app/code/Magento/Config/Model/Config/Structure/AbstractElement.php b/app/code/Magento/Config/Model/Config/Structure/AbstractElement.php
index e10a1a1c3e725333743bea341d6170865f17d119..03ed66f29abec3ebd79735f648aefcd633dc44cc 100644
--- a/app/code/Magento/Config/Model/Config/Structure/AbstractElement.php
+++ b/app/code/Magento/Config/Model/Config/Structure/AbstractElement.php
@@ -5,6 +5,7 @@
  */
 namespace Magento\Config\Model\Config\Structure;
 
+use Magento\Framework\App\Config\ScopeConfigInterface;
 use Magento\Store\Model\StoreManagerInterface;
 
 abstract class AbstractElement implements ElementInterface
@@ -136,7 +137,7 @@ abstract class AbstractElement implements ElementInterface
         $showInScope = [
             \Magento\Store\Model\ScopeInterface::SCOPE_STORE => $this->_hasVisibilityValue('showInStore'),
             \Magento\Store\Model\ScopeInterface::SCOPE_WEBSITE => $this->_hasVisibilityValue('showInWebsite'),
-            \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT => $this->_hasVisibilityValue('showInDefault'),
+            ScopeConfigInterface::SCOPE_TYPE_DEFAULT => $this->_hasVisibilityValue('showInDefault'),
         ];
 
         if ($this->_storeManager->isSingleStoreMode()) {
diff --git a/app/code/Magento/Config/Test/Unit/Model/Config/ScopeDefinerTest.php b/app/code/Magento/Config/Test/Unit/Model/Config/ScopeDefinerTest.php
index 23069beec258fa8c6ab4e398c537a4874a9010b7..e0c64a35053ad44c88baa18861e84641a995d17d 100644
--- a/app/code/Magento/Config/Test/Unit/Model/Config/ScopeDefinerTest.php
+++ b/app/code/Magento/Config/Test/Unit/Model/Config/ScopeDefinerTest.php
@@ -5,6 +5,7 @@
  */
 namespace Magento\Config\Test\Unit\Model\Config;
 
+use Magento\Framework\App\Config\ScopeConfigInterface;
 use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
 
 class ScopeDefinerTest extends \PHPUnit_Framework_TestCase
@@ -31,7 +32,7 @@ class ScopeDefinerTest extends \PHPUnit_Framework_TestCase
 
     public function testGetScopeReturnsDefaultScopeIfNoScopeDataIsSpecified()
     {
-        $this->assertEquals(\Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT, $this->_model->getScope());
+        $this->assertEquals(ScopeConfigInterface::SCOPE_TYPE_DEFAULT, $this->_model->getScope());
     }
 
     public function testGetScopeReturnsStoreScopeIfStoreIsSpecified()
diff --git a/app/code/Magento/Config/Test/Unit/Model/Config/Structure/AbstractElementTest.php b/app/code/Magento/Config/Test/Unit/Model/Config/Structure/AbstractElementTest.php
index 03e9fd8d2266e5c9256c74a81716e59e4eb40ac0..778141ab2132096aa8d0e750f7175bebdcea935b 100644
--- a/app/code/Magento/Config/Test/Unit/Model/Config/Structure/AbstractElementTest.php
+++ b/app/code/Magento/Config/Test/Unit/Model/Config/Structure/AbstractElementTest.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\Config\Test\Unit\Model\Config\Structure;
 
+use Magento\Framework\App\Config\ScopeConfigInterface;
+
 class AbstractElementTest extends \PHPUnit_Framework_TestCase
 {
     /**
@@ -77,7 +79,7 @@ class AbstractElementTest extends \PHPUnit_Framework_TestCase
         $this->_storeManager->expects($this->once())->method('isSingleStoreMode')->will($this->returnValue(true));
         $this->_model->setData(
             ['showInDefault' => 1, 'showInStore' => 0, 'showInWebsite' => 0],
-            \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT
+            ScopeConfigInterface::SCOPE_TYPE_DEFAULT
         );
         $this->assertTrue($this->_model->isVisible());
     }
@@ -87,7 +89,7 @@ class AbstractElementTest extends \PHPUnit_Framework_TestCase
         $this->_storeManager->expects($this->once())->method('isSingleStoreMode')->will($this->returnValue(true));
         $this->_model->setData(
             ['hide_in_single_store_mode' => 1, 'showInDefault' => 1, 'showInStore' => 0, 'showInWebsite' => 0],
-            \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT
+            ScopeConfigInterface::SCOPE_TYPE_DEFAULT
         );
         $this->assertFalse($this->_model->isVisible());
     }
@@ -100,7 +102,7 @@ class AbstractElementTest extends \PHPUnit_Framework_TestCase
         $this->_storeManager->expects($this->once())->method('isSingleStoreMode')->will($this->returnValue(true));
         $this->_model->setData(
             ['showInDefault' => 0, 'showInStore' => 0, 'showInWebsite' => 0],
-            \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT
+            ScopeConfigInterface::SCOPE_TYPE_DEFAULT
         );
         $this->assertFalse($this->_model->isVisible());
     }
@@ -121,7 +123,7 @@ class AbstractElementTest extends \PHPUnit_Framework_TestCase
         return [
             [
                 ['showInDefault' => 1, 'showInStore' => 0, 'showInWebsite' => 0],
-                \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT,
+                ScopeConfigInterface::SCOPE_TYPE_DEFAULT,
             ],
             [
                 ['showInDefault' => 0, 'showInStore' => 1, 'showInWebsite' => 0],
@@ -150,7 +152,7 @@ class AbstractElementTest extends \PHPUnit_Framework_TestCase
         return [
             [
                 ['showInDefault' => 0, 'showInStore' => 1, 'showInWebsite' => 1],
-                \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT,
+                ScopeConfigInterface::SCOPE_TYPE_DEFAULT,
             ],
             [
                 ['showInDefault' => 1, 'showInStore' => 0, 'showInWebsite' => 1],
diff --git a/app/code/Magento/Config/composer.json b/app/code/Magento/Config/composer.json
index 04e2fbc1e741c134694fdd2579fc618a3bf132c4..339caeb7101710a9d1ac410ab6749ff8e3b8c5d3 100644
--- a/app/code/Magento/Config/composer.json
+++ b/app/code/Magento/Config/composer.json
@@ -3,17 +3,17 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/framework": "0.74.0-beta6",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-cron": "0.74.0-beta6",
-        "magento/module-email": "0.74.0-beta6",
-        "magento/module-directory": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-media-storage": "0.74.0-beta6",
+        "magento/framework": "0.74.0-beta7",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-cron": "0.74.0-beta7",
+        "magento/module-email": "0.74.0-beta7",
+        "magento/module-directory": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-media-storage": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/ConfigurableImportExport/composer.json b/app/code/Magento/ConfigurableImportExport/composer.json
index d504ebf2a76d16c9f183cd6419774e822571e6c3..3476dfec4a07b222c02e69cb4dd2909fcabafb35 100644
--- a/app/code/Magento/ConfigurableImportExport/composer.json
+++ b/app/code/Magento/ConfigurableImportExport/composer.json
@@ -3,16 +3,16 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/module-catalog-import-export": "0.74.0-beta6",
-        "magento/module-eav": "0.74.0-beta6",
-        "magento/module-import-export": "0.74.0-beta6",
-        "magento/module-configurable-product": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/module-catalog-import-export": "0.74.0-beta7",
+        "magento/module-eav": "0.74.0-beta7",
+        "magento/module-import-export": "0.74.0-beta7",
+        "magento/module-configurable-product": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/ConfigurableProduct/Api/Data/OptionInterface.php b/app/code/Magento/ConfigurableProduct/Api/Data/OptionInterface.php
index 82e73fe8686e268e1b3701c216fe3bb8a2d4ee95..1c60ed2762efbb9c8e1a4fc6bd62c511dc98f7f1 100644
--- a/app/code/Magento/ConfigurableProduct/Api/Data/OptionInterface.php
+++ b/app/code/Magento/ConfigurableProduct/Api/Data/OptionInterface.php
@@ -41,17 +41,6 @@ interface OptionInterface extends \Magento\Framework\Api\ExtensibleDataInterface
      */
     public function setLabel($label);
 
-    /**
-     * @return string|null
-     */
-    public function getType();
-
-    /**
-     * @param string $type
-     * @return $this
-     */
-    public function setType($type);
-
     /**
      * @return int|null
      */
diff --git a/app/code/Magento/ConfigurableProduct/Api/OptionTypesListInterface.php b/app/code/Magento/ConfigurableProduct/Api/OptionTypesListInterface.php
deleted file mode 100644
index 0978b9c705c4933d3590a69b9454432c4cf3f0d6..0000000000000000000000000000000000000000
--- a/app/code/Magento/ConfigurableProduct/Api/OptionTypesListInterface.php
+++ /dev/null
@@ -1,19 +0,0 @@
-<?php
-/**
- *
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\ConfigurableProduct\Api;
-
-interface OptionTypesListInterface
-{
-    /**
-     * Get all available option types for configurable product
-     *
-     * @return string[]
-     * @throws \Magento\Framework\Exception\NoSuchEntityException
-     * @throws \Magento\Framework\Exception\InputException
-     */
-    public function getItems();
-}
diff --git a/app/code/Magento/ConfigurableProduct/Model/OptionRepository.php b/app/code/Magento/ConfigurableProduct/Model/OptionRepository.php
index 3e18c09648b9f9a6087e3daef9d67c1f4279b0e1..68cdb235bdeb03bd1e15e7b2146d92586236aac0 100644
--- a/app/code/Magento/ConfigurableProduct/Model/OptionRepository.php
+++ b/app/code/Magento/ConfigurableProduct/Model/OptionRepository.php
@@ -87,26 +87,17 @@ class OptionRepository implements \Magento\ConfigurableProduct\Api\OptionReposit
     public function get($sku, $id)
     {
         $product = $this->getProduct($sku);
-        $collection = $this->getConfigurableAttributesCollection($product);
-        $collection->addFieldToFilter($collection->getResource()->getIdFieldName(), $id);
-        /** @var \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute $configurableAttribute */
-        $configurableAttribute = $collection->getFirstItem();
-        if (!$configurableAttribute->getId()) {
-            throw new NoSuchEntityException(__('Requested option doesn\'t exist: %1', $id));
-        }
-        $prices = $configurableAttribute->getPrices();
-        if (is_array($prices)) {
-            foreach ($prices as $price) {
-                /** @var \Magento\ConfigurableProduct\Api\Data\OptionValueInterface $value */
-                $value = $this->optionValueFactory->create();
-                $value->setValueIndex($price['value_index'])
-                    ->setPricingValue($price['pricing_value'])
-                    ->setIsPercent($price['is_percent']);
-                $values[] = $value;
+
+        $extensionAttribute = $product->getExtensionAttributes();
+        if ($extensionAttribute !== null) {
+            $options = $extensionAttribute->getConfigurableProductOptions();
+            foreach ($options as $option) {
+                if ($option->getId() == $id) {
+                    return $option;
+                }
             }
         }
-        $configurableAttribute->setValues($values);
-        return $configurableAttribute;
+        throw new NoSuchEntityException(__('Requested option doesn\'t exist: %1', $id));
     }
 
     /**
@@ -116,21 +107,10 @@ class OptionRepository implements \Magento\ConfigurableProduct\Api\OptionReposit
     {
         $options = [];
         $product = $this->getProduct($sku);
-        foreach ($this->getConfigurableAttributesCollection($product) as $option) {
-            $values = [];
-            $prices = $option->getPrices();
-            if (is_array($prices)) {
-                foreach ($prices as $price) {
-                    /** @var \Magento\ConfigurableProduct\Api\Data\OptionValueInterface $value */
-                    $value = $this->optionValueFactory->create();
-                    $value->setValueIndex($price['value_index'])
-                        ->setPricingValue($price['pricing_value'])
-                        ->setIsPercent($price['is_percent']);
-                    $values[] = $value;
-                }
-            }
-            $option->setValues($values);
-            $options[] = $option;
+
+        $extensionAttribute = $product->getExtensionAttributes();
+        if ($extensionAttribute !== null) {
+            $options = $extensionAttribute->getConfigurableProductOptions();
         }
         return $options;
     }
@@ -259,17 +239,6 @@ class OptionRepository implements \Magento\ConfigurableProduct\Api\OptionReposit
         return $product;
     }
 
-    /**
-     * Retrieve configurable attribute collection through product object
-     *
-     * @param \Magento\Catalog\Model\Product $product
-     * @return \Magento\ConfigurableProduct\Model\Resource\Product\Type\Configurable\Attribute\Collection
-     */
-    private function getConfigurableAttributesCollection(\Magento\Catalog\Model\Product $product)
-    {
-        return $this->configurableType->getConfigurableAttributeCollection($product);
-    }
-
     /**
      * Ensure that all necessary data is available for a new option creation.
      *
@@ -284,9 +253,6 @@ class OptionRepository implements \Magento\ConfigurableProduct\Api\OptionReposit
         if (!$option->getAttributeId()) {
             $inputException->addError(__('Option attribute ID is not specified.'));
         }
-        if (!$option->getType()) {
-            $inputException->addError(__('Option type is not specified.'));
-        }
         if (!$option->getLabel()) {
             $inputException->addError(__('Option label is not specified.'));
         }
diff --git a/app/code/Magento/ConfigurableProduct/Model/OptionTypesList.php b/app/code/Magento/ConfigurableProduct/Model/OptionTypesList.php
deleted file mode 100644
index 23b871b21248166e892ec10b45801cf1184dcf39..0000000000000000000000000000000000000000
--- a/app/code/Magento/ConfigurableProduct/Model/OptionTypesList.php
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-/**
- *
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-namespace Magento\ConfigurableProduct\Model;
-
-class OptionTypesList implements \Magento\ConfigurableProduct\Api\OptionTypesListInterface
-{
-    /**
-     * @var \Magento\Catalog\Model\System\Config\Source\Inputtype
-     */
-    protected $inputType;
-
-    /**
-     * @param \Magento\Catalog\Model\System\Config\Source\Inputtype $inputType
-     */
-    public function __construct(\Magento\Catalog\Model\System\Config\Source\Inputtype $inputType)
-    {
-        $this->inputType = $inputType;
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function getItems()
-    {
-        return array_map(
-            function ($inputType) {
-                return $inputType['value'];
-            },
-            $this->inputType->toOptionArray()
-        );
-    }
-}
diff --git a/app/code/Magento/ConfigurableProduct/Model/Plugin/AfterProductLoad.php b/app/code/Magento/ConfigurableProduct/Model/Plugin/AfterProductLoad.php
new file mode 100644
index 0000000000000000000000000000000000000000..6bf640f16735294afeb92a35513ebbbd58e7e5f0
--- /dev/null
+++ b/app/code/Magento/ConfigurableProduct/Model/Plugin/AfterProductLoad.php
@@ -0,0 +1,103 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\ConfigurableProduct\Model\Plugin;
+
+class AfterProductLoad
+{
+    /**
+     * @var \Magento\Catalog\Api\Data\ProductExtensionFactory
+     */
+    protected $productExtensionFactory;
+
+    /**
+     * @var \Magento\ConfigurableProduct\Api\Data\OptionValueInterfaceFactory
+     */
+    protected $optionValueFactory;
+
+    /**
+     * @param \Magento\Catalog\Api\Data\ProductExtensionFactory $productExtensionFactory
+     * @param \Magento\ConfigurableProduct\Api\Data\OptionValueInterfaceFactory $optionValueFactory
+     */
+    public function __construct(
+        \Magento\Catalog\Api\Data\ProductExtensionFactory $productExtensionFactory,
+        \Magento\ConfigurableProduct\Api\Data\OptionValueInterfaceFactory $optionValueFactory
+    ) {
+        $this->productExtensionFactory = $productExtensionFactory;
+        $this->optionValueFactory = $optionValueFactory;
+    }
+
+    /**
+     * @param \Magento\Catalog\Model\Product $subject
+     * @return \Magento\Catalog\Model\Product
+     */
+    public function afterLoad(\Magento\Catalog\Model\Product $product)
+    {
+        if ($product->getTypeId() != \Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE) {
+            return $product;
+        }
+
+        $productExtension = $product->getExtensionAttributes();
+        if ($productExtension === null) {
+            $productExtension = $this->productExtensionFactory->create();
+        }
+
+        $productExtension->setConfigurableProductOptions($this->getOptions($product));
+        $productExtension->setConfigurableProductLinks($this->getLinkedProducts($product));
+
+        $product->setExtensionAttributes($productExtension);
+
+        return $product;
+    }
+
+    /**
+     * @param \Magento\Catalog\Model\Product $product
+     * @return \Magento\ConfigurableProduct\Api\Data\OptionInterface[]
+     */
+    protected function getOptions(\Magento\Catalog\Model\Product $product)
+    {
+        $options = [];
+        /** @var \Magento\ConfigurableProduct\Model\Product\Type\Configurable $typeInstance */
+        $typeInstance = $product->getTypeInstance();
+        $attributeCollection = $typeInstance->getConfigurableAttributes($product);
+        /** @var \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute $option */
+        foreach ($attributeCollection as $option) {
+            $values = [];
+            $prices = $option->getPrices();
+            if (is_array($prices)) {
+                foreach ($prices as $price) {
+                    /** @var \Magento\ConfigurableProduct\Api\Data\OptionValueInterface $value */
+                    $value = $this->optionValueFactory->create();
+                    $value->setValueIndex($price['value_index'])
+                        ->setPricingValue($price['pricing_value'])
+                        ->setIsPercent($price['is_percent']);
+                    $values[] = $value;
+                }
+            }
+            $option->setValues($values);
+            $options[] = $option;
+        }
+        return $options;
+    }
+
+    /**
+     * @param \Magento\Catalog\Model\Product $product
+     * @return int[]
+     */
+    protected function getLinkedProducts(\Magento\Catalog\Model\Product $product)
+    {
+        /** @var \Magento\ConfigurableProduct\Model\Product\Type\Configurable $typeInstance */
+        $typeInstance = $product->getTypeInstance();
+        $childrenIds = $typeInstance->getChildrenIds($product->getId());
+
+        if (isset($childrenIds[0])) {
+            return $childrenIds[0];
+        } else {
+            return [];
+        }
+    }
+}
diff --git a/app/code/Magento/ConfigurableProduct/Model/Plugin/AroundProductRepositorySave.php b/app/code/Magento/ConfigurableProduct/Model/Plugin/AroundProductRepositorySave.php
new file mode 100644
index 0000000000000000000000000000000000000000..f0a12b809dcd9c484b63f379c94f1749ff5d6555
--- /dev/null
+++ b/app/code/Magento/ConfigurableProduct/Model/Plugin/AroundProductRepositorySave.php
@@ -0,0 +1,197 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\ConfigurableProduct\Model\Plugin;
+
+use Magento\Framework\Exception\InputException;
+
+class AroundProductRepositorySave
+{
+    /**
+     * @var \Magento\ConfigurableProduct\Api\OptionRepositoryInterface
+     */
+    protected $optionRepository;
+
+    /**
+     * @var \Magento\Catalog\Model\ProductFactory
+     */
+    protected $productFactory;
+
+    /**
+     * Type configurable factory
+     *
+     * @var \Magento\ConfigurableProduct\Model\Resource\Product\Type\ConfigurableFactory
+     */
+    protected $typeConfigurableFactory;
+
+    /*
+     * @var \Magento\ConfigurableProduct\Model\Resource\Product\Type\Configurable\Attribute\Price\Data
+     */
+    protected $priceData;
+
+    /**
+     * @param \Magento\ConfigurableProduct\Api\OptionRepositoryInterface $optionRepository
+     * @param \Magento\Catalog\Model\ProductFactory $productFactory
+     * @param \Magento\ConfigurableProduct\Model\Resource\Product\Type\Configurable\Attribute\Price\Data $priceData
+     * @param \Magento\ConfigurableProduct\Model\Resource\Product\Type\ConfigurableFactory $typeConfigurableFactory
+     */
+    public function __construct(
+        \Magento\ConfigurableProduct\Api\OptionRepositoryInterface $optionRepository,
+        \Magento\Catalog\Model\ProductFactory $productFactory,
+        \Magento\ConfigurableProduct\Model\Resource\Product\Type\Configurable\Attribute\Price\Data $priceData,
+        \Magento\ConfigurableProduct\Model\Resource\Product\Type\ConfigurableFactory $typeConfigurableFactory
+    ) {
+        $this->optionRepository = $optionRepository;
+        $this->productFactory = $productFactory;
+        $this->priceData = $priceData;
+        $this->typeConfigurableFactory = $typeConfigurableFactory;
+    }
+
+    /**
+     * @param \Magento\Catalog\Api\ProductRepositoryInterface $subject
+     * @param callable $proceed
+     * @param \Magento\Catalog\Api\Data\ProductInterface $product
+     * @param bool $saveOptions
+     * @return \Magento\Catalog\Api\Data\ProductInterface
+     * @throws \Magento\Framework\Exception\CouldNotSaveException
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function aroundSave(
+        \Magento\Catalog\Api\ProductRepositoryInterface $subject,
+        \Closure $proceed,
+        \Magento\Catalog\Api\Data\ProductInterface $product,
+        $saveOptions = false
+    ) {
+        /** @var \Magento\Catalog\Api\Data\ProductInterface $result */
+        $result = $proceed($product, $saveOptions);
+
+        if ($product->getTypeId() != \Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE) {
+            return $result;
+        }
+
+        $extendedAttributes = $product->getExtensionAttributes();
+        if ($extendedAttributes === null) {
+            return $result;
+        }
+        $configurableProductOptions = $extendedAttributes->getConfigurableProductOptions();
+        $configurableProductLinks = $extendedAttributes->getConfigurableProductLinks();
+        if ($configurableProductOptions === null && $configurableProductLinks === null) {
+            return $result;
+        }
+        if ($configurableProductOptions !== null) {
+            $this->saveConfigurableProductOptions($result, $configurableProductOptions);
+            $result->getTypeInstance()->resetConfigurableAttributes($result);
+        }
+        if ($configurableProductLinks !== null) {
+            $this->saveConfigurableProductLinks($result, $configurableProductLinks);
+        }
+        $this->priceData->setProductPrice($result->getId(), null);
+        return $subject->get($result->getSku(), false, $result->getStoreId(), true);
+    }
+
+    /**
+     * @param \Magento\Catalog\Api\Data\ProductInterface $product
+     * @param \Magento\ConfigurableProduct\Api\Data\OptionInterface[] $options
+     * @return $this
+     */
+    protected function saveConfigurableProductOptions(
+        \Magento\Catalog\Api\Data\ProductInterface $product,
+        array $options
+    ) {
+        $existingOptionIds = [];
+        if ($product->getExtensionAttributes() !== null) {
+            $extensionAttributes = $product->getExtensionAttributes();
+            if ($extensionAttributes->getConfigurableProductOptions() !== null) {
+                $existingOptions = $extensionAttributes->getConfigurableProductOptions();
+                foreach ($existingOptions as $option) {
+                    $existingOptionIds[] = $option->getId();
+                }
+            }
+        }
+
+        $updatedOptionIds = [];
+        foreach ($options as $option) {
+            if ($option->getId()) {
+                $updatedOptionIds[] = $option->getId();
+            }
+            $this->optionRepository->save($product->getSku(), $option);
+        }
+
+        $optionIdsToDelete = array_diff($existingOptionIds, $updatedOptionIds);
+        foreach ($optionIdsToDelete as $optionId) {
+            $this->optionRepository->deleteById($product->getSku(), $optionId);
+        }
+        return $this;
+    }
+
+    /**
+     * @param \Magento\Catalog\Api\Data\ProductInterface $product
+     * @param int[] $linkIds
+     * @return $this
+     */
+    protected function saveConfigurableProductLinks(
+        \Magento\Catalog\Api\Data\ProductInterface $product,
+        array $linkIds
+    ) {
+        $configurableProductTypeResource = $this->typeConfigurableFactory->create();
+        if (!empty($linkIds)) {
+            /** @var \Magento\ConfigurableProduct\Model\Product\Type\Configurable $configurableProductType */
+            $configurableProductType = $product->getTypeInstance();
+            $configurableAttributes = $configurableProductType->getConfigurableAttributes($product);
+            $attributeCodes = [];
+            foreach ($configurableAttributes as $configurableAttribute) {
+                /** @var \Magento\Catalog\Model\Resource\Eav\Attribute $productAttribute */
+                $productAttribute = $configurableAttribute->getProductAttribute();
+                $attributeCode = $productAttribute->getAttributeCode();
+                $attributeCodes[] = $attributeCode;
+            }
+            $this->validateProductLinks($attributeCodes, $linkIds);
+        }
+
+        $configurableProductTypeResource->saveProducts($product, $linkIds);
+        return $this;
+    }
+
+    /**
+     * @param array $attributeCodes
+     * @param array $linkIds
+     * @throws InputException
+     * @return $this
+     */
+    protected function validateProductLinks(array $attributeCodes, array $linkIds)
+    {
+        $valueMap = [];
+        if (empty($attributeCodes) && !empty($linkIds)) {
+            throw new InputException(
+                __('The configurable product does not have any variation attribute.')
+            );
+        }
+
+        foreach ($linkIds as $productId) {
+            $variation = $this->productFactory->create()->load($productId);
+            if (!$variation->getId()) {
+                throw new InputException(__('Product with id "%1" does not exist.', $productId));
+            }
+            $valueKey = '';
+            foreach ($attributeCodes as $attributeCode) {
+                if (!$variation->getData($attributeCode)) {
+                    throw new InputException(
+                        __('Product with id "%1" does not contain required attribute "%2".', $productId, $attributeCode)
+                    );
+                }
+                $valueKey = $valueKey . $attributeCode . ':' . $variation->getData($attributeCode) . ';';
+            }
+            if (isset($valueMap[$valueKey])) {
+                throw new InputException(
+                    __('Products "%1" and %2 have the same set of attribute values.', $productId, $valueMap[$valueKey])
+                );
+            }
+            $valueMap[$valueKey] = $productId;
+        }
+        return $this;
+    }
+}
diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php
index 5922c01bad8a3868bd867b8bd1522d3b2593ef30..c1fb0b41ef427e758954ee9728084e67eb9c5bed 100644
--- a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php
+++ b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php
@@ -377,6 +377,18 @@ class Configurable extends \Magento\Catalog\Model\Product\Type\AbstractType
         return $product->getData($this->_configurableAttributes);
     }
 
+    /**
+     * Reset the cached configurable attributes of a product
+     *
+     * @param \Magento\Catalog\Model\Product $product
+     * @return $this
+     */
+    public function resetConfigurableAttributes($product)
+    {
+        $product->unsetData($this->_configurableAttributes);
+        return $this;
+    }
+
     /**
      * Retrieve Configurable Attributes as array
      *
diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable/Attribute.php b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable/Attribute.php
index f02e39626d66a7571bea42e1c5b2b1af804caf9c..8cf22a9b6dc3b4127baa3b8e9c8e5a9c0ade4dce 100644
--- a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable/Attribute.php
+++ b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable/Attribute.php
@@ -24,7 +24,6 @@ class Attribute extends \Magento\Framework\Model\AbstractExtensibleModel impleme
      */
     const KEY_ATTRIBUTE_ID = 'attribute_id';
     const KEY_LABEL = 'label';
-    const KEY_TYPE = 'type';
     const KEY_POSITION = 'position';
     const KEY_IS_USE_DEFAULT = 'is_use_default';
     const KEY_VALUES = 'values';
@@ -119,15 +118,6 @@ class Attribute extends \Magento\Framework\Model\AbstractExtensibleModel impleme
         return $this->getData(self::KEY_ATTRIBUTE_ID);
     }
 
-    /**
-     * {@inheritdoc}
-     * @codeCoverageIgnore
-     */
-    public function getType()
-    {
-        return $this->getData(self::KEY_TYPE);
-    }
-
     /**
      * {@inheritdoc}
      * @codeCoverageIgnore
@@ -174,15 +164,6 @@ class Attribute extends \Magento\Framework\Model\AbstractExtensibleModel impleme
         return $this->setData(self::KEY_LABEL, $label);
     }
 
-    /**
-     * @param string $type
-     * @return $this
-     */
-    public function setType($type)
-    {
-        return $this->setData(self::KEY_TYPE, $type);
-    }
-
     /**
      * @param int $position
      * @return $this
diff --git a/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Type/Configurable.php b/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Type/Configurable.php
index e556661f45b1a802fd4f9024cbcbbd4889653cd0..671aa6b136ab40b63ad67c9f7229dcdb7a8ae1f9 100644
--- a/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Type/Configurable.php
+++ b/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Type/Configurable.php
@@ -180,10 +180,6 @@ class Configurable extends \Magento\Framework\Model\Resource\Db\AbstractDb
                 implode(
                     ' AND ',
                     [
-                        $this->_getReadAdapter()->quoteInto(
-                            'entity_value.entity_type_id = ?',
-                            $product->getEntityTypeId()
-                        ),
                         'entity_value.attribute_id = super_attribute.attribute_id',
                         'entity_value.store_id = 0',
                         'entity_value.entity_id = product_link.product_id'
diff --git a/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Type/Configurable/Attribute/Collection.php b/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Type/Configurable/Attribute/Collection.php
index 9d2ca8b5414c7920d4fb9235e6c6eaaaf4882368..f10a02db96f2297d1050a322c9bb92eaaa28cb91 100644
--- a/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Type/Configurable/Attribute/Collection.php
+++ b/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Type/Configurable/Attribute/Collection.php
@@ -263,7 +263,12 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
             $values = $this->getPriceValues();
 
             foreach ($values as $data) {
-                $this->getItemById($data['product_super_attribute_id'])->addPrice($data);
+                $item = $this->getItemById($data['product_super_attribute_id']);
+                //the price values is cached, it could have gotten out of sync with current items
+                //when a filter is added, in that case, we just ignore the data from the cache
+                if ($item) {
+                    $item->addPrice($data);
+                }
             }
         }
         return $this;
diff --git a/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Type/Configurable/Attribute/Price/Data.php b/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Type/Configurable/Attribute/Price/Data.php
index 248ed3ede9f343883132711c056d9966431c763e..3e5c714e425e4d50f4eec11eb6f1a09879c1ec87 100644
--- a/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Type/Configurable/Attribute/Price/Data.php
+++ b/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Type/Configurable/Attribute/Price/Data.php
@@ -24,10 +24,10 @@ class Data
 
     /**
      * @param int $productId
-     * @param array $priceData
+     * @param array|null $priceData
      * @return void
      */
-    public function setProductPrice($productId, array $priceData)
+    public function setProductPrice($productId, array $priceData = null)
     {
         $this->prices[$productId] = $priceData;
     }
diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/OptionRepositoryTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/OptionRepositoryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..34b66ecb320dc65bed96338f0435a8253b7aca5b
--- /dev/null
+++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/OptionRepositoryTest.php
@@ -0,0 +1,210 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\ConfigurableProduct\Test\Unit\Model;
+
+class OptionRepositoryTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\ConfigurableProduct\Model\OptionRepository
+     */
+    protected $model;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productRepositoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productMock;
+
+    protected function setUp()
+    {
+        $this->productRepositoryMock = $this->getMock('\Magento\Catalog\Api\ProductRepositoryInterface');
+        $this->productMock = $this->getMock('\Magento\Catalog\Api\Data\ProductInterface');
+        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $this->model = $objectManager->getObject(
+            '\Magento\ConfigurableProduct\Model\OptionRepository',
+            [
+                'productRepository' => $this->productRepositoryMock,
+            ]
+        );
+    }
+
+    public function testGet()
+    {
+        $productSku = "configurable";
+        $optionId = 3;
+
+        $this->productRepositoryMock->expects($this->once())
+            ->method('get')
+            ->with($productSku)
+            ->willReturn($this->productMock);
+        $this->productMock->expects($this->once())
+            ->method('getTypeId')
+            ->willReturn(\Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE);
+
+        $optionMock = $this->getMock('\Magento\ConfigurableProduct\Api\Data\OptionInterface');
+        $optionMock->expects($this->once())
+            ->method('getId')
+            ->willReturn($optionId);
+        $productExtensionMock = $this->getMockBuilder('\Magento\Catalog\Api\Data\ProductExtension')
+            ->setMethods(['getConfigurableProductOptions'])
+            ->getMock();
+        $productExtensionMock->expects($this->once())
+            ->method('getConfigurableProductOptions')
+            ->willReturn([$optionMock]);
+        $this->productMock->expects($this->once())
+            ->method('getExtensionAttributes')
+            ->willReturn($productExtensionMock);
+
+        $this->assertEquals($optionMock, $this->model->get($productSku, $optionId));
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\InputException
+     * @expectedExceptionMessage Only implemented for configurable product: configurable
+     */
+    public function testGetNotConfigurableProduct()
+    {
+        $productSku = "configurable";
+        $optionId = 3;
+
+        $this->productRepositoryMock->expects($this->once())
+            ->method('get')
+            ->with($productSku)
+            ->willReturn($this->productMock);
+        $this->productMock->expects($this->once())
+            ->method('getTypeId')
+            ->willReturn('simple');
+
+        $this->model->get($productSku, $optionId);
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\NoSuchEntityException
+     * @expectedExceptionMessage Requested option doesn't exist: 3
+     */
+    public function testGetEmptyExtensionAttribute()
+    {
+        $productSku = "configurable";
+        $optionId = 3;
+
+        $this->productRepositoryMock->expects($this->once())
+            ->method('get')
+            ->with($productSku)
+            ->willReturn($this->productMock);
+        $this->productMock->expects($this->once())
+            ->method('getTypeId')
+            ->willReturn(\Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE);
+
+        $this->productMock->expects($this->once())
+            ->method('getExtensionAttributes')
+            ->willReturn(null);
+
+        $this->model->get($productSku, $optionId);
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\NoSuchEntityException
+     * @expectedExceptionMessage Requested option doesn't exist: 3
+     */
+    public function testGetOptionIdNotFound()
+    {
+        $productSku = "configurable";
+        $optionId = 3;
+
+        $this->productRepositoryMock->expects($this->once())
+            ->method('get')
+            ->with($productSku)
+            ->willReturn($this->productMock);
+        $this->productMock->expects($this->once())
+            ->method('getTypeId')
+            ->willReturn(\Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE);
+
+        $optionMock = $this->getMock('\Magento\ConfigurableProduct\Api\Data\OptionInterface');
+        $optionMock->expects($this->once())
+            ->method('getId')
+            ->willReturn(6);
+        $productExtensionMock = $this->getMockBuilder('\Magento\Catalog\Api\Data\ProductExtension')
+            ->setMethods(['getConfigurableProductOptions'])
+            ->getMock();
+        $productExtensionMock->expects($this->once())
+            ->method('getConfigurableProductOptions')
+            ->willReturn([$optionMock]);
+        $this->productMock->expects($this->once())
+            ->method('getExtensionAttributes')
+            ->willReturn($productExtensionMock);
+
+        $this->model->get($productSku, $optionId);
+    }
+
+    public function testGetList()
+    {
+        $productSku = "configurable";
+
+        $this->productRepositoryMock->expects($this->once())
+            ->method('get')
+            ->with($productSku)
+            ->willReturn($this->productMock);
+        $this->productMock->expects($this->once())
+            ->method('getTypeId')
+            ->willReturn(\Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE);
+
+        $optionMock = $this->getMock('\Magento\ConfigurableProduct\Api\Data\OptionInterface');
+        $productExtensionMock = $this->getMockBuilder('\Magento\Catalog\Api\Data\ProductExtension')
+            ->setMethods(['getConfigurableProductOptions'])
+            ->getMock();
+        $productExtensionMock->expects($this->once())
+            ->method('getConfigurableProductOptions')
+            ->willReturn([$optionMock]);
+        $this->productMock->expects($this->once())
+            ->method('getExtensionAttributes')
+            ->willReturn($productExtensionMock);
+
+        $this->assertEquals([$optionMock], $this->model->getList($productSku));
+    }
+
+    public function testGetListNullExtensionAttribute()
+    {
+        $productSku = "configurable";
+
+        $this->productRepositoryMock->expects($this->once())
+            ->method('get')
+            ->with($productSku)
+            ->willReturn($this->productMock);
+        $this->productMock->expects($this->once())
+            ->method('getTypeId')
+            ->willReturn(\Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE);
+
+        $this->productMock->expects($this->once())
+            ->method('getExtensionAttributes')
+            ->willReturn(null);
+
+        $this->assertEquals([], $this->model->getList($productSku));
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\InputException
+     * @expectedExceptionMessage Only implemented for configurable product: configurable
+     */
+    public function testGetListNotConfigurableProduct()
+    {
+        $productSku = "configurable";
+
+        $this->productRepositoryMock->expects($this->once())
+            ->method('get')
+            ->with($productSku)
+            ->willReturn($this->productMock);
+        $this->productMock->expects($this->once())
+            ->method('getTypeId')
+            ->willReturn('simple');
+
+        $this->model->getList($productSku);
+    }
+}
diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/OptionTypesListTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/OptionTypesListTest.php
deleted file mode 100644
index 79867bb302e321ff1da0c4e887a1d2f754bb115b..0000000000000000000000000000000000000000
--- a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/OptionTypesListTest.php
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-namespace Magento\ConfigurableProduct\Test\Unit\Model;
-
-class OptionTypesListTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var OptionTypesList
-     */
-    protected $model;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $sourceMock;
-
-    protected function setUp()
-    {
-        $this->sourceMock = $this->getMock('\Magento\Catalog\Model\System\Config\Source\Inputtype', [], [], '', false);
-        $this->model = new \Magento\ConfigurableProduct\Model\OptionTypesList($this->sourceMock);
-    }
-
-    public function testGetItems()
-    {
-        $data = [
-            ['value' => 'multiselect', 'label' => __('Multiple Select')],
-            ['value' => 'select', 'label' => __('Dropdown')]
-        ];
-        $this->sourceMock->expects($this->once())->method('toOptionArray')->willReturn($data);
-        $expected = ['multiselect', 'select'];
-        $this->assertEquals($expected, $this->model->getItems());
-    }
-}
diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Plugin/AfterProductLoadTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Plugin/AfterProductLoadTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..af3e73f0b855eeddb16f965f7438d8a16cbcd601
--- /dev/null
+++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Plugin/AfterProductLoadTest.php
@@ -0,0 +1,239 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\ConfigurableProduct\Test\Unit\Model\Plugin;
+
+use Magento\ConfigurableProduct\Model\Plugin\AfterProductLoad;
+
+class AfterProductLoadTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var AfterProductLoad
+     */
+    protected $model;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $optionValueFactory;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productExtensionFactory;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|Magento\Catalog\Model\Product
+     */
+    protected $productMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $configurableProductTypeInstanceMock;
+
+    protected function setUp()
+    {
+        $this->optionValueFactory = $this->getMockBuilder(
+            '\Magento\ConfigurableProduct\Api\Data\OptionValueInterfaceFactory'
+        )->disableOriginalConstructor()->getMock();
+        $this->productMock = $this->getMockBuilder('Magento\Catalog\Model\Product')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->configurableProductTypeInstanceMock = $this->getMock(
+            '\Magento\ConfigurableProduct\Model\Product\Type\Configurable',
+            [],
+            [],
+            '',
+            false
+        );
+        $this->productMock->expects($this->any())
+            ->method('getTypeInstance')
+            ->willReturn($this->configurableProductTypeInstanceMock);
+        $this->productExtensionFactory = $this->getMockBuilder('\Magento\Catalog\Api\Data\ProductExtensionFactory')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->model = new \Magento\ConfigurableProduct\Model\Plugin\AfterProductLoad(
+            $this->productExtensionFactory,
+            $this->optionValueFactory
+        );
+    }
+
+    protected function setupOptions()
+    {
+        $optionValues = [
+            [
+                'value_index' => 5,
+                'pricing_value' => 10,
+                'is_percent' => 0,
+            ],
+            [
+                'value_index' => 6,
+                'pricing_value' => 5,
+                'is_percent' => 1,
+            ],
+        ];
+        $optionMock1 = $this->getMockBuilder('\Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute')
+            ->disableOriginalConstructor()
+            ->setMethods(['getPrices', 'setValues'])
+            ->getMock();
+        $optionMock1->expects($this->once())
+            ->method('getPrices')
+            ->willReturn($optionValues);
+
+        $optionValueMock1 = $this->getMockBuilder('\Magento\ConfigurableProduct\Api\Data\OptionValueInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $optionValueMock1->expects($this->once())
+            ->method('setValueIndex')
+            ->with($optionValues[0]['value_index'])
+            ->willReturnSelf();
+        $optionValueMock1->expects($this->once())
+            ->method('setPricingValue')
+            ->with($optionValues[0]['pricing_value'])
+            ->willReturnSelf();
+        $optionValueMock1->expects($this->once())
+            ->method('setIsPercent')
+            ->with($optionValues[0]['is_percent'])
+            ->willReturnSelf();
+
+        $optionValueMock2 = $this->getMockBuilder('\Magento\ConfigurableProduct\Api\Data\OptionValueInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $optionValueMock2->expects($this->once())
+            ->method('setValueIndex')
+            ->with($optionValues[1]['value_index'])
+            ->willReturnSelf();
+        $optionValueMock2->expects($this->once())
+            ->method('setPricingValue')
+            ->with($optionValues[1]['pricing_value'])
+            ->willReturnSelf();
+        $optionValueMock2->expects($this->once())
+            ->method('setIsPercent')
+            ->with($optionValues[1]['is_percent'])
+            ->willReturnSelf();
+
+        $this->optionValueFactory->expects($this->at(0))
+            ->method('create')
+            ->willReturn($optionValueMock1);
+        $optionMock1->expects($this->once())
+            ->method('setValues')
+            ->with([$optionValueMock1, $optionValueMock2]);
+
+        $optionMock2 = $this->getMockBuilder('\Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute')
+            ->disableOriginalConstructor()
+            ->setMethods(['getPrices', 'setValues'])
+            ->getMock();
+        $optionMock2->expects($this->once())
+            ->method('getPrices')
+            ->willReturn([]);
+        $optionMock2->expects($this->once())
+            ->method('setValues')
+            ->with([]);
+        $this->optionValueFactory->expects($this->at(1))
+            ->method('create')
+            ->willReturn($optionValueMock2);
+
+        $options = [$optionMock1, $optionMock2];
+
+        $this->configurableProductTypeInstanceMock->expects($this->once())
+            ->method('getConfigurableAttributes')
+            ->with($this->productMock)
+            ->willReturn($options);
+        return $options;
+    }
+
+    protected function setupLinks()
+    {
+        $id = 5;
+        $links = [6, 7];
+        $this->productMock->expects($this->once())
+            ->method('getId')
+            ->willReturn($id);
+        $this->configurableProductTypeInstanceMock->expects($this->once())
+            ->method('getChildrenIds')
+            ->with($id)
+            ->willReturn([$links]);
+        return $links;
+    }
+
+    public function testAfterLoad()
+    {
+        $options = $this->setupOptions();
+        $links = $this->setupLinks();
+
+        $this->productMock->expects($this->once())
+            ->method('getTypeId')
+            ->willReturn(\Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE);
+
+        $extensionAttributeMock = $this->getMockBuilder('\Magento\Catalog\Api\Data\ProductExtension')
+            ->setMethods(['setConfigurableProductOptions', 'setConfigurableProductLinks'])
+            ->getMock();
+
+        $extensionAttributeMock->expects($this->once())->method('setConfigurableProductOptions')
+            ->with($options)
+            ->willReturnSelf();
+        $extensionAttributeMock->expects($this->once())->method('setConfigurableProductLinks')
+            ->with($links)
+            ->willReturnSelf();
+
+        $this->productExtensionFactory->expects($this->once())
+            ->method('create')
+            ->willReturn($extensionAttributeMock);
+
+        $this->productMock->expects($this->once())
+            ->method('setExtensionAttributes')
+            ->with($extensionAttributeMock)
+            ->willReturnSelf();
+
+        $this->assertEquals($this->productMock, $this->model->afterLoad($this->productMock));
+    }
+
+    public function testAfterLoadNotConfigurableProduct()
+    {
+        $this->productMock->expects($this->once())
+            ->method('getTypeId')
+            ->willReturn('simple');
+
+        $this->productMock->expects($this->never())
+            ->method('getExtensionAttributes');
+        $this->productMock->expects($this->never())
+            ->method('setExtensionAttributes');
+        $this->assertEquals($this->productMock, $this->model->afterLoad($this->productMock));
+    }
+
+    public function testAfterLoadNoLinks()
+    {
+        $options = $this->setupOptions();
+
+        $this->productMock->expects($this->once())
+            ->method('getTypeId')
+            ->willReturn(\Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE);
+
+        $extensionAttributeMock = $this->getMockBuilder('\Magento\Catalog\Api\Data\ProductExtension')
+            ->setMethods(['setConfigurableProductOptions', 'setConfigurableProductLinks'])
+            ->getMock();
+
+        $extensionAttributeMock->expects($this->once())->method('setConfigurableProductOptions')
+            ->with($options)
+            ->willReturnSelf();
+        $extensionAttributeMock->expects($this->once())->method('setConfigurableProductLinks')
+            ->with([])
+            ->willReturnSelf();
+
+        $this->productExtensionFactory->expects($this->once())
+            ->method('create')
+            ->willReturn($extensionAttributeMock);
+
+        $this->productMock->expects($this->once())
+            ->method('setExtensionAttributes')
+            ->with($extensionAttributeMock)
+            ->willReturnSelf();
+
+        $this->assertEquals($this->productMock, $this->model->afterLoad($this->productMock));
+    }
+}
diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Plugin/AroundProductRepositorySaveTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Plugin/AroundProductRepositorySaveTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..6e750f9e13fcee390a5ae1a4fab496a507816f6c
--- /dev/null
+++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Plugin/AroundProductRepositorySaveTest.php
@@ -0,0 +1,553 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\ConfigurableProduct\Test\Unit\Model\Plugin;
+
+use Magento\ConfigurableProduct\Model\Plugin\AroundProductRepositorySave;
+
+class AroundProductRepositorySaveTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var AroundProductRepositorySave
+     */
+    protected $plugin;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productRepositoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productOptionRepositoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productFactoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productExtensionMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $configurableTypeFactoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $priceDataMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productInterfaceMock;
+
+    /**
+     * @var \Closure
+     */
+    protected $closureMock;
+
+    protected function setUp()
+    {
+        $this->productRepositoryMock = $this->getMock('Magento\Catalog\Api\ProductRepositoryInterface');
+        $this->productOptionRepositoryMock = $this->getMock(
+            'Magento\ConfigurableProduct\Api\OptionRepositoryInterface'
+        );
+        $this->configurableTypeFactoryMock = $this->getMockBuilder(
+            '\Magento\ConfigurableProduct\Model\Resource\Product\Type\ConfigurableFactory'
+        )->disableOriginalConstructor()->getMock();
+        $this->priceDataMock = $this->getMockBuilder(
+            '\Magento\ConfigurableProduct\Model\Resource\Product\Type\Configurable\Attribute\Price\Data'
+        )->disableOriginalConstructor()->getMock();
+        $this->productInterfaceMock = $this->getMock('\Magento\Catalog\Api\Data\ProductInterface');
+        $this->productMock = $this->getMock(
+            'Magento\Catalog\Model\Product',
+            ['getExtensionAttributes', 'getTypeId', 'getSku', 'getStoreId', 'getId', 'getTypeInstance'],
+            [],
+            '',
+            false
+        );
+        $this->closureMock = function () {
+            return $this->productMock;
+        };
+
+        $this->productFactoryMock = $this->getMockBuilder('\Magento\Catalog\Model\ProductFactory')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $this->plugin = $objectManager->getObject(
+            'Magento\ConfigurableProduct\Model\Plugin\AroundProductRepositorySave',
+            [
+                'optionRepository' => $this->productOptionRepositoryMock,
+                'productFactory' => $this->productFactoryMock,
+                'priceData' => $this->priceDataMock,
+                'typeConfigurableFactory' => $this->configurableTypeFactoryMock
+            ]
+        );
+
+        $this->productExtensionMock = $this->getMock(
+            'Magento\Catalog\Api\Data\ProductExtension',
+            [
+                'getConfigurableProductOptions',
+                'getConfigurableProductLinks',
+                'setConfigurableProductOptions',
+                'setConfigurableProductLinks',
+            ],
+            [],
+            '',
+            false
+        );
+    }
+
+    public function testAroundSaveWhenProductIsSimple()
+    {
+        $this->productMock->expects($this->once())->method('getTypeId')->willReturn('simple');
+        $this->productMock->expects($this->never())->method('getExtensionAttributes');
+
+        $this->assertEquals(
+            $this->productMock,
+            $this->plugin->aroundSave($this->productRepositoryMock, $this->closureMock, $this->productMock)
+        );
+    }
+
+    public function testAroundSaveWithoutOptions()
+    {
+        $this->productInterfaceMock->expects($this->once())->method('getTypeId')
+            ->willReturn(\Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE);
+        $this->productInterfaceMock->expects($this->once())
+            ->method('getExtensionAttributes')
+            ->willReturn($this->productExtensionMock);
+        $this->productExtensionMock->expects($this->once())
+            ->method('getConfigurableProductOptions')
+            ->willReturn(null);
+        $this->productExtensionMock->expects($this->once())
+            ->method('getConfigurableProductLinks')
+            ->willReturn(null);
+
+        $this->priceDataMock->expects($this->never())
+            ->method('setProductPrice');
+
+        $this->assertEquals(
+            $this->productMock,
+            $this->plugin->aroundSave($this->productRepositoryMock, $this->closureMock, $this->productInterfaceMock)
+        );
+    }
+
+    protected function setupProducts($productIds, $attributeCode, $additionalProductId = null)
+    {
+        $count = 0;
+        $products = [];
+        foreach ($productIds as $productId) {
+            $productMock = $this->getMockBuilder('\Magento\Catalog\Model\Product')
+                ->disableOriginalConstructor()
+                ->getMock();
+            $productMock->expects($this->once())
+                ->method('load')
+                ->with($productId)
+                ->willReturnSelf();
+            $productMock->expects($this->once())
+                ->method('getId')
+                ->willReturn($productId);
+            $productMock->expects($this->any())
+                ->method('getData')
+                ->with($attributeCode)
+                ->willReturn($productId);
+            $this->productFactoryMock->expects($this->at($count))
+                ->method('create')
+                ->willReturn($productMock);
+            $products[] = $productMock;
+            $count++;
+        }
+
+        if ($additionalProductId) {
+            $nonExistingProductMock = $this->getMockBuilder('\Magento\Catalog\Model\Product')
+                ->disableOriginalConstructor()
+                ->getMock();
+            $nonExistingProductMock->expects($this->once())
+                ->method('load')
+                ->with($additionalProductId)
+                ->willReturnSelf();
+            $this->productFactoryMock->expects($this->at($count))
+                ->method('create')
+                ->willReturn($nonExistingProductMock);
+            $products[] = $nonExistingProductMock;
+        }
+        return $products;
+    }
+
+    protected function setupConfigurableProductAttributes($attributeCodes)
+    {
+        $configurableProductTypeMock = $this->getMockBuilder(
+            '\Magento\ConfigurableProduct\Model\Product\Type\Configurable'
+        )->disableOriginalConstructor()->getMock();
+
+        $this->productMock->expects($this->once())
+            ->method('getTypeInstance')
+            ->willReturn($configurableProductTypeMock);
+
+        $configurableAttributes = [];
+        foreach ($attributeCodes as $attributeCode) {
+            $configurableAttribute = $this->getMockBuilder(
+                '\Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute'
+            )->setMethods(['getProductAttribute'])
+                ->disableOriginalConstructor()
+                ->getMock();
+            $productAttributeMock = $this->getMockBuilder('\Magento\Catalog\Model\Resource\Eav\Attribute')
+                ->disableOriginalConstructor()
+                ->getMock();
+            $productAttributeMock->expects($this->once())
+                ->method('getAttributeCode')
+                ->willReturn($attributeCode);
+            $configurableAttribute->expects($this->once())
+                ->method('getProductAttribute')
+                ->willReturn($productAttributeMock);
+            $configurableAttributes[] = $configurableAttribute;
+        }
+
+        $configurableProductTypeMock->expects($this->once())
+            ->method('getConfigurableAttributes')
+            ->with($this->productMock)
+            ->willReturn($configurableAttributes);
+
+        return $this;
+    }
+
+    public function testAroundSaveWithLinks()
+    {
+        $links = [4, 5];
+        $configurableAttributeCode = 'color';
+        $this->productMock->expects($this->once())->method('getTypeId')
+            ->willReturn(\Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE);
+        $this->productMock->expects($this->once())
+            ->method('getExtensionAttributes')
+            ->willReturn($this->productExtensionMock);
+        $this->productExtensionMock->expects($this->once())
+            ->method('getConfigurableProductOptions')
+            ->willReturn(null);
+        $this->productExtensionMock->expects($this->once())
+            ->method('getConfigurableProductLinks')
+            ->willReturn($links);
+
+        $this->setupConfigurableProductAttributes([$configurableAttributeCode]);
+        $this->setupProducts($links, $configurableAttributeCode);
+
+        $configurableTypeMock = $this->getMockBuilder(
+            '\Magento\ConfigurableProduct\Model\Resource\Product\Type\Configurable'
+        )->disableOriginalConstructor()->getMock();
+        $this->configurableTypeFactoryMock->expects($this->once())
+            ->method('create')
+            ->willReturn($configurableTypeMock);
+        $configurableTypeMock->expects($this->once())
+            ->method('saveProducts')
+            ->with($this->productMock, $links);
+
+        $productId = 3;
+        $this->productMock->expects($this->any())
+            ->method('getId')
+            ->willReturn($productId);
+        $this->priceDataMock->expects($this->once())
+            ->method('setProductPrice')
+            ->with($productId, null);
+
+        $productSku = 'configurable-sku';
+        $this->productMock->expects($this->any())
+            ->method('getSku')
+            ->willReturn($productSku);
+        $newProductMock = $this->setupReload($productSku);
+
+        $this->assertEquals(
+            $newProductMock,
+            $this->plugin->aroundSave($this->productRepositoryMock, $this->closureMock, $this->productMock)
+        );
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\InputException
+     * @expectedExceptionMessage Product with id "6" does not exist.
+     */
+    public function testAroundSaveWithNonExistingLinks()
+    {
+        $links = [4, 5];
+        $nonExistingId = 6;
+        $configurableAttributeCode = 'color';
+
+        $this->setupConfigurableProductAttributes([$configurableAttributeCode]);
+        $productMocks = $this->setupProducts($links, $configurableAttributeCode, $nonExistingId);
+        $nonExistingProductMock = $productMocks[2];
+        $nonExistingProductMock->expects($this->once())
+            ->method('getId')
+            ->willReturn(null);
+        $links[] = $nonExistingId;
+
+        $this->productMock->expects($this->once())->method('getTypeId')
+            ->willReturn(\Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE);
+        $this->productMock->expects($this->once())
+            ->method('getExtensionAttributes')
+            ->willReturn($this->productExtensionMock);
+        $this->productExtensionMock->expects($this->once())
+            ->method('getConfigurableProductOptions')
+            ->willReturn(null);
+        $this->productExtensionMock->expects($this->once())
+            ->method('getConfigurableProductLinks')
+            ->willReturn($links);
+
+        $configurableTypeMock = $this->getMockBuilder(
+            '\Magento\ConfigurableProduct\Model\Resource\Product\Type\Configurable'
+        )->disableOriginalConstructor()->getMock();
+        $this->configurableTypeFactoryMock->expects($this->once())
+            ->method('create')
+            ->willReturn($configurableTypeMock);
+        $configurableTypeMock->expects($this->never())
+            ->method('saveProducts')
+            ->with($this->productMock, $links);
+
+        $this->plugin->aroundSave($this->productRepositoryMock, $this->closureMock, $this->productMock);
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\InputException
+     * @expectedExceptionMessage Product with id "6" does not contain required attribute "color".
+     */
+    public function testAroundSaveWithLinksWithMissingAttribute()
+    {
+        $links = [4, 5];
+        $simpleProductId = 6;
+        $configurableAttributeCode = 'color';
+
+        $this->setupConfigurableProductAttributes([$configurableAttributeCode]);
+        $productMocks = $this->setupProducts($links, $configurableAttributeCode, $simpleProductId);
+        $simpleProductMock = $productMocks[2];
+        $simpleProductMock->expects($this->once())
+            ->method('getId')
+            ->willReturn($simpleProductId);
+        $simpleProductMock->expects($this->any())
+            ->method('getData')
+            ->with($configurableAttributeCode)
+            ->willReturn(null);
+
+        $links[] = $simpleProductId;
+
+        $this->productMock->expects($this->once())->method('getTypeId')
+            ->willReturn(\Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE);
+        $this->productMock->expects($this->once())
+            ->method('getExtensionAttributes')
+            ->willReturn($this->productExtensionMock);
+        $this->productExtensionMock->expects($this->once())
+            ->method('getConfigurableProductOptions')
+            ->willReturn(null);
+        $this->productExtensionMock->expects($this->once())
+            ->method('getConfigurableProductLinks')
+            ->willReturn($links);
+
+        $configurableTypeMock = $this->getMockBuilder(
+            '\Magento\ConfigurableProduct\Model\Resource\Product\Type\Configurable'
+        )->disableOriginalConstructor()->getMock();
+        $this->configurableTypeFactoryMock->expects($this->once())
+            ->method('create')
+            ->willReturn($configurableTypeMock);
+        $configurableTypeMock->expects($this->never())
+            ->method('saveProducts')
+            ->with($this->productMock, $links);
+
+        $this->plugin->aroundSave($this->productRepositoryMock, $this->closureMock, $this->productMock);
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\InputException
+     * @expectedExceptionMessage Products "6" and 4 have the same set of attribute values.
+     */
+    public function testAroundSaveWithLinksWithDuplicateAttributes()
+    {
+        $links = [4, 5];
+        $simpleProductId = 6;
+        $configurableAttributeCode = 'color';
+
+        $this->setupConfigurableProductAttributes([$configurableAttributeCode]);
+        $productMocks = $this->setupProducts($links, $configurableAttributeCode, $simpleProductId);
+        $simpleProductMock = $productMocks[2];
+        $simpleProductMock->expects($this->once())
+            ->method('getId')
+            ->willReturn($simpleProductId);
+        $simpleProductMock->expects($this->any())
+            ->method('getData')
+            ->with($configurableAttributeCode)
+            ->willReturn(4);
+
+        $links[] = $simpleProductId;
+
+        $this->productMock->expects($this->once())->method('getTypeId')
+            ->willReturn(\Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE);
+        $this->productMock->expects($this->once())
+            ->method('getExtensionAttributes')
+            ->willReturn($this->productExtensionMock);
+        $this->productExtensionMock->expects($this->once())
+            ->method('getConfigurableProductOptions')
+            ->willReturn(null);
+        $this->productExtensionMock->expects($this->once())
+            ->method('getConfigurableProductLinks')
+            ->willReturn($links);
+
+        $configurableTypeMock = $this->getMockBuilder(
+            '\Magento\ConfigurableProduct\Model\Resource\Product\Type\Configurable'
+        )->disableOriginalConstructor()->getMock();
+        $this->configurableTypeFactoryMock->expects($this->once())
+            ->method('create')
+            ->willReturn($configurableTypeMock);
+        $configurableTypeMock->expects($this->never())
+            ->method('saveProducts')
+            ->with($this->productMock, $links);
+
+        $this->plugin->aroundSave($this->productRepositoryMock, $this->closureMock, $this->productMock);
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\InputException
+     * @expectedExceptionMessage The configurable product does not have any variation attribute.
+     */
+    public function testAroundSaveWithLinksWithoutVariationAttributes()
+    {
+        $links = [4, 5];
+
+        $this->setupConfigurableProductAttributes([]);
+
+        $this->productMock->expects($this->once())->method('getTypeId')
+            ->willReturn(\Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE);
+        $this->productMock->expects($this->once())
+            ->method('getExtensionAttributes')
+            ->willReturn($this->productExtensionMock);
+        $this->productExtensionMock->expects($this->once())
+            ->method('getConfigurableProductOptions')
+            ->willReturn(null);
+        $this->productExtensionMock->expects($this->once())
+            ->method('getConfigurableProductLinks')
+            ->willReturn($links);
+
+        $this->plugin->aroundSave($this->productRepositoryMock, $this->closureMock, $this->productMock);
+    }
+
+    public function testAroundSaveWithOptions()
+    {
+        $productSku = "configurable_sku";
+        $this->productInterfaceMock->expects($this->once())->method('getTypeId')
+            ->willReturn(\Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE);
+        //two options with id 5 and 6
+        $options = $this->setupOptions([5, 6]);
+        //two existing options with id 4 and 5
+        $this->setupExistingOptions([4, 5]);
+
+        $this->productMock->expects($this->any())->method('getSku')
+            ->will($this->returnValue($productSku));
+
+        $this->productOptionRepositoryMock->expects($this->at(0))
+            ->method('save')
+            ->with($productSku, $options[0]);
+        $this->productOptionRepositoryMock->expects($this->at(1))
+            ->method('save')
+            ->with($productSku, $options[1]);
+        $this->productOptionRepositoryMock->expects($this->at(2))
+            ->method('deleteById')
+            ->with($productSku, 4);
+
+        $configurableProductTypeMock = $this->getMockBuilder(
+            '\Magento\ConfigurableProduct\Model\Product\Type\Configurable'
+        )->disableOriginalConstructor()->getMock();
+        $configurableProductTypeMock->expects($this->once())
+            ->method('resetConfigurableAttributes')
+            ->with($this->productMock)
+            ->willReturnSelf();
+        $this->productMock->expects($this->any())
+            ->method('getTypeInstance')
+            ->willReturn($configurableProductTypeMock);
+
+        $productId = 3;
+        $this->productMock->expects($this->once())
+            ->method('getId')
+            ->willReturn($productId);
+        $this->priceDataMock->expects($this->once())
+            ->method('setProductPrice')
+            ->with($productId, null);
+
+        $newProductMock = $this->setupReload($productSku);
+
+        $this->assertEquals(
+            $newProductMock,
+            $this->plugin->aroundSave($this->productRepositoryMock, $this->closureMock, $this->productInterfaceMock)
+        );
+    }
+
+    protected function setupReload($productSku)
+    {
+        $newProductMock = $this->getMockBuilder('Magento\Catalog\Api\Data\ProductInterface')
+            ->disableOriginalConstructor()->getMock();
+        $this->productRepositoryMock->expects($this->once())
+            ->method('get')
+            ->with($productSku, false, null, true)
+            ->willReturn($newProductMock);
+        return $newProductMock;
+    }
+
+    protected function setupExistingOptions(array $existingOptionIds)
+    {
+        $options = [];
+        foreach ($existingOptionIds as $existingOptionId) {
+            $optionMock = $this->getMock('\Magento\ConfigurableProduct\Api\Data\OptionInterface');
+            $optionMock->expects($this->any())
+                ->method('getId')
+                ->willReturn($existingOptionId);
+            $options[] = $optionMock;
+        }
+
+        $productExtensionMock = $this->getMockBuilder('Magento\Catalog\Api\Data\ProductExtension')
+            ->disableOriginalConstructor()
+            ->setMethods(['getConfigurableProductOptions'])
+            ->getMock();
+        $productExtensionMock->expects($this->any())
+            ->method('getConfigurableProductOptions')
+            ->willReturn($options);
+
+        $this->productMock->expects($this->any())
+            ->method('getExtensionAttributes')
+            ->willReturn($productExtensionMock);
+    }
+
+    protected function setupOptions(array $optionIds)
+    {
+        $options = [];
+        foreach ($optionIds as $optionId) {
+            $optionMock = $this->getMock('\Magento\ConfigurableProduct\Api\Data\OptionInterface');
+            $optionMock->expects($this->any())
+                ->method('getId')
+                ->willReturn($optionId);
+            $options[] = $optionMock;
+        }
+
+        $productExtensionMock = $this->getMockBuilder('Magento\Catalog\Api\Data\ProductExtension')
+            ->disableOriginalConstructor()
+            ->setMethods(['getConfigurableProductOptions', 'getConfigurableProductLinks'])
+            ->getMock();
+        $productExtensionMock->expects($this->any())
+            ->method('getConfigurableProductOptions')
+            ->willReturn($options);
+        $productExtensionMock->expects($this->any())
+            ->method('getConfigurableProductLinks')
+            ->willReturn(null);
+
+        $this->productInterfaceMock->expects($this->once())
+            ->method('getExtensionAttributes')
+            ->willReturn($productExtensionMock);
+        return $options;
+    }
+}
diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Type/ConfigurableTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Type/ConfigurableTest.php
index d0c5ae32ab1dc80a675f55233119de9eedcdc708..4ca090adef44b5e3786bd066067c7c6aaa03ac53 100644
--- a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Type/ConfigurableTest.php
+++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Type/ConfigurableTest.php
@@ -408,6 +408,19 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase
         ];
     }
 
+    public function testResetConfigurableAttributes()
+    {
+        $product = $this->getMockBuilder('\Magento\Catalog\Model\Product')
+            ->setMethods(['unsetData', '__wakeup', '__sleep'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $product->expects($this->any())->method('unsetData')
+            ->with('_cache_instance_configurable_attributes')
+            ->will($this->returnSelf());
+
+        $this->assertEquals($this->_model, $this->_model->resetConfigurableAttributes($product));
+    }
+
     public function testHasOptions()
     {
         $productMock = $this->getMockBuilder('\Magento\Catalog\Model\Product')
@@ -584,10 +597,6 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase
             ->setMethods(['getId', 'getAttributeCode'])
             ->disableOriginalConstructor()
             ->getMock();
-        $productResource = $this->getMockBuilder('\Magento\Catalog\Model\Resource\Product')
-            ->setMethods(['__wakeup', 'loadAllAttributes', 'getSortedAttributes'])
-            ->disableOriginalConstructor()
-            ->getMock();
         $productCollection = $this->getMockBuilder(
             'Magento\ConfigurableProduct\Model\Resource\Product\Type\Configurable\Product\Collection'
         )
@@ -616,14 +625,12 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase
             ->method('getData')
             ->with('_cache_instance_store_filter')
             ->willReturn('some_filter');
-        $productMock->expects($this->once())->method('hasData')->willReturn(true);
-        $productMock->expects($this->at(3))->method('getData')->willReturn([$usedProductMock]);
-        $productMock->expects($this->once())->method('getResource')->willReturn($productResource);
-        $productMock->expects($this->once())->method('getAttributeSetId')->willReturn(5);
-        $productResource->expects($this->once())->method('loadAllAttributes')->with($productMock)->willReturnSelf();
-        $productResource->expects($this->once())
-            ->method('getSortedAttributes')
-            ->with(5)
+        $productMock->expects($this->any())->method('hasData')->willReturn(true);
+        $productMock->expects($this->at(3))->method('getData')
+            ->with('_cache_instance_products')
+            ->willReturn([$usedProductMock]);
+        $productMock->expects($this->at(5))->method('getData')
+            ->with('_cache_instance_product_set_attributes')
             ->willReturn([$eavAttributeMock]);
         $eavAttributeMock->expects($this->once())->method('getId')->willReturn(1);
         $eavAttributeMock->expects($this->once())->method('getAttributeCode')->willReturn('attr_code');
diff --git a/app/code/Magento/ConfigurableProduct/composer.json b/app/code/Magento/ConfigurableProduct/composer.json
index 507ee995f908bde44cc3f29647133573e35de89c..e39bfede226336143aab79ade959eb6ccfb71b39 100644
--- a/app/code/Magento/ConfigurableProduct/composer.json
+++ b/app/code/Magento/ConfigurableProduct/composer.json
@@ -3,26 +3,26 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/module-catalog-inventory": "0.74.0-beta6",
-        "magento/module-sales": "0.74.0-beta6",
-        "magento/module-checkout": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-eav": "0.74.0-beta6",
-        "magento/module-customer": "0.74.0-beta6",
-        "magento/module-catalog-rule": "0.74.0-beta6",
-        "magento/module-directory": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
-        "magento/module-media-storage": "0.74.0-beta6",
-        "magento/module-quote": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/module-catalog-inventory": "0.74.0-beta7",
+        "magento/module-sales": "0.74.0-beta7",
+        "magento/module-checkout": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-eav": "0.74.0-beta7",
+        "magento/module-customer": "0.74.0-beta7",
+        "magento/module-catalog-rule": "0.74.0-beta7",
+        "magento/module-directory": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
+        "magento/module-media-storage": "0.74.0-beta7",
+        "magento/module-quote": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "suggest": {
-      "magento/module-webapi": "0.74.0-beta6"
+      "magento/module-webapi": "0.74.0-beta7"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/ConfigurableProduct/etc/di.xml b/app/code/Magento/ConfigurableProduct/etc/di.xml
index fcd5d77b81e4de8e9a5df180968909b02d290221..490c15a70a51fc150d80d3e8b42dd5c4ef8aa47e 100644
--- a/app/code/Magento/ConfigurableProduct/etc/di.xml
+++ b/app/code/Magento/ConfigurableProduct/etc/di.xml
@@ -6,7 +6,6 @@
  */
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
-    <preference for="Magento\ConfigurableProduct\Api\OptionTypesListInterface" type="Magento\ConfigurableProduct\Model\OptionTypesList" />
     <preference for="Magento\ConfigurableProduct\Api\ConfigurableProductManagementInterface" type="Magento\ConfigurableProduct\Model\ConfigurableProductManagement" />
     <preference for="Magento\ConfigurableProduct\Api\LinkManagementInterface" type="Magento\ConfigurableProduct\Model\LinkManagement" />
     <preference for="Magento\ConfigurableProduct\Api\OptionRepositoryInterface" type="Magento\ConfigurableProduct\Model\OptionRepository" />
@@ -59,6 +58,12 @@
     <type name="Magento\Catalog\Model\Product\Type">
         <plugin name="configurable_output" type="Magento\ConfigurableProduct\Model\Product\Type\Plugin" />
     </type>
+    <type name="Magento\Catalog\Api\ProductRepositoryInterface">
+        <plugin name="configurableProductSaveOptions" type="\Magento\ConfigurableProduct\Model\Plugin\AroundProductRepositorySave"/>
+    </type>
+    <type name="Magento\Catalog\Model\Product">
+        <plugin name="configurableProductLoadAfter" type="\Magento\ConfigurableProduct\Model\Plugin\AfterProductLoad"/>
+    </type>
     <virtualType name="Magento\ConfigurableProduct\Pricing\Price\Pool" type="Magento\Framework\Pricing\Price\Pool">
         <arguments>
             <argument name="prices" xsi:type="array">
diff --git a/app/code/Magento/ConfigurableProduct/etc/service_data_attributes.xml b/app/code/Magento/ConfigurableProduct/etc/service_data_attributes.xml
new file mode 100644
index 0000000000000000000000000000000000000000..74edcdbf65a91e08cc384b50b416deff63e8780c
--- /dev/null
+++ b/app/code/Magento/ConfigurableProduct/etc/service_data_attributes.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Api/etc/service_data_attributes.xsd">
+    <extension_attributes for="Magento\Catalog\Api\Data\ProductInterface">
+        <attribute code="configurable_product_options" type="Magento\ConfigurableProduct\Api\Data\OptionInterface[]" />
+        <attribute code="configurable_product_links" type="int[]" />
+    </extension_attributes>
+</config>
diff --git a/app/code/Magento/ConfigurableProduct/etc/webapi.xml b/app/code/Magento/ConfigurableProduct/etc/webapi.xml
index 9c68aa71869f44782120dda382eb7de6c34e9f2d..158db3c3c5fa8313960e1735250f3f7cfb250388 100644
--- a/app/code/Magento/ConfigurableProduct/etc/webapi.xml
+++ b/app/code/Magento/ConfigurableProduct/etc/webapi.xml
@@ -43,12 +43,6 @@
             <resource ref="Magento_Catalog::products"/>
         </resources>
     </route>
-    <route url="/V1/configurable-products/options/types" method="GET">
-        <service class="Magento\ConfigurableProduct\Api\OptionTypesListInterface" method="getItems" />
-        <resources>
-            <resource ref="Magento_Catalog::products" />
-        </resources>
-    </route>
     <route url="/V1/configurable-products/:sku/options" method="POST">
         <service class="Magento\ConfigurableProduct\Api\OptionRepositoryInterface" method="save" />
         <resources>
diff --git a/app/code/Magento/Contact/composer.json b/app/code/Magento/Contact/composer.json
index d2e5971064d0752a9053de71ef835fa13f07b6db..3918d730162140a6d4a43c0d3f867d04160a7da7 100644
--- a/app/code/Magento/Contact/composer.json
+++ b/app/code/Magento/Contact/composer.json
@@ -3,15 +3,15 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-config": "0.74.0-beta6",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-customer": "0.74.0-beta6",
-        "magento/module-cms": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-config": "0.74.0-beta7",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-customer": "0.74.0-beta7",
+        "magento/module-cms": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Cookie/composer.json b/app/code/Magento/Cookie/composer.json
index d3d5ef16f597b19653d8a69ff3e597bca16d30bf..e9fbc65e8fe32e9286593292ffb40f6f2c373af3 100644
--- a/app/code/Magento/Cookie/composer.json
+++ b/app/code/Magento/Cookie/composer.json
@@ -3,15 +3,15 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "suggest": {
-        "magento/module-backend": "0.74.0-beta6"
+        "magento/module-backend": "0.74.0-beta7"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Cron/composer.json b/app/code/Magento/Cron/composer.json
index 02fe4b2ed4e83bb3de474176d18e622266e9552d..a1fbef449d8300e48de58421c67bd96cd716ea89 100644
--- a/app/code/Magento/Cron/composer.json
+++ b/app/code/Magento/Cron/composer.json
@@ -3,13 +3,13 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-config": "0.74.0-beta6",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-config": "0.74.0-beta7",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/CurrencySymbol/composer.json b/app/code/Magento/CurrencySymbol/composer.json
index 4ef0b1acf67493b6de9ff927c58ba3ad8ae97166..6f862fbf51bd05c47a100f58df52d9d7580bb902 100644
--- a/app/code/Magento/CurrencySymbol/composer.json
+++ b/app/code/Magento/CurrencySymbol/composer.json
@@ -3,16 +3,16 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-config": "0.74.0-beta6",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-page-cache": "0.74.0-beta6",
-        "magento/module-directory": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-config": "0.74.0-beta7",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-page-cache": "0.74.0-beta7",
+        "magento/module-directory": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Customer/Block/Adminhtml/Edit/BackButton.php b/app/code/Magento/Customer/Block/Adminhtml/Edit/BackButton.php
index ee99e417ad351ce4007b26d8119a590a5c7daa38..20d5ffa53787e68ab33e50a594401856af4dcec5 100644
--- a/app/code/Magento/Customer/Block/Adminhtml/Edit/BackButton.php
+++ b/app/code/Magento/Customer/Block/Adminhtml/Edit/BackButton.php
@@ -5,11 +5,10 @@
  */
 namespace Magento\Customer\Block\Adminhtml\Edit;
 
-use Magento\Ui\Component\Control\ButtonProviderInterface;
+use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface;
 
 /**
  * Class BackButton
- * @package Magento\Customer\Block\Adminhtml\Edit
  */
 class BackButton extends GenericButton implements ButtonProviderInterface
 {
@@ -20,7 +19,7 @@ class BackButton extends GenericButton implements ButtonProviderInterface
     {
         return [
             'label' => __('Back'),
-            'on_click' => 'setLocation(\'' . $this->getBackUrl() . '\')',
+            'on_click' => sprintf("location.href = '%s';", $this->getBackUrl()),
             'class' => 'back',
             'sort_order' => 10
         ];
diff --git a/app/code/Magento/Customer/Block/Adminhtml/Edit/DeleteButton.php b/app/code/Magento/Customer/Block/Adminhtml/Edit/DeleteButton.php
index 00966848b9b3177db7df9b0e8c6605d4c9f35013..c2961ece3dd4b6938635711b7836721cc243886e 100644
--- a/app/code/Magento/Customer/Block/Adminhtml/Edit/DeleteButton.php
+++ b/app/code/Magento/Customer/Block/Adminhtml/Edit/DeleteButton.php
@@ -6,7 +6,7 @@
 namespace Magento\Customer\Block\Adminhtml\Edit;
 
 use Magento\Customer\Api\AccountManagementInterface;
-use Magento\Ui\Component\Control\ButtonProviderInterface;
+use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface;
 
 /**
  * Class DeleteButton
diff --git a/app/code/Magento/Customer/Block/Adminhtml/Edit/InvalidateTokenButton.php b/app/code/Magento/Customer/Block/Adminhtml/Edit/InvalidateTokenButton.php
index 7b02478d44516a095d203c1b5a31f6a73a1952bc..a3744a1e8b2c3d08dc3e5729edd0dc849401b84a 100644
--- a/app/code/Magento/Customer/Block/Adminhtml/Edit/InvalidateTokenButton.php
+++ b/app/code/Magento/Customer/Block/Adminhtml/Edit/InvalidateTokenButton.php
@@ -5,7 +5,7 @@
  */
 namespace Magento\Customer\Block\Adminhtml\Edit;
 
-use Magento\Ui\Component\Control\ButtonProviderInterface;
+use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface;
 
 /**
  * Class InvalidateTokenButton
diff --git a/app/code/Magento/Customer/Block/Adminhtml/Edit/OrderButton.php b/app/code/Magento/Customer/Block/Adminhtml/Edit/OrderButton.php
index 4b402caf146e2112786a254f797cb3ecd1341be2..0edfd379f6517bb9a979c157ca530f3118119084 100644
--- a/app/code/Magento/Customer/Block/Adminhtml/Edit/OrderButton.php
+++ b/app/code/Magento/Customer/Block/Adminhtml/Edit/OrderButton.php
@@ -5,11 +5,10 @@
  */
 namespace Magento\Customer\Block\Adminhtml\Edit;
 
-use Magento\Ui\Component\Control\ButtonProviderInterface;
+use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface;
 
 /**
  * Class OrderButton
- * @package Magento\Customer\Block\Adminhtml\Edit
  */
 class OrderButton extends GenericButton implements ButtonProviderInterface
 {
@@ -42,7 +41,7 @@ class OrderButton extends GenericButton implements ButtonProviderInterface
         if ($customerId && $this->authorization->isAllowed('Magento_Sales::create')) {
             $data = [
                 'label' => __('Create Order'),
-                'on_click' => 'setLocation(\'' . $this->getCreateOrderUrl() . '\')',
+                'on_click' => sprintf("location.href = '%s';", $this->getCreateOrderUrl()),
                 'class' => 'add',
                 'sort_order' => 40,
             ];
diff --git a/app/code/Magento/Customer/Block/Adminhtml/Edit/ResetButton.php b/app/code/Magento/Customer/Block/Adminhtml/Edit/ResetButton.php
index 81e2d5845910886742c0f0f85d26c4b6bb9cbf18..8581974c55b8d8472502b5552d7562d4e9ee96ec 100644
--- a/app/code/Magento/Customer/Block/Adminhtml/Edit/ResetButton.php
+++ b/app/code/Magento/Customer/Block/Adminhtml/Edit/ResetButton.php
@@ -5,11 +5,10 @@
  */
 namespace Magento\Customer\Block\Adminhtml\Edit;
 
-use Magento\Ui\Component\Control\ButtonProviderInterface;
+use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface;
 
 /**
  * Class ResetButton
- * @package Magento\Customer\Block\Adminhtml\Edit
  */
 class ResetButton implements ButtonProviderInterface
 {
@@ -21,7 +20,7 @@ class ResetButton implements ButtonProviderInterface
         return [
             'label' => __('Reset'),
             'class' => 'reset',
-            'on_click' => 'setLocation(window.location.href)',
+            'on_click' => 'location.reload();',
             'sort_order' => 30
         ];
     }
diff --git a/app/code/Magento/Customer/Block/Adminhtml/Edit/ResetPasswordButton.php b/app/code/Magento/Customer/Block/Adminhtml/Edit/ResetPasswordButton.php
index ff377711a9b506dd5c6061f36a8151bf333dbd6a..f2894efd0bd0ba816b4d627a48b703948d0a355a 100644
--- a/app/code/Magento/Customer/Block/Adminhtml/Edit/ResetPasswordButton.php
+++ b/app/code/Magento/Customer/Block/Adminhtml/Edit/ResetPasswordButton.php
@@ -5,11 +5,10 @@
  */
 namespace Magento\Customer\Block\Adminhtml\Edit;
 
-use Magento\Ui\Component\Control\ButtonProviderInterface;
+use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface;
 
 /**
  * Class ResetPasswordButton
- * @package Magento\Customer\Block\Adminhtml\Edit
  */
 class ResetPasswordButton extends GenericButton implements ButtonProviderInterface
 {
@@ -24,7 +23,7 @@ class ResetPasswordButton extends GenericButton implements ButtonProviderInterfa
             $data = [
                 'label' => __('Reset Password'),
                 'class' => 'reset reset-password',
-                'on_click' => 'setLocation(\'' . $this->getResetPasswordUrl() . '\')',
+                'on_click' => sprintf("location.href = '%s';", $this->getResetPasswordUrl()),
                 'sort_order' => 40,
             ];
         }
diff --git a/app/code/Magento/Customer/Block/Adminhtml/Edit/SaveAndContinueButton.php b/app/code/Magento/Customer/Block/Adminhtml/Edit/SaveAndContinueButton.php
index f3113b1503ab1896f6bb82e030525640dea77a5c..44b9d328b252e848acfb58c6a8ecd4f37e35c1e1 100644
--- a/app/code/Magento/Customer/Block/Adminhtml/Edit/SaveAndContinueButton.php
+++ b/app/code/Magento/Customer/Block/Adminhtml/Edit/SaveAndContinueButton.php
@@ -6,11 +6,10 @@
 namespace Magento\Customer\Block\Adminhtml\Edit;
 
 use Magento\Customer\Api\AccountManagementInterface;
-use Magento\Ui\Component\Control\ButtonProviderInterface;
+use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface;
 
 /**
  * Class SaveAndContinueButton
- * @package Magento\Customer\Block\Adminhtml\Edit
  */
 class SaveAndContinueButton extends GenericButton implements ButtonProviderInterface
 {
diff --git a/app/code/Magento/Customer/Block/Adminhtml/Edit/SaveButton.php b/app/code/Magento/Customer/Block/Adminhtml/Edit/SaveButton.php
index b52302c73c90a619723dd57cb8552cb555a892c5..33f0bdada2941a33f6a5e38b3ec6ad99a425c8a6 100644
--- a/app/code/Magento/Customer/Block/Adminhtml/Edit/SaveButton.php
+++ b/app/code/Magento/Customer/Block/Adminhtml/Edit/SaveButton.php
@@ -6,7 +6,7 @@
 namespace Magento\Customer\Block\Adminhtml\Edit;
 
 use Magento\Customer\Api\AccountManagementInterface;
-use Magento\Ui\Component\Control\ButtonProviderInterface;
+use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface;
 
 /**
  * Class SaveButton
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php
index 4a6743eddfabfa5ea5e4edc92c88aa13e8d40e7c..08919f7401d9007c97a89ad793161063ae4ca1cb 100644
--- a/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php
@@ -27,7 +27,7 @@ class Save extends \Magento\Customer\Controller\Adminhtml\Index
     protected function _extractCustomerData()
     {
         $customerData = [];
-        if ($this->getRequest()->getPost('account')) {
+        if ($this->getRequest()->getPost('customer')) {
             $serviceAttributes = [
                 CustomerInterface::DEFAULT_BILLING,
                 CustomerInterface::DEFAULT_SHIPPING,
@@ -40,7 +40,7 @@ class Save extends \Magento\Customer\Controller\Adminhtml\Index
                 'adminhtml_customer',
                 \Magento\Customer\Api\CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER,
                 $serviceAttributes,
-                'account'
+                'customer'
             );
         }
 
@@ -113,7 +113,7 @@ class Save extends \Magento\Customer\Controller\Adminhtml\Index
         $extractedCustomerData[CustomerInterface::DEFAULT_BILLING] = null;
         $extractedCustomerData[CustomerInterface::DEFAULT_SHIPPING] = null;
         foreach ($addressIdList as $addressId) {
-            $scope = sprintf('account/customer_address/%s', $addressId);
+            $scope = sprintf('address/%s', $addressId);
             $addressData = $this->_extractData(
                 $this->getRequest(),
                 'adminhtml_customer_address',
@@ -151,10 +151,9 @@ class Save extends \Magento\Customer\Controller\Adminhtml\Index
      */
     protected function _extractCustomerAddressData(array & $extractedCustomerData)
     {
-        $customerData = $this->getRequest()->getPost('account');
-        $addresses = isset($customerData['customer_address']) ? $customerData['customer_address'] : [];
+        $addresses = $this->getRequest()->getPost('address');
         $result = [];
-        if ($addresses) {
+        if (is_array($addresses)) {
             if (isset($addresses['_template_'])) {
                 unset($addresses['_template_']);
             }
@@ -177,8 +176,10 @@ class Save extends \Magento\Customer\Controller\Adminhtml\Index
     public function execute()
     {
         $returnToEdit = false;
-        $customerId = (int)$this->getRequest()->getParam('id');
         $originalRequestData = $this->getRequest()->getPostValue();
+        $customerId = isset($originalRequestData['customer']['entity_id'])
+            ? $originalRequestData['customer']['entity_id']
+            : null;
         if ($originalRequestData) {
             try {
                 // optional fields might be set in request for future processing by observers in other modules
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/Validate.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/Validate.php
index 3986551d78389058e3f503511c7bf9d621ee66f5..b701d653dc030d2436527e924c5761f369e9da99 100644
--- a/app/code/Magento/Customer/Controller/Adminhtml/Index/Validate.php
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/Validate.php
@@ -37,7 +37,7 @@ class Validate extends \Magento\Customer\Controller\Adminhtml\Index
             );
             $customerForm->setInvisibleIgnored(true);
 
-            $data = $customerForm->extractData($this->getRequest(), 'account');
+            $data = $customerForm->extractData($this->getRequest(), 'customer');
 
             if ($customer->getWebsiteId()) {
                 unset($data['website_id']);
@@ -74,8 +74,7 @@ class Validate extends \Magento\Customer\Controller\Adminhtml\Index
      */
     protected function _validateCustomerAddress($response)
     {
-        $customerData =  $this->getRequest()->getParam('account');
-        $addresses = isset($customerData['customer_address']) ? $customerData['customer_address'] : [];
+        $addresses = $this->getRequest()->getPost('address');
         if (!is_array($addresses)) {
             return;
         }
@@ -86,7 +85,7 @@ class Validate extends \Magento\Customer\Controller\Adminhtml\Index
 
             $addressForm = $this->_formFactory->create('customer_address', 'adminhtml_customer_address');
 
-            $requestScope = sprintf('account/customer_address/%s', $index);
+            $requestScope = sprintf('address/%s', $index);
             $formData = $addressForm->extractData($this->getRequest(), $requestScope);
 
             $errors = $addressForm->validateData($formData);
diff --git a/app/code/Magento/Customer/Model/Config/Backend/Address/Street.php b/app/code/Magento/Customer/Model/Config/Backend/Address/Street.php
index 7e187a71e5c08bdad11cf84b9cfdc3c9ca85632c..b25f4c6d0b3a3cb83b3693f1d2d7c08fb4859247 100644
--- a/app/code/Magento/Customer/Model/Config/Backend/Address/Street.php
+++ b/app/code/Magento/Customer/Model/Config/Backend/Address/Street.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\Customer\Model\Config\Backend\Address;
 
+use Magento\Framework\App\Config\ScopeConfigInterface;
+
 /**
  * Line count config model for customer address street attribute
  *
@@ -64,7 +66,7 @@ class Street extends \Magento\Framework\App\Config\Value
                 }
                 break;
 
-            case \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT:
+            case ScopeConfigInterface::SCOPE_TYPE_DEFAULT:
                 $attribute->setData('multiline_count', $value);
                 break;
         }
diff --git a/app/code/Magento/Customer/Model/Customer.php b/app/code/Magento/Customer/Model/Customer.php
index d6792e7d47c2a33d77b8b6991754a7dad31c3e56..776c8e74e1ace9aa8cc4205174c6fb0977032368 100644
--- a/app/code/Magento/Customer/Model/Customer.php
+++ b/app/code/Magento/Customer/Model/Customer.php
@@ -12,6 +12,7 @@ use Magento\Customer\Model\Resource\Address\CollectionFactory;
 use Magento\Customer\Model\Resource\Customer as ResourceCustomer;
 use Magento\Customer\Api\Data\CustomerInterfaceFactory;
 use Magento\Customer\Model\Data\Customer as CustomerData;
+use Magento\Framework\App\Config\ScopeConfigInterface;
 use Magento\Framework\Reflection\DataObjectProcessor;
 use Magento\Framework\Exception\EmailNotConfirmedException;
 use Magento\Framework\Exception\InvalidEmailOrPasswordException;
@@ -1034,6 +1035,12 @@ class Customer extends \Magento\Framework\Model\AbstractModel
             $errors[] = __('Gender is required.');
         }
 
+        $transport = new \Magento\Framework\Object(
+            ['errors' => $errors]
+        );
+        $this->_eventManager->dispatch('customer_validate', ['customer' => $this, 'transport' => $transport]);
+        $errors = $transport->getErrors();
+
         if (empty($errors)) {
             return true;
         }
@@ -1304,7 +1311,7 @@ class Customer extends \Magento\Framework\Model\AbstractModel
     {
         return (int)$this->_scopeConfig->getValue(
             self::XML_PATH_CUSTOMER_RESET_PASSWORD_LINK_EXPIRATION_PERIOD,
-            \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT
+            ScopeConfigInterface::SCOPE_TYPE_DEFAULT
         );
     }
 
diff --git a/app/code/Magento/Customer/Model/Customer/DataProvider.php b/app/code/Magento/Customer/Model/Customer/DataProvider.php
new file mode 100644
index 0000000000000000000000000000000000000000..8597c0da84a866ac3cd2be1812044273e782ec77
--- /dev/null
+++ b/app/code/Magento/Customer/Model/Customer/DataProvider.php
@@ -0,0 +1,373 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Customer\Model\Customer;
+
+use Magento\Eav\Model\Config;
+use Magento\Eav\Model\Entity\Type;
+use Magento\Customer\Model\Address;
+use Magento\Customer\Model\Customer;
+use Magento\Ui\DataProvider\EavValidationRul;
+use Magento\Customer\Model\Resource\Customer\Collection;
+use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface;
+use Magento\Customer\Model\Resource\Customer\CollectionFactory as CustomerCollectionFactory;
+
+/**
+ * Class DataProvider
+ */
+class DataProvider implements DataProviderInterface
+{
+    /**
+     * @var string
+     */
+    protected $primaryFieldName;
+
+    /**
+     * @var string
+     */
+    protected $requestFieldName;
+
+    /**
+     * @var Collection
+     */
+    protected $collection;
+
+    /**
+     * @var Config
+     */
+    protected $eavConfig;
+
+    /**
+     * @var array
+     */
+    protected $meta = [];
+
+    /**
+     * Provider configuration data
+     *
+     * @var array
+     */
+    protected $data = [];
+
+    /**
+     * @var array
+     */
+    protected $loadedData;
+
+    /**
+     * EAV attribute properties to fetch from meta storage
+     * @var array
+     */
+    protected $metaProperties = [
+        'dataType' => 'frontend_input',
+        'visible' => 'is_visible',
+        'required' => 'is_required',
+        'label' => 'frontend_label',
+        'sortOrder' => 'sort_order',
+        'notice' => 'note',
+        'default' => 'default_value',
+        'size' => 'scope_multiline_count'
+    ];
+
+    /**
+     * Form element mapping
+     *
+     * @var array
+     */
+    protected $formElement = [
+        'text' => 'input',
+        'hidden' => 'input',
+        'boolean' => 'checkbox',
+    ];
+
+    /**
+     * @var EavValidationRul
+     */
+    protected $eavValidationRul;
+
+    /**
+     * Constructor
+     *
+     * @param string $primaryFieldName
+     * @param string $requestFieldName
+     * @param EavValidationRul $eavValidationRul
+     * @param CustomerCollectionFactory $customerCollectionFactory
+     * @param Config $eavConfig
+     * @param array $meta
+     * @param array $data
+     */
+    public function __construct(
+        $primaryFieldName,
+        $requestFieldName,
+        EavValidationRul $eavValidationRul,
+        CustomerCollectionFactory $customerCollectionFactory,
+        Config $eavConfig,
+        array $meta = [],
+        array $data = []
+    ) {
+        $this->primaryFieldName = $primaryFieldName;
+        $this->requestFieldName = $requestFieldName;
+        $this->eavValidationRul = $eavValidationRul;
+        $this->collection = $customerCollectionFactory->create();
+        $this->collection->addAttributeToSelect('*');
+        $this->eavConfig = $eavConfig;
+        $this->meta = $meta;
+        $this->meta['customer']['fields'] = $this->getAttributesMeta(
+            $this->eavConfig->getEntityType('customer')
+        );
+        $this->meta['address']['fields'] = $this->getAttributesMeta(
+            $this->eavConfig->getEntityType('customer_address')
+        );
+        $this->data = $data;
+    }
+
+    /**
+     * Get meta data
+     *
+     * @return array
+     */
+    public function getMeta()
+    {
+        return $this->meta;
+    }
+
+    /**
+     * Get field meta info
+     *
+     * @param string $fieldSetName
+     * @param string $fieldName
+     * @return array
+     */
+    public function getFieldMetaInfo($fieldSetName, $fieldName)
+    {
+        return isset($this->meta[$fieldSetName]['fields'][$fieldName])
+            ? $this->meta[$fieldSetName]['fields'][$fieldName]
+            : [];
+    }
+
+    /**
+     * Get config data
+     *
+     * @return mixed
+     */
+    public function getConfigData()
+    {
+        return isset($this->data['config']) ? $this->data['config'] : [];
+    }
+
+    /**
+     * Set data
+     *
+     * @param mixed $config
+     * @return void
+     */
+    public function setConfigData($config)
+    {
+        $this->data['config'] = $config;
+    }
+
+    /**
+     * Get data
+     *
+     * @return array
+     */
+    public function getData()
+    {
+        if (isset($this->loadedData)) {
+            return $this->loadedData;
+        }
+
+        $items = $this->collection->getItems();
+        /** @var Customer $customer */
+        foreach ($items as $customer) {
+            $result['customer'] = $customer->getData();
+
+            $addresses = [];
+            /** @var Address $address */
+            foreach ($customer->getAddresses() as $address) {
+                $addressId = $address->getId();
+                $address->load($addressId);
+                $addresses[$addressId] = $address->getData();
+                $this->prepareAddressData($addressId, $addresses, $result['customer']);
+            }
+            if (!empty($addresses)) {
+                $result['address'] = $addresses;
+            }
+
+            $this->loadedData[$customer->getId()] = $result;
+        }
+
+        return $this->loadedData;
+    }
+
+    /**
+     * Get field name in request
+     *
+     * @return string
+     */
+    public function getRequestFieldName()
+    {
+        return $this->requestFieldName;
+    }
+
+    /**
+     * Get primary field name
+     *
+     * @return string
+     */
+    public function getPrimaryFieldName()
+    {
+        return $this->primaryFieldName;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function addFilter($field, $condition = null)
+    {
+        $this->collection->addFieldToFilter($field, $condition);
+    }
+
+    /**
+     * Add field to select
+     *
+     * @param string|array $field
+     * @param string|null $alias
+     * @return void
+     */
+    public function addField($field, $alias = null)
+    {
+        $this->collection->addAttributeToSelect($field);
+    }
+
+    /**
+     * self::setOrder() alias
+     *
+     * @param string $field
+     * @param string $direction
+     * @return void
+     */
+    public function addOrder($field, $direction)
+    {
+        $this->collection->addOrder($field, $direction);
+    }
+
+    /**
+     * Set Query limit
+     *
+     * @param int $offset
+     * @param int $size
+     * @return void
+     */
+    public function setLimit($offset, $size)
+    {
+        $this->collection->setPageSize($size);
+        $this->collection->setCurPage($offset);
+    }
+
+    /**
+     * Removes field from select
+     *
+     * @param string|null $field
+     * @param bool $isAlias Alias identifier
+     * @return void
+     */
+    public function removeField($field, $isAlias = false)
+    {
+        $this->collection->removeAttributeToSelect($field);
+    }
+
+    /**
+     * Removes all fields from select
+     *
+     * @return void
+     */
+    public function removeAllFields()
+    {
+        $this->collection->removeAttributeToSelect();
+    }
+
+    /**
+     * Retrieve count of loaded items
+     *
+     * @return int
+     */
+    public function count()
+    {
+        return $this->collection->count();
+    }
+
+    /**
+     * Get fields meta info
+     *
+     * @param string $fieldSetName
+     * @return array
+     */
+    public function getFieldsMetaInfo($fieldSetName)
+    {
+        return isset($this->meta[$fieldSetName]['fields']) ? $this->meta[$fieldSetName]['fields'] : [];
+    }
+
+    /**
+     * Get attributes meta
+     *
+     * @param Type $entityType
+     * @return array
+     * @throws \Magento\Framework\Exception\LocalizedException
+     */
+    protected function getAttributesMeta(Type $entityType)
+    {
+        $meta = [];
+        $attributes = $entityType->getAttributeCollection();
+        /* @var \Magento\Eav\Model\Entity\Attribute\AbstractAttribute $attribute */
+        foreach ($attributes as $attribute) {
+            $code = $attribute->getAttributeCode();
+            // use getDataUsingMethod, since some getters are defined and apply additional processing of returning value
+            foreach ($this->metaProperties as $metaName => $origName) {
+                $value = $attribute->getDataUsingMethod($origName);
+                $meta[$code][$metaName] = $value;
+                if ('frontend_input' === $origName) {
+                    $meta[$code]['formElement'] = isset($this->formElement[$value])
+                        ? $this->formElement[$value]
+                        : $value;
+                }
+                if ($attribute->usesSource()) {
+                    $meta[$code]['options'] = $attribute->getSource()->getAllOptions();
+                }
+            }
+
+            $rules = $this->eavValidationRul->build($attribute, $meta[$code]);
+            if (!empty($rules)) {
+                $meta[$code]['validation'] = $rules;
+            }
+        }
+        return $meta;
+    }
+
+    /**
+     * Prepare address data
+     *
+     * @param int $addressId
+     * @param array $addresses
+     * @param array $customer
+     * @return void
+     */
+    protected function prepareAddressData($addressId, array &$addresses, array $customer)
+    {
+        if (isset($customer['default_billing'])
+            && $addressId == $customer['default_billing']
+        ) {
+            $addresses[$addressId]['default_billing'] = $customer['default_billing'];
+        }
+        if (isset($customer['default_shipping'])
+            && $addressId == $customer['default_shipping']
+        ) {
+            $addresses[$addressId]['default_shipping'] = $customer['default_shipping'];
+        }
+        if (isset($addresses[$addressId]['street'])) {
+            $addresses[$addressId]['street'] = explode("\n", $addresses[$addressId]['street']);
+        }
+    }
+}
diff --git a/app/code/Magento/Customer/Model/Resource/Address.php b/app/code/Magento/Customer/Model/Resource/Address.php
index 57a5c1cbcf3d9c28e975a999395d5ffd18600696..3b6ae0a28c8f9e812e762b72dbfe45d35681ebe9 100644
--- a/app/code/Magento/Customer/Model/Resource/Address.php
+++ b/app/code/Magento/Customer/Model/Resource/Address.php
@@ -45,13 +45,22 @@ class Address extends \Magento\Eav\Model\Entity\AbstractEntity
      */
     protected function _construct()
     {
-        $resource = $this->_resource;
-        $this->setType(
-            'customer_address'
-        )->setConnection(
-            $resource->getConnection('customer_read'),
-            $resource->getConnection('customer_write')
-        );
+        $this->_read = 'customer_read';
+        $this->_write = 'customer_write';
+    }
+
+    /**
+     * Getter and lazy loader for _type
+     *
+     * @throws \Magento\Framework\Exception\LocalizedException
+     * @return \Magento\Eav\Model\Entity\Type
+     */
+    public function getEntityType()
+    {
+        if (empty($this->_type)) {
+            $this->setType('customer_address');
+        }
+        return parent::getEntityType();
     }
 
     /**
diff --git a/app/code/Magento/Customer/Model/Session.php b/app/code/Magento/Customer/Model/Session.php
index c01cd99d642cf7cb72c963fc20513f2e8e525235..4212be78b59114439b049203b03eca3a488991e4 100644
--- a/app/code/Magento/Customer/Model/Session.php
+++ b/app/code/Magento/Customer/Model/Session.php
@@ -102,6 +102,7 @@ class Session extends \Magento\Framework\Session\SessionManager
      * @param \Magento\Framework\Session\StorageInterface $storage
      * @param \Magento\Framework\Stdlib\CookieManagerInterface $cookieManager
      * @param \Magento\Framework\Stdlib\Cookie\CookieMetadataFactory $cookieMetadataFactory
+     * @param \Magento\Framework\App\State $appState
      * @param Share $configShare
      * @param \Magento\Framework\Url\Helper\Data $coreUrl
      * @param \Magento\Customer\Model\Url $customerUrl
@@ -113,6 +114,7 @@ class Session extends \Magento\Framework\Session\SessionManager
      * @param \Magento\Framework\App\Http\Context $httpContext
      * @param CustomerRepositoryInterface $customerRepository
      * @param GroupManagementInterface $groupManagement
+     * @throws \Magento\Framework\Exception\SessionException
      * @SuppressWarnings(PHPMD.ExcessiveParameterList)
      */
     public function __construct(
@@ -124,6 +126,7 @@ class Session extends \Magento\Framework\Session\SessionManager
         \Magento\Framework\Session\StorageInterface $storage,
         \Magento\Framework\Stdlib\CookieManagerInterface $cookieManager,
         \Magento\Framework\Stdlib\Cookie\CookieMetadataFactory $cookieMetadataFactory,
+        \Magento\Framework\App\State $appState,
         Config\Share $configShare,
         \Magento\Framework\Url\Helper\Data $coreUrl,
         \Magento\Customer\Model\Url $customerUrl,
@@ -154,9 +157,9 @@ class Session extends \Magento\Framework\Session\SessionManager
             $validator,
             $storage,
             $cookieManager,
-            $cookieMetadataFactory
+            $cookieMetadataFactory,
+            $appState
         );
-        $this->start();
         $this->groupManagement = $groupManagement;
         $this->_eventManager->dispatch('customer_session_init', ['customer_session' => $this]);
     }
diff --git a/app/code/Magento/Customer/Test/Unit/Block/Widget/DobTest.php b/app/code/Magento/Customer/Test/Unit/Block/Widget/DobTest.php
index 5d1e91708b4fcd6da306011c551415bf3586d66a..834c64df6701f19605ccd05fb8298d1def87fa4a 100644
--- a/app/code/Magento/Customer/Test/Unit/Block/Widget/DobTest.php
+++ b/app/code/Magento/Customer/Test/Unit/Block/Widget/DobTest.php
@@ -10,6 +10,7 @@ namespace Magento\Customer\Test\Unit\Block\Widget;
 
 use Magento\Framework\Exception\NoSuchEntityException;
 use Magento\Customer\Block\Widget\Dob;
+use Magento\Framework\Locale\Resolver;
 
 class DobTest extends \PHPUnit_Framework_TestCase
 {
@@ -69,7 +70,7 @@ class DobTest extends \PHPUnit_Framework_TestCase
         $localeResolver = $this->getMock('\Magento\Framework\Locale\ResolverInterface');
         $localeResolver->expects($this->any())
             ->method('getLocale')
-            ->willReturn(\Magento\Framework\Locale\ResolverInterface::DEFAULT_LOCALE);
+            ->willReturn(Resolver::DEFAULT_LOCALE);
         $timezone = $objectManager->getObject(
             'Magento\Framework\Stdlib\DateTime\Timezone',
             ['localeResolver' => $localeResolver]
diff --git a/app/code/Magento/Customer/Test/Unit/Model/Resource/AddressTest.php b/app/code/Magento/Customer/Test/Unit/Model/Resource/AddressTest.php
index fe17aa1aca70eb47723da99b6c9a8639944b76de..c15cf1596c8245fb30d8a79ba097923d545c26b0 100644
--- a/app/code/Magento/Customer/Test/Unit/Model/Resource/AddressTest.php
+++ b/app/code/Magento/Customer/Test/Unit/Model/Resource/AddressTest.php
@@ -18,6 +18,9 @@ class AddressTest extends \PHPUnit_Framework_TestCase
     /** @var \Magento\Customer\Model\CustomerFactory|\PHPUnit_Framework_MockObject_MockObject */
     protected $customerFactory;
 
+    /** @var \Magento\Eav\Model\Entity\Type */
+    protected $eavConfigType;
+
     protected function setUp()
     {
         $this->addressResource = (new ObjectManagerHelper($this))->getObject(
@@ -178,16 +181,16 @@ class AddressTest extends \PHPUnit_Framework_TestCase
                 )
             );
 
-        $eavConfigType = $this->getMock(
+        $this->eavConfigType = $this->getMock(
             'Magento\Eav\Model\Entity\Type',
             ['getEntityIdField', 'getId', 'getEntityTable', '__wakeup'],
             [],
             '',
             false
         );
-        $eavConfigType->expects($this->any())->method('getEntityIdField')->willReturn(false);
-        $eavConfigType->expects($this->any())->method('getId')->willReturn(false);
-        $eavConfigType->expects($this->any())->method('getEntityTable')->willReturn('customer_address_entity');
+        $this->eavConfigType->expects($this->any())->method('getEntityIdField')->willReturn(false);
+        $this->eavConfigType->expects($this->any())->method('getId')->willReturn(false);
+        $this->eavConfigType->expects($this->any())->method('getEntityTable')->willReturn('customer_address_entity');
 
         $eavConfig = $this->getMock(
             'Magento\Eav\Model\Config',
@@ -199,10 +202,10 @@ class AddressTest extends \PHPUnit_Framework_TestCase
         $eavConfig->expects($this->any())
             ->method('getEntityType')
             ->with('customer_address')
-            ->willReturn($eavConfigType);
+            ->willReturn($this->eavConfigType);
         $eavConfig->expects($this->any())
             ->method('getEntityAttributeCodes')
-            ->with($eavConfigType)
+            ->with($this->eavConfigType)
             ->willReturn(
                 [
                     'entity_type_id',
@@ -217,13 +220,13 @@ class AddressTest extends \PHPUnit_Framework_TestCase
         $eavConfig->expects($this->any())
             ->method('getAttribute')
             ->willReturnMap([
-                [$eavConfigType, 'entity_type_id', $attributeMock],
-                [$eavConfigType, 'attribute_set_id', $attributeMock],
-                [$eavConfigType, 'created_at', $attributeMock],
-                [$eavConfigType, 'updated_at', $attributeMock],
-                [$eavConfigType, 'parent_id', $attributeMock],
-                [$eavConfigType, 'increment_id', $attributeMock],
-                [$eavConfigType, 'entity_id', $attributeMock],
+                [$this->eavConfigType, 'entity_type_id', $attributeMock],
+                [$this->eavConfigType, 'attribute_set_id', $attributeMock],
+                [$this->eavConfigType, 'created_at', $attributeMock],
+                [$this->eavConfigType, 'updated_at', $attributeMock],
+                [$this->eavConfigType, 'parent_id', $attributeMock],
+                [$this->eavConfigType, 'increment_id', $attributeMock],
+                [$this->eavConfigType, 'entity_id', $attributeMock],
             ]);
 
         return $eavConfig;
@@ -261,4 +264,9 @@ class AddressTest extends \PHPUnit_Framework_TestCase
         $this->customerFactory = $this->getMock('Magento\Customer\Model\CustomerFactory', ['create'], [], '', false);
         return $this->customerFactory;
     }
+
+    public function testGetType()
+    {
+        $this->assertSame($this->eavConfigType, $this->addressResource->getEntityType());
+    }
 }
diff --git a/app/code/Magento/Customer/composer.json b/app/code/Magento/Customer/composer.json
index 340ab29eca160e1cca6c80f8426ea2ebe66261cb..0e4da26475620658642e2a1582cbe7391c7b2edc 100644
--- a/app/code/Magento/Customer/composer.json
+++ b/app/code/Magento/Customer/composer.json
@@ -3,33 +3,33 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-eav": "0.74.0-beta6",
-        "magento/module-directory": "0.74.0-beta6",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/module-newsletter": "0.74.0-beta6",
-        "magento/module-sales": "0.74.0-beta6",
-        "magento/module-checkout": "0.74.0-beta6",
-        "magento/module-wishlist": "0.74.0-beta6",
-        "magento/module-theme": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-review": "0.74.0-beta6",
-        "magento/module-tax": "0.74.0-beta6",
-        "magento/module-page-cache": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
-        "magento/module-authorization": "0.74.0-beta6",
-        "magento/module-integration": "0.74.0-beta6",
-        "magento/module-media-storage": "0.74.0-beta6",
-        "magento/module-ui": "0.74.0-beta6",
-        "magento/module-config": "0.74.0-beta6",
-        "magento/module-quote": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-eav": "0.74.0-beta7",
+        "magento/module-directory": "0.74.0-beta7",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/module-newsletter": "0.74.0-beta7",
+        "magento/module-sales": "0.74.0-beta7",
+        "magento/module-checkout": "0.74.0-beta7",
+        "magento/module-wishlist": "0.74.0-beta7",
+        "magento/module-theme": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-review": "0.74.0-beta7",
+        "magento/module-tax": "0.74.0-beta7",
+        "magento/module-page-cache": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
+        "magento/module-authorization": "0.74.0-beta7",
+        "magento/module-integration": "0.74.0-beta7",
+        "magento/module-media-storage": "0.74.0-beta7",
+        "magento/module-ui": "0.74.0-beta7",
+        "magento/module-config": "0.74.0-beta7",
+        "magento/module-quote": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "suggest": {
-        "magento/module-cookie": "0.74.0-beta6"
+        "magento/module-cookie": "0.74.0-beta7"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Customer/etc/data_source/customer.xml b/app/code/Magento/Customer/etc/data_source/customer.xml
deleted file mode 100644
index 10fddb904a989f9f5a94fc1af7181458d65fd473..0000000000000000000000000000000000000000
--- a/app/code/Magento/Customer/etc/data_source/customer.xml
+++ /dev/null
@@ -1,62 +0,0 @@
-<?xml version="1.0"?>
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-        xsi:noNamespaceSchemaLocation="../../../../../../app/code/Magento/Ui/etc/data_source.xsd">
-    <dataSource
-            name="account" label="Account Information"
-            dataSet="Magento\Customer\Model\Resource\Customer\Collection">
-        <fields entityType="customer">
-            <field name="entity_id" dataType="text" visible="false"/>
-            <field name="default_billing" source="eav" dataType="boolean" visible="false"/>
-            <field name="default_shipping" source="eav" dataType="boolean" visible="false"/>
-            <field name="website_id" dataType="number" formElement="select" source="eav" label="Associate to Website">
-                <constraints>
-                    <validate name="required-entry"/>
-                </constraints>
-                <tooltip>
-                    <link>http://www.magentocommerce.com/knowledge-base/entry/understanding-store-scopes</link>
-                    <description>If your Magento site has multiple views, you can set the scope to apply to a specific view.</description>
-                </tooltip>
-            </field>
-            <field name="prefix" source="eav" dataType="text"/>
-            <field name="group_id" dataType="number" formElement="select" source="eav" label="Group" fieldGroup="group_id" />
-            <field name="disable_auto_group_change" source="eav" dataType="boolean" formElement="checkbox" fieldGroup="group_id"/>
-            <field name="firstname" source="eav" dataType="text">
-                <constraints>
-                    <validate name="required-entry"/>
-                </constraints>
-            </field>
-            <field name="middlename" source="eav" dataType="text"/>
-            <field name="lastname" source="eav" dataType="text">
-                <constraints>
-                    <validate name="required-entry"/>
-                </constraints>
-            </field>
-            <field name="suffix" source="eav" dataType="text"/>
-            <field name="email" source="eav" formElement="email">
-                <constraints>
-                    <validate name="required-entry"/>
-                    <validate name="validate-email"/>
-                </constraints>
-            </field>
-            <field name="dob" source="eav" dataType="text" label="Date Of Birth" formElement="date"/>
-            <field name="taxvat" source="eav" dataType="text" label="Tax VAT Number"/>
-            <field name="gender" source="eav" dataType="text" formElement="select"/>
-            <field name="sendemail"
-                   dataType="boolean"
-                   formElement="checkbox"
-                   label="Welcome Email"
-                   description="Send a Welcome email "/>
-            <field name="sendemail_store_id"
-                   dataType="number"
-                   formElement="select"
-                   optionProvider="Magento\Store\Model\System\Store::getStoreValuesForForm"
-                   label="Send From"/>
-        </fields>
-    </dataSource>
-</config>
\ No newline at end of file
diff --git a/app/code/Magento/Customer/etc/data_source/customer_address.xml b/app/code/Magento/Customer/etc/data_source/customer_address.xml
deleted file mode 100644
index e3e88b578a12604b97419639750b8317019d0e51..0000000000000000000000000000000000000000
--- a/app/code/Magento/Customer/etc/data_source/customer_address.xml
+++ /dev/null
@@ -1,89 +0,0 @@
-<?xml version="1.0"?>
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-        xsi:noNamespaceSchemaLocation="../../../../../../app/code/Magento/Ui/etc/data_source.xsd">
-    <dataSource name="customer_address"
-                label="Customer Address"
-                dataSet="Magento\Customer\Model\Resource\Address\Collection">
-        <fields entityType="customer_address">
-            <field name="parent_id" dataType="number" visible="false"/>
-            <field name="prefix" source="eav"/>
-            <field name="firstname" source="eav">
-                <constraints>
-                    <validate name="required-entry"/>
-                </constraints>
-            </field>
-            <field name="middlename" source="eav"/>
-            <field name="lastname" source="eav">
-                <constraints>
-                    <validate name="required-entry"/>
-                </constraints>
-            </field>
-            <field name="suffix" source="eav"/>
-            <field name="company" source="eav" label="Company"/>
-            <field name="street" dataType="text" formElement="input" size="2" source="eav">
-                <constraints>
-                    <validate name="required-entry"/>
-                </constraints>
-            </field>
-            <field name="city" source="eav">
-                <constraints>
-                    <validate name="required-entry"/>
-                </constraints>
-            </field>
-            <field name="country_id" source="eav" formElement="select">
-                <constraints>
-                    <validate name="required-entry"/>
-                </constraints>
-            </field>
-            <field name="region_id" source="eav" formElement="select" customEntry="region">
-                <constraints>
-                    <validate name="required-entry"/>
-                    <filter on="{parentScope}.country_id" by="country_id" />
-                </constraints>
-            </field>
-            <field name="region" source="eav" formElement="input" visible="false"/>
-
-            <field name="postcode" source="eav" formElement="post_code" >
-                <constraints>
-                    <validate name="required-entry"/>
-                </constraints>
-            </field>
-
-            <field name="telephone" source="eav" label="Phone Number">
-                <constraints>
-                    <validate name="required-entry"/>
-                </constraints>
-            </field>
-            <field name="fax" source="eav" label="Fax"/>
-            <field name="vat_id" source="eav" label="VAT number"/>
-            <field name="default_billing" source="reference" dataType="boolean" formElement="checkbox"
-                   displayArea="head" description="Default Billing Address" uniqueNs="default_billing" uniqueProp="value">
-                <reference target="account"
-                           referencedField="parent_id"
-                           targetField="entity_id"
-                           neededField="default_billing"
-                        />
-            </field>
-            <field name="default_shipping" source="reference" dataType="boolean" formElement="checkbox"
-                   displayArea="head" description="Default Shipping Address" uniqueNs="default_shipping" uniqueProp="value">
-                <reference target="account"
-                           referencedField="parent_id"
-                           targetField="entity_id"
-                           neededField="default_shipping"
-                        />
-            </field>
-        </fields>
-        <references>
-            <reference target="account"
-                       referencedField="parent_id"
-                       targetField="entity_id"
-                    />
-        </references>
-    </dataSource>
-</config>
diff --git a/app/code/Magento/Customer/etc/data_source/customer_group.xml b/app/code/Magento/Customer/etc/data_source/customer_group.xml
deleted file mode 100644
index 87da4cb4d717c8fc029e1f1331f4a80efffb7963..0000000000000000000000000000000000000000
--- a/app/code/Magento/Customer/etc/data_source/customer_group.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0"?>
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../app/code/Magento/Ui/etc/data_source.xsd">
-    <dataSource name="customer_group" label="Customer Group" dataSet="Magento\Customer\Model\Resource\Group\Collection">
-        <fields>
-            <field name="customer_group_id" dataType="number" visible="false"/>
-            <field name="customer_group_code" dataType="text"/>
-        </fields>
-    </dataSource>
-</config>
\ No newline at end of file
diff --git a/app/code/Magento/Customer/view/adminhtml/layout/customer_form.xml b/app/code/Magento/Customer/view/adminhtml/layout/customer_form.xml
deleted file mode 100644
index 9893992bb265420ff38bc1b3dd18ccdacaa8b9b2..0000000000000000000000000000000000000000
--- a/app/code/Magento/Customer/view/adminhtml/layout/customer_form.xml
+++ /dev/null
@@ -1,72 +0,0 @@
-<?xml version="1.0"?>
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
-    <body>
-        <referenceBlock name="form">
-            <arguments>
-                <argument name="meta" xsi:type="array">
-                    <item name="defaults" xsi:type="array">
-                        <item name="visible" xsi:type="boolean">true</item>
-                    </item>
-                </argument>
-                <argument name="label" xsi:type="string">Customer Information</argument>
-                <argument name="name" xsi:type="string">customer_form</argument>
-                <argument name="data_sources" xsi:type="array">
-                    <item name="customer_info" xsi:type="array">
-                        <item name="name" xsi:type="string">account</item>
-                        <item name="submit_url" xsi:type="url" path="customer/index/save">
-                            <param name="_current">1</param>
-                            <param name="back"></param>
-                        </item>
-                        <item name="validate_url" xsi:type="url" path="customer/index/validate">
-                            <param name="_current">1</param>
-                            <param name="back"></param>
-                        </item>
-                    </item>
-                </argument>
-                <argument name="layout" xsi:type="array">
-                    <item name="type" xsi:type="string">tabs</item>
-                    <item name="configuration" xsi:type="array">
-                        <item name="tabs_container_name" xsi:type="string">left</item>
-                        <item name="areas" xsi:type="array">
-                            <item name="general" xsi:type="array">
-                                <item name="index" xsi:type="string">account_info</item>
-                                <item name="type" xsi:type="string">fieldset</item>
-                                <item name="label" xsi:type="string" translate="true">Customer Info</item>
-                                <item name="collapsible" xsi:type="boolean">true</item>
-                                <item name="ajax" xsi:type="boolean">true</item>
-                            </item>
-                            <item name="customer_address" xsi:type="array">
-                                <item name="index" xsi:type="string">customer_address</item>
-                                <item name="type" xsi:type="string">tab</item>
-                                <item name="label" xsi:type="string" translate="true">Customer Address</item>
-                            </item>
-                        </item>
-                    </item>
-                </argument>
-                <argument name="buttons" xsi:type="array">
-                    <item name="back" xsi:type="string">Magento\Customer\Block\Adminhtml\Edit\BackButton</item>
-                    <item name="delete" xsi:type="string">Magento\Customer\Block\Adminhtml\Edit\DeleteButton</item>
-                    <item name="invalidateToken" xsi:type="string">Magento\Customer\Block\Adminhtml\Edit\InvalidateTokenButton</item>
-                    <item name="resetPassword" xsi:type="string">Magento\Customer\Block\Adminhtml\Edit\ResetPasswordButton</item>
-                    <item name="order" xsi:type="string">Magento\Customer\Block\Adminhtml\Edit\OrderButton</item>
-                    <item name="reset" xsi:type="string">Magento\Customer\Block\Adminhtml\Edit\ResetButton</item>
-                    <item name="save" xsi:type="string">Magento\Customer\Block\Adminhtml\Edit\SaveButton</item>
-                    <item name="save_and_continue" xsi:type="string">Magento\Customer\Block\Adminhtml\Edit\SaveAndContinueButton</item>
-                </argument>
-            </arguments>
-            <block class="Magento\Customer\Block\Adminhtml\Edit\Tab\View" name="customer_edit_tab_view" template="tab/view.phtml">
-                <arguments>
-                    <argument name="tab_label" xsi:type="string">Customer View</argument>
-                    <argument name="sort_order" xsi:type="number">10</argument>
-                </arguments>
-                <block class="Magento\Customer\Block\Adminhtml\Edit\Tab\View\PersonalInfo" name="personal_info" template="tab/view/personal_info.phtml"/>
-            </block>
-        </referenceBlock>
-    </body>
-</page>
diff --git a/app/code/Magento/Customer/view/adminhtml/layout/customer_index_edit.xml b/app/code/Magento/Customer/view/adminhtml/layout/customer_index_edit.xml
index 12fa054b6398b5714ecedc796294822336b22b03..4d3ff76ccb80b348cf0a9bee817580682f7dd61b 100644
--- a/app/code/Magento/Customer/view/adminhtml/layout/customer_index_edit.xml
+++ b/app/code/Magento/Customer/view/adminhtml/layout/customer_index_edit.xml
@@ -5,11 +5,21 @@
  * See COPYING.txt for license details.
  */
 -->
-<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="admin-2columns-left" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
+<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="admin-2columns-left"
+      xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
     <body>
         <referenceContainer name="admin.scope.col.wrap" htmlClass="admin__old" /> <!-- ToDo UI: remove this wrapper with old styles removal. The class name "admin__old" is for tests only, we shouldn't use it in any way -->
         <referenceContainer name="content">
-            <ui_component name="customer_form" component="form" />
+            <referenceBlock name="customer_form">
+                <block class="Magento\Customer\Block\Adminhtml\Edit\Tab\View" name="customer_edit_tab_view" template="tab/view.phtml">
+                    <arguments>
+                        <argument name="tab_label" xsi:type="string">Customer View</argument>
+                        <argument name="sort_order" xsi:type="number">10</argument>
+                    </arguments>
+                    <block class="Magento\Customer\Block\Adminhtml\Edit\Tab\View\PersonalInfo" name="personal_info" template="tab/view/personal_info.phtml"/>
+                </block>
+            </referenceBlock>
+            <uiComponent name="customer_form"/>
         </referenceContainer>
     </body>
 </page>
diff --git a/app/code/Magento/Customer/view/base/ui_component/customer_form.xml b/app/code/Magento/Customer/view/base/ui_component/customer_form.xml
new file mode 100644
index 0000000000000000000000000000000000000000..eb6199714da3274dc2302072d7cf26a60ed2088a
--- /dev/null
+++ b/app/code/Magento/Customer/view/base/ui_component/customer_form.xml
@@ -0,0 +1,553 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Ui/etc/ui_configuration.xsd">
+    <argument name="data" xsi:type="array">
+        <item name="js_config" xsi:type="array">
+            <item name="config" xsi:type="array">
+                <item name="provider" xsi:type="string">customer_form.customer_form_data_source</item>
+            </item>
+            <item name="deps" xsi:type="string">customer_form.customer_form_data_source</item>
+        </item>
+        <item name="label" xsi:type="string" translate="true">Customer Information</item>
+        <item name="layout" xsi:type="array">
+            <item name="type" xsi:type="string">tabs</item>
+            <item name="navContainerName" xsi:type="string">left</item>
+        </item>
+        <item name="buttons" xsi:type="array">
+            <item name="back" xsi:type="string">Magento\Customer\Block\Adminhtml\Edit\BackButton</item>
+            <item name="delete" xsi:type="string">Magento\Customer\Block\Adminhtml\Edit\DeleteButton</item>
+            <item name="invalidateToken" xsi:type="string">Magento\Customer\Block\Adminhtml\Edit\InvalidateTokenButton</item>
+            <item name="resetPassword" xsi:type="string">Magento\Customer\Block\Adminhtml\Edit\ResetPasswordButton</item>
+            <item name="order" xsi:type="string">Magento\Customer\Block\Adminhtml\Edit\OrderButton</item>
+            <item name="reset" xsi:type="string">Magento\Customer\Block\Adminhtml\Edit\ResetButton</item>
+            <item name="save" xsi:type="string">Magento\Customer\Block\Adminhtml\Edit\SaveButton</item>
+            <item name="save_and_continue" xsi:type="string">Magento\Customer\Block\Adminhtml\Edit\SaveAndContinueButton</item>
+        </item>
+    </argument>
+    <dataSource name="customer_form_data_source">
+        <argument name="dataProvider" xsi:type="configurableObject">
+            <argument name="class" xsi:type="string">Magento\Customer\Model\Customer\DataProvider</argument>
+            <argument name="primaryFieldName" xsi:type="string">entity_id</argument>
+            <argument name="requestFieldName" xsi:type="string">id</argument>
+            <argument name="meta" xsi:type="array">
+                <item name="customer" xsi:type="array">
+                    <item name="config" xsi:type="array">
+                        <item name="label" xsi:type="string" translate="true">Account Information</item>
+                    </item>
+                </item>
+                <item name="address" xsi:type="array">
+                    <item name="is_collection" xsi:type="boolean">true</item>
+                    <item name="config" xsi:type="array">
+                        <item name="label" xsi:type="string" translate="true">Addresses</item>
+                    </item>
+                </item>
+            </argument>
+            <argument name="data" xsi:type="array">
+                <item name="js_config" xsi:type="array">
+                    <item name="component" xsi:type="string">Magento_Ui/js/grid/provider</item>
+                </item>
+                <item name="config" xsi:type="array">
+                    <item name="submit_url" xsi:type="string">customer/index/save</item>
+                    <item name="validate_url" xsi:type="string">customer/index/validate</item>
+                </item>
+            </argument>
+        </argument>
+        <argument name="data" xsi:type="array">
+            <item name="js_config" xsi:type="array">
+                <item name="component" xsi:type="string">Magento_Ui/js/form/provider</item>
+            </item>
+        </argument>
+    </dataSource>
+    <fieldset name="customer">
+        <argument name="data" xsi:type="array">
+            <item name="config" xsi:type="array">
+                <item name="label" xsi:type="string" translate="true">Account Information</item>
+            </item>
+        </argument>
+        <field name="entity_id">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="visible" xsi:type="boolean">false</item>
+                    <item name="dataType" xsi:type="string">text</item>
+                    <item name="formElement" xsi:type="string">input</item>
+                    <item name="source" xsi:type="string">customer</item>
+                </item>
+            </argument>
+        </field>
+        <field name="created_in">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="visible" xsi:type="boolean">false</item>
+                    <item name="formElement" xsi:type="string">input</item>
+                    <item name="source" xsi:type="string">customer</item>
+                </item>
+            </argument>
+        </field>
+        <field name="default_billing">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="visible" xsi:type="boolean">false</item>
+                    <item name="dataType" xsi:type="string">boolean</item>
+                    <item name="formElement" xsi:type="string">checkbox</item>
+                    <item name="source" xsi:type="string">customer</item>
+                </item>
+            </argument>
+        </field>
+        <field name="default_shipping">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="visible" xsi:type="boolean">false</item>
+                    <item name="dataType" xsi:type="string">boolean</item>
+                    <item name="formElement" xsi:type="string">checkbox</item>
+                    <item name="source" xsi:type="string">customer</item>
+                </item>
+            </argument>
+        </field>
+        <field name="website_id">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="dataType" xsi:type="string">number</item>
+                    <item name="formElement" xsi:type="string">select</item>
+                    <item name="source" xsi:type="string">customer</item>
+                    <item name="validation" xsi:type="array">
+                        <item name="required-entry" xsi:type="boolean">true</item>
+                    </item>
+                    <item name="tooltip" xsi:type="array">
+                        <item name="link" xsi:type="string">http://www.magentocommerce.com/knowledge-base/entry/understanding-store-scopes</item>
+                        <item name="description" xsi:type="string">If your Magento site has multiple views, you can set the scope to apply to a specific view.</item>
+                    </item>
+                </item>
+            </argument>
+        </field>
+        <field name="prefix">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="visible" xsi:type="boolean">true</item>
+                    <item name="dataType" xsi:type="string">text</item>
+                    <item name="formElement" xsi:type="string">input</item>
+                    <item name="source" xsi:type="string">customer</item>
+                </item>
+            </argument>
+        </field>
+        <container name="container_group">
+            <argument name="data" xsi:type="array">
+                <item name="type" xsi:type="string">group</item>
+                <item name="js_config" xsi:type="array">
+                    <item name="component" xsi:type="string">Magento_Ui/js/form/components/group</item>
+                </item>
+                <item name="config" xsi:type="array">
+                    <item name="label" xsi:type="string" translate="true">Group</item>
+                    <item name="required" xsi:type="boolean">true</item>
+                    <item name="dataScope" xsi:type="boolean">false</item>
+                    <item name="sortOrder" xsi:type="number">20</item>
+                </item>
+            </argument>
+            <field name="group_id">
+                <argument name="data" xsi:type="array">
+                    <item name="config" xsi:type="array">
+                        <item name="fieldGroup" xsi:type="string">group_id</item>
+                        <item name="dataType" xsi:type="string">number</item>
+                        <item name="formElement" xsi:type="string">select</item>
+                        <item name="source" xsi:type="string">customer</item>
+                    </item>
+                </argument>
+            </field>
+            <field name="disable_auto_group_change">
+                <argument name="data" xsi:type="array">
+                    <item name="config" xsi:type="array">
+                        <item name="fieldGroup" xsi:type="string">group_id</item>
+                        <item name="dataType" xsi:type="string">boolean</item>
+                        <item name="formElement" xsi:type="string">checkbox</item>
+                        <item name="source" xsi:type="string">customer</item>
+                    </item>
+                </argument>
+            </field>
+        </container>
+        <field name="firstname">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="dataType" xsi:type="string">text</item>
+                    <item name="formElement" xsi:type="string">input</item>
+                    <item name="source" xsi:type="string">customer</item>
+                    <item name="validation" xsi:type="array">
+                        <item name="required-entry" xsi:type="boolean">true</item>
+                    </item>
+                </item>
+            </argument>
+        </field>
+        <field name="middlename">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="visible" xsi:type="boolean">true</item>
+                    <item name="dataType" xsi:type="string">text</item>
+                    <item name="formElement" xsi:type="string">input</item>
+                    <item name="source" xsi:type="string">customer</item>
+                </item>
+            </argument>
+        </field>
+        <field name="lastname">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="dataType" xsi:type="string">text</item>
+                    <item name="formElement" xsi:type="string">input</item>
+                    <item name="source" xsi:type="string">customer</item>
+                    <item name="validation" xsi:type="array">
+                        <item name="required-entry" xsi:type="boolean">true</item>
+                    </item>
+                </item>
+            </argument>
+        </field>
+        <field name="suffix">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="visible" xsi:type="boolean">true</item>
+                    <item name="dataType" xsi:type="string">text</item>
+                    <item name="formElement" xsi:type="string">input</item>
+                    <item name="source" xsi:type="string">customer</item>
+                </item>
+            </argument>
+        </field>
+        <field name="email">
+            <argument name="data" xsi:type="array">
+                <item name="js_config" xsi:type="array">
+                    <item name="extends" xsi:type="string">input</item>
+                </item>
+                <item name="config" xsi:type="array">
+                    <item name="dataType" xsi:type="string">text</item>
+                    <item name="formElement" xsi:type="string">email</item>
+                    <item name="source" xsi:type="string">customer</item>
+                    <item name="validation" xsi:type="array">
+                        <item name="required-entry" xsi:type="boolean">true</item>
+                        <item name="validate-email" xsi:type="boolean">true</item>
+                    </item>
+                </item>
+            </argument>
+        </field>
+        <field name="dob">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="visible" xsi:type="boolean">true</item>
+                    <item name="dataType" xsi:type="string">text</item>
+                    <item name="formElement" xsi:type="string">date</item>
+                    <item name="source" xsi:type="string">customer</item>
+                    <item name="validation" xsi:type="array">
+                        <item name="validate-date" xsi:type="boolean">true</item>
+                    </item>
+                </item>
+            </argument>
+        </field>
+        <field name="taxvat">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="visible" xsi:type="boolean">true</item>
+                    <item name="dataType" xsi:type="string">text</item>
+                    <item name="formElement" xsi:type="string">input</item>
+                    <item name="source" xsi:type="string">customer</item>
+                </item>
+            </argument>
+        </field>
+        <field name="gender">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="visible" xsi:type="boolean">true</item>
+                    <item name="dataType" xsi:type="string">text</item>
+                    <item name="formElement" xsi:type="string">select</item>
+                    <item name="source" xsi:type="string">customer</item>
+                </item>
+            </argument>
+        </field>
+        <field name="sendemail_store_id">
+            <argument name="data" xsi:type="array">
+                <item name="options" xsi:type="object">Magento\Store\Model\System\Store</item>
+                <item name="config" xsi:type="array">
+                    <item name="label" xsi:type="string">Send From</item>
+                    <item name="dataType" xsi:type="string">number</item>
+                    <item name="formElement" xsi:type="string">select</item>
+                </item>
+            </argument>
+        </field>
+        <field name="sendemail">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="label" xsi:type="string">Welcome Email</item>
+                    <item name="description" xsi:type="string">Send a Welcome email</item>
+                    <item name="dataType" xsi:type="string">boolean</item>
+                    <item name="formElement" xsi:type="string">checkbox</item>
+                </item>
+            </argument>
+        </field>
+    </fieldset>
+    <fieldset name="address">
+        <argument name="data" xsi:type="array">
+            <item name="config" xsi:type="array">
+                <item name="is_collection" xsi:type="boolean">true</item>
+                <item name="label" xsi:type="string" translate="true">Addresses</item>
+                <item name="removeMessage" xsi:type="string" translate="true">Are you sure you want to delete this item?</item>
+            </item>
+        </argument>
+        <field name="parent_id">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="visible" xsi:type="boolean">false</item>
+                    <item name="dataType" xsi:type="string">number</item>
+                    <item name="formElement" xsi:type="string">input</item>
+                    <item name="source" xsi:type="string">address</item>
+                </item>
+            </argument>
+        </field>
+        <field name="prefix">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="visible" xsi:type="boolean">true</item>
+                    <item name="dataType" xsi:type="string">text</item>
+                    <item name="formElement" xsi:type="string">input</item>
+                    <item name="source" xsi:type="string">address</item>
+                </item>
+            </argument>
+        </field>
+        <field name="firstname">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="source" xsi:type="string">address</item>
+                    <item name="dataType" xsi:type="string">text</item>
+                    <item name="formElement" xsi:type="string">input</item>
+                    <item name="validation" xsi:type="array">
+                        <item name="required-entry" xsi:type="boolean">true</item>
+                    </item>
+                </item>
+            </argument>
+        </field>
+        <field name="middlename">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="visible" xsi:type="boolean">true</item>
+                    <item name="dataType" xsi:type="string">text</item>
+                    <item name="formElement" xsi:type="string">input</item>
+                    <item name="source" xsi:type="string">address</item>
+                </item>
+            </argument>
+        </field>
+        <field name="lastname">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="dataType" xsi:type="string">text</item>
+                    <item name="formElement" xsi:type="string">input</item>
+                    <item name="source" xsi:type="string">address</item>
+                    <item name="validation" xsi:type="array">
+                        <item name="required-entry" xsi:type="boolean">true</item>
+                    </item>
+                </item>
+            </argument>
+        </field>
+        <field name="suffix">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="visible" xsi:type="boolean">true</item>
+                    <item name="dataType" xsi:type="string">text</item>
+                    <item name="formElement" xsi:type="string">input</item>
+                    <item name="source" xsi:type="string">address</item>
+                    <item name="sortOrder" xsi:type="string">43</item>
+                </item>
+            </argument>
+        </field>
+        <field name="company">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="dataType" xsi:type="string">text</item>
+                    <item name="formElement" xsi:type="string">input</item>
+                    <item name="source" xsi:type="string">address</item>
+                    <item name="sortOrder" xsi:type="string">44</item>
+                    <item name="validation" xsi:type="array">
+                        <item name="min_text_length" xsi:type="number">0</item>
+                    </item>
+                </item>
+            </argument>
+        </field>
+        <container name="street_container">
+            <argument name="data" xsi:type="array">
+                <item name="type" xsi:type="string">group</item>
+                <item name="js_config" xsi:type="array">
+                    <item name="component" xsi:type="string">Magento_Ui/js/form/components/group</item>
+                </item>
+                <item name="config" xsi:type="array">
+                    <item name="label" xsi:type="string" translate="true">Street Address</item>
+                    <item name="required" xsi:type="boolean">true</item>
+                    <item name="dataScope" xsi:type="string">street</item>
+                    <item name="sortOrder" xsi:type="string">45</item>
+                </item>
+            </argument>
+            <field name="street">
+                <argument name="data" xsi:type="array">
+                    <item name="config" xsi:type="array">
+                        <item name="dataScope" xsi:type="string">0</item>
+                        <item name="dataType" xsi:type="string">text</item>
+                        <item name="formElement" xsi:type="string">input</item>
+                        <item name="source" xsi:type="string">address</item>
+                        <item name="validation" xsi:type="array">
+                            <item name="required-entry" xsi:type="boolean">true</item>
+                        </item>
+                    </item>
+                </argument>
+            </field>
+            <field name="street_second">
+                <argument name="data" xsi:type="array">
+                    <item name="config" xsi:type="array">
+                        <item name="dataScope" xsi:type="string">1</item>
+                        <item name="dataType" xsi:type="string">text</item>
+                        <item name="formElement" xsi:type="string">input</item>
+                        <item name="source" xsi:type="string">address</item>
+                    </item>
+                </argument>
+            </field>
+        </container>
+        <field name="city">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="dataType" xsi:type="string">text</item>
+                    <item name="formElement" xsi:type="string">input</item>
+                    <item name="source" xsi:type="string">address</item>
+                    <item name="validation" xsi:type="array">
+                        <item name="required-entry" xsi:type="boolean">true</item>
+                    </item>
+                </item>
+            </argument>
+        </field>
+        <field name="country_id">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="dataType" xsi:type="string">text</item>
+                    <item name="formElement" xsi:type="string">select</item>
+                    <item name="source" xsi:type="string">address</item>
+                    <item name="validation" xsi:type="array">
+                        <item name="required-entry" xsi:type="boolean">true</item>
+                    </item>
+                </item>
+            </argument>
+        </field>
+        <field name="country_id">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="dataType" xsi:type="string">text</item>
+                    <item name="formElement" xsi:type="string">select</item>
+                    <item name="source" xsi:type="string">address</item>
+                    <item name="validation" xsi:type="array">
+                        <item name="required-entry" xsi:type="boolean">true</item>
+                    </item>
+                </item>
+            </argument>
+        </field>
+        <field name="region">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="visible" xsi:type="boolean">false</item>
+                    <item name="dataType" xsi:type="string">text</item>
+                    <item name="formElement" xsi:type="string">input</item>
+                    <item name="source" xsi:type="string">address</item>
+                </item>
+            </argument>
+        </field>
+        <field name="region_id">
+            <argument name="data" xsi:type="array">
+                <item name="customEntry" xsi:type="string">region</item>
+                <item name="config" xsi:type="array">
+                    <item name="dataType" xsi:type="string">text</item>
+                    <item name="formElement" xsi:type="string">select</item>
+                    <item name="source" xsi:type="string">address</item>
+                    <item name="customEntry" xsi:type="string">region</item>
+                    <item name="validation" xsi:type="array">
+                        <item name="required-entry" xsi:type="boolean">true</item>
+                    </item>
+                    <item name="filterBy" xsi:type="array">
+                        <item name="target" xsi:type="string"><![CDATA[<%= provider %>:<%= parentScope %>.country_id]]></item>
+                        <item name="field" xsi:type="string">country_id</item>
+                    </item>
+                </item>
+            </argument>
+        </field>
+        <field name="postcode">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="dataType" xsi:type="string">text</item>
+                    <item name="component" xsi:type="string">Magento_Ui/js/form/element/post-code</item>
+                    <item name="formElement" xsi:type="string">input</item>
+                    <item name="source" xsi:type="string">address</item>
+                    <item name="validation" xsi:type="array">
+                        <item name="required-entry" xsi:type="boolean">true</item>
+                    </item>
+                </item>
+            </argument>
+        </field>
+        <field name="telephone">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="dataType" xsi:type="string">text</item>
+                    <item name="formElement" xsi:type="string">input</item>
+                    <item name="source" xsi:type="string">address</item>
+                    <item name="validation" xsi:type="array">
+                        <item name="required-entry" xsi:type="boolean">true</item>
+                    </item>
+                </item>
+            </argument>
+        </field>
+        <field name="fax">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="dataType" xsi:type="string">text</item>
+                    <item name="formElement" xsi:type="string">input</item>
+                    <item name="source" xsi:type="string">address</item>
+                    <item name="validation" xsi:type="array">
+                        <item name="min_text_length" xsi:type="number">0</item>
+                    </item>
+                </item>
+            </argument>
+        </field>
+        <field name="vat_id">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="dataType" xsi:type="string">text</item>
+                    <item name="formElement" xsi:type="string">input</item>
+                    <item name="source" xsi:type="string">address</item>
+                </item>
+            </argument>
+        </field>
+        <field name="default_billing">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="dataType" xsi:type="string">boolean</item>
+                    <item name="formElement" xsi:type="string">checkbox</item>
+                    <item name="displayArea" xsi:type="string">head</item>
+                    <item name="uniqueNs" xsi:type="string">default_billing</item>
+                    <item name="uniqueProp" xsi:type="string">value</item>
+                    <item name="description" xsi:type="string" translate="true">Default Billing Address</item>
+                    <item name="source" xsi:type="array">
+                        <item name="target" xsi:type="string">customer</item>
+                        <item name="targetField" xsi:type="string">default_billing</item>
+                        <item name="referencedField" xsi:type="string">entity_id</item>
+                    </item>
+                </item>
+            </argument>
+        </field>
+        <field name="default_shipping">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="dataType" xsi:type="string">boolean</item>
+                    <item name="formElement" xsi:type="string">checkbox</item>
+                    <item name="displayArea" xsi:type="string">head</item>
+                    <item name="uniqueNs" xsi:type="string">default_shipping</item>
+                    <item name="uniqueProp" xsi:type="string">value</item>
+                    <item name="description" xsi:type="string" translate="true">Default Shipping Address</item>
+                    <item name="source" xsi:type="array">
+                        <item name="target" xsi:type="string">customer</item>
+                        <item name="targetField" xsi:type="string">default_shipping</item>
+                        <item name="referencedField" xsi:type="string">entity_id</item>
+                    </item>
+                </item>
+            </argument>
+        </field>
+    </fieldset>
+</form>
diff --git a/app/code/Magento/CustomerImportExport/composer.json b/app/code/Magento/CustomerImportExport/composer.json
index 3635354b9f3c6e0593281f1465051226cfc8c355..1541d6e931b963ebbe66888254d08f6022586430 100644
--- a/app/code/Magento/CustomerImportExport/composer.json
+++ b/app/code/Magento/CustomerImportExport/composer.json
@@ -3,17 +3,17 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-customer": "0.74.0-beta6",
-        "magento/module-eav": "0.74.0-beta6",
-        "magento/module-import-export": "0.74.0-beta6",
-        "magento/module-directory": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-customer": "0.74.0-beta7",
+        "magento/module-eav": "0.74.0-beta7",
+        "magento/module-import-export": "0.74.0-beta7",
+        "magento/module-directory": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/DesignEditor/Model/Url/NavigationMode.php b/app/code/Magento/DesignEditor/Model/Url/NavigationMode.php
index af413fcd477b0b044e36d1bc9ed4bfc3c6637eb5..cb54368e519392d63b842cd6227cce1644e51c7d 100644
--- a/app/code/Magento/DesignEditor/Model/Url/NavigationMode.php
+++ b/app/code/Magento/DesignEditor/Model/Url/NavigationMode.php
@@ -38,7 +38,7 @@ class NavigationMode extends \Magento\Framework\Url
      * @param \Magento\Framework\Url\ScopeResolverInterface $scopeResolver
      * @param \Magento\Framework\Session\Generic $session
      * @param \Magento\Framework\Session\SidResolverInterface $sidResolver
-     * @param \Magento\Framework\Url\RouteParamsResolverFactory $routeParamsResolver
+     * @param \Magento\Framework\Url\RouteParamsResolverFactory $routeParamsResolverFactory
      * @param \Magento\Framework\Url\QueryParamsResolverInterface $queryParamsResolver
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param string $scopeType
@@ -53,7 +53,7 @@ class NavigationMode extends \Magento\Framework\Url
         \Magento\Framework\Url\ScopeResolverInterface $scopeResolver,
         \Magento\Framework\Session\Generic $session,
         \Magento\Framework\Session\SidResolverInterface $sidResolver,
-        \Magento\Framework\Url\RouteParamsResolverFactory $routeParamsResolver,
+        \Magento\Framework\Url\RouteParamsResolverFactory $routeParamsResolverFactory,
         \Magento\Framework\Url\QueryParamsResolverInterface $queryParamsResolver,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         $scopeType,
@@ -75,7 +75,7 @@ class NavigationMode extends \Magento\Framework\Url
             $scopeResolver,
             $session,
             $sidResolver,
-            $routeParamsResolver,
+            $routeParamsResolverFactory,
             $queryParamsResolver,
             $scopeConfig,
             $scopeType,
diff --git a/app/code/Magento/DesignEditor/Test/Unit/Model/Url/NavigationModeTest.php b/app/code/Magento/DesignEditor/Test/Unit/Model/Url/NavigationModeTest.php
index e6de82bcf54ee3798e263bafb0d3a5f77c5e1435..e4ee8ff76365954f2ec2b404f72515d4c2cc3249 100644
--- a/app/code/Magento/DesignEditor/Test/Unit/Model/Url/NavigationModeTest.php
+++ b/app/code/Magento/DesignEditor/Test/Unit/Model/Url/NavigationModeTest.php
@@ -90,7 +90,7 @@ class NavigationModeTest extends \PHPUnit_Framework_TestCase
             [
                 'helper' => $this->_designHelperMock,
                 'data' => $this->_testData,
-                'routeParamsResolver' => $this->_routeParamsMock,
+                'routeParamsResolverFactory' => $this->_routeParamsMock,
                 'scopeResolver' => $this->_scopeResolverMock
             ]
         );
diff --git a/app/code/Magento/DesignEditor/composer.json b/app/code/Magento/DesignEditor/composer.json
index 7a24e23445b99be4268f881b05eff8013e9553da..f9d3156293edff7b668fddde96bc2c1b26871f33 100644
--- a/app/code/Magento/DesignEditor/composer.json
+++ b/app/code/Magento/DesignEditor/composer.json
@@ -3,18 +3,18 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-theme": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-eav": "0.74.0-beta6",
-        "magento/module-translation": "0.74.0-beta6",
-        "magento/module-config": "0.74.0-beta6",
-        "magento/module-media-storage": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-theme": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-eav": "0.74.0-beta7",
+        "magento/module-translation": "0.74.0-beta7",
+        "magento/module-config": "0.74.0-beta7",
+        "magento/module-media-storage": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Developer/composer.json b/app/code/Magento/Developer/composer.json
index 2acb479e5e7da4b25ea3e78b4269be86c45fa06c..dfe90bb1778175658e44a84c52ce21fc9243573a 100644
--- a/app/code/Magento/Developer/composer.json
+++ b/app/code/Magento/Developer/composer.json
@@ -3,12 +3,12 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Developer/etc/adminhtml/system.xml b/app/code/Magento/Developer/etc/adminhtml/system.xml
index f858f6b51bc275787d5b476b42a1a3f62277ec11..13ec5c3a13106fc5820440bb0b7754e6404a5074 100644
--- a/app/code/Magento/Developer/etc/adminhtml/system.xml
+++ b/app/code/Magento/Developer/etc/adminhtml/system.xml
@@ -9,7 +9,7 @@
         <section id="dev" translate="label">
             <group id="front_end_development_workflow" translate="label" type="text" sortOrder="8" showInDefault="1" showInWebsite="1" showInStore="1">
                 <label>Front-end development workflow</label>
-                <field id="type" translate="label comment" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
+                <field id="type" translate="label comment" type="select" sortOrder="1" showInDefault="1" showInWebsite="0" showInStore="0">
                     <label>Workflow type</label>
                     <comment>Not available in production mode</comment>
                     <source_model>Magento\Developer\Model\Config\Source\WorkflowType</source_model>
diff --git a/app/code/Magento/Dhl/composer.json b/app/code/Magento/Dhl/composer.json
index 9523a52d2f19d36247e9a99814c24cf43e8ee2a5..41241d5133de99d58082d16c854e2adb73acab39 100644
--- a/app/code/Magento/Dhl/composer.json
+++ b/app/code/Magento/Dhl/composer.json
@@ -3,22 +3,22 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-config": "0.74.0-beta6",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-shipping": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-directory": "0.74.0-beta6",
-        "magento/module-sales": "0.74.0-beta6",
-        "magento/module-checkout": "0.74.0-beta6",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/module-catalog-inventory": "0.74.0-beta6",
-        "magento/module-quote": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-config": "0.74.0-beta7",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-shipping": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-directory": "0.74.0-beta7",
+        "magento/module-sales": "0.74.0-beta7",
+        "magento/module-checkout": "0.74.0-beta7",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/module-catalog-inventory": "0.74.0-beta7",
+        "magento/module-quote": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "lib-libxml": "*",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Directory/Model/Currency.php b/app/code/Magento/Directory/Model/Currency.php
index 9e7d2b9abef186b2f221c94c7ef61007534c81eb..31ab3bf266dd24b8fb1b657731f5b8bcf2c1bda4 100644
--- a/app/code/Magento/Directory/Model/Currency.php
+++ b/app/code/Magento/Directory/Model/Currency.php
@@ -311,6 +311,16 @@ class Currency extends \Magento\Framework\Model\AbstractModel
         return $this->_localeCurrency->getCurrency($this->getCode())->toCurrency($price, $options);
     }
 
+    /**
+     * Return currency symbol for current locale and currency code
+     *
+     * @return string
+     */
+    public function getCurrencySymbol()
+    {
+        return $this->_localeCurrency->getCurrency($this->getCode())->getSymbol();
+    }
+
     /**
      * @return string
      */
diff --git a/app/code/Magento/Directory/Model/PriceCurrency.php b/app/code/Magento/Directory/Model/PriceCurrency.php
index 3aa697742a41687cf66d0e78517afd3549aaac1c..9cf7dabd2de746d5193abe8bbf7b1c1f5662e550 100644
--- a/app/code/Magento/Directory/Model/PriceCurrency.php
+++ b/app/code/Magento/Directory/Model/PriceCurrency.php
@@ -117,6 +117,16 @@ class PriceCurrency implements \Magento\Framework\Pricing\PriceCurrencyInterface
         return $currentCurrency;
     }
 
+    /**
+     * @param null|string|bool|int|\Magento\Framework\App\ScopeInterface $scope
+     * @param \Magento\Framework\Model\AbstractModel|string|null $currency
+     * @return string
+     */
+    public function getCurrencySymbol($scope = null, $currency = null)
+    {
+        return $this->getCurrency($scope, $currency)->getCurrencySymbol();
+    }
+
     /**
      * Get store model
      *
diff --git a/app/code/Magento/Directory/Test/Unit/Model/CurrencyTest.php b/app/code/Magento/Directory/Test/Unit/Model/CurrencyTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..33a312880adc33b16f3c0f2327573b2f08d1ae32
--- /dev/null
+++ b/app/code/Magento/Directory/Test/Unit/Model/CurrencyTest.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Directory\Test\Unit\Model;
+
+use Magento\Directory\Model\Currency;
+
+class CurrencyTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Currency
+     */
+    protected $currency;
+
+    protected $currencyCode = 'USD';
+
+    /**
+     * @var \Magento\Framework\Locale\CurrencyInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $localeCurrencyMock;
+
+    public function setUp()
+    {
+        $this->localeCurrencyMock = $this->getMock('\Magento\Framework\Locale\CurrencyInterface');
+
+        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $this->currency = $objectManager->getObject('Magento\Directory\Model\Currency', [
+            'localeCurrency' => $this->localeCurrencyMock,
+            'data' => [
+                'currency_code' => $this->currencyCode,
+            ]
+        ]);
+    }
+
+    public function testGetCurrencySymbol()
+    {
+        $currencySymbol = '$';
+
+        $currencyMock = $this->getMockBuilder('\Magento\Framework\Currency')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $currencyMock->expects($this->once())
+            ->method('getSymbol')
+            ->willReturn($currencySymbol);
+
+        $this->localeCurrencyMock->expects($this->once())
+            ->method('getCurrency')
+            ->with($this->currencyCode)
+            ->willReturn($currencyMock);
+        $this->assertEquals($currencySymbol, $this->currency->getCurrencySymbol());
+    }
+}
diff --git a/app/code/Magento/Directory/Test/Unit/Model/PriceCurrencyTest.php b/app/code/Magento/Directory/Test/Unit/Model/PriceCurrencyTest.php
index 205a63e7b0c33f3ffaa312cf9256ee2607f4aab8..b934435151a040f0f7156c532aecdb85f313e6e8 100644
--- a/app/code/Magento/Directory/Test/Unit/Model/PriceCurrencyTest.php
+++ b/app/code/Magento/Directory/Test/Unit/Model/PriceCurrencyTest.php
@@ -168,6 +168,18 @@ class PriceCurrencyTest extends \PHPUnit_Framework_TestCase
         ));
     }
 
+    public function testGetCurrencySymbol()
+    {
+        $storeId = 2;
+        $currencySymbol = '$';
+
+        $currencyMock = $this->getCurrentCurrencyMock();
+        $currencyMock->expects($this->once())
+            ->method('getCurrencySymbol')
+            ->willReturn($currencySymbol);
+        $this->assertEquals($currencySymbol, $this->priceCurrency->getCurrencySymbol($storeId, $currencyMock));
+    }
+
     protected function getCurrentCurrencyMock()
     {
         $currency = $this->getMockBuilder('Magento\Directory\Model\Currency')
diff --git a/app/code/Magento/Directory/composer.json b/app/code/Magento/Directory/composer.json
index bc25eea4a4f6717ae53a92714ecf462bfa6f0e6d..610a919710b954d481569fce81e506a5b41f00ab 100644
--- a/app/code/Magento/Directory/composer.json
+++ b/app/code/Magento/Directory/composer.json
@@ -3,15 +3,15 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-config": "0.74.0-beta6",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-config": "0.74.0-beta7",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "lib-libxml": "*",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Downloadable/Api/Data/LinkContentInterface.php b/app/code/Magento/Downloadable/Api/Data/LinkContentInterface.php
deleted file mode 100644
index 1972068f435512611b3d564f875ec666f6d20b56..0000000000000000000000000000000000000000
--- a/app/code/Magento/Downloadable/Api/Data/LinkContentInterface.php
+++ /dev/null
@@ -1,194 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Downloadable\Api\Data;
-
-/**
- * @codeCoverageIgnore
- */
-interface LinkContentInterface extends \Magento\Framework\Api\ExtensibleDataInterface
-{
-    /**
-     * Retrieve sample title
-     *
-     * @return string
-     */
-    public function getTitle();
-
-    /**
-     * Set sample title
-     *
-     * @param string $title
-     * @return $this
-     */
-    public function setTitle($title);
-
-    /**
-     * Retrieve sample sort order
-     *
-     * @return int
-     */
-    public function getSortOrder();
-
-    /**
-     * Set sample sort order
-     *
-     * @param int $sortOrder
-     * @return $this
-     */
-    public function setSortOrder($sortOrder);
-
-    /**
-     * Retrieve link price
-     *
-     * @return string
-     */
-    public function getPrice();
-
-    /**
-     * Set link price
-     *
-     * @param string $price
-     * @return $this
-     */
-    public function setPrice($price);
-
-    /**
-     * Retrieve number of allowed downloads of the link
-     *
-     * @return int
-     */
-    public function getNumberOfDownloads();
-
-    /**
-     * Set number of allowed downloads of the link
-     *
-     * @param int $numberOfDownloads
-     * @return $this
-     */
-    public function setNumberOfDownloads($numberOfDownloads);
-
-    /**
-     * Check if link is shareable
-     *
-     * @return bool
-     */
-    public function isShareable();
-
-    /**
-     * Set whether link is shareable
-     *
-     * @param bool $shareable
-     * @return $this
-     */
-    public function setShareable($shareable);
-
-    /**
-     * Retrieve link file content
-     *
-     * @return \Magento\Downloadable\Api\Data\File\ContentInterface|null
-     */
-    public function getLinkFile();
-
-    /**
-     * Set link file content
-     *
-     * @param \Magento\Downloadable\Api\Data\File\ContentInterface $linkFile
-     * @return $this
-     */
-    public function setLinkFile(\Magento\Downloadable\Api\Data\File\ContentInterface $linkFile = null);
-
-    /**
-     * Retrieve link URL
-     *
-     * @return string|null
-     */
-    public function getLinkUrl();
-
-    /**
-     * Set link URL
-     *
-     * @param string $linkUrl
-     * @return $this
-     */
-    public function setLinkUrl($linkUrl);
-
-    /**
-     * Retrieve link type ('url' or 'file')
-     *
-     * @return string|null
-     */
-    public function getLinkType();
-
-    /**
-     * Set link type ('url' or 'file')
-     *
-     * @param string $linkType
-     * @return $this
-     */
-    public function setLinkType($linkType);
-
-    /**
-     * Retrieve sample file content
-     *
-     * @return \Magento\Downloadable\Api\Data\File\ContentInterface|null
-     */
-    public function getSampleFile();
-
-    /**
-     * Retrieve sample file content
-     *
-     * @param \Magento\Downloadable\Api\Data\File\ContentInterface $sampleFile
-     * @return $this
-     */
-    public function setSampleFile(\Magento\Downloadable\Api\Data\File\ContentInterface $sampleFile = null);
-
-    /**
-     * Retrieve sample URL
-     *
-     * @return string|null
-     */
-    public function getSampleUrl();
-
-    /**
-     * Set sample URL
-     *
-     * @param string $sampleUrl
-     * @return $this
-     */
-    public function setSampleUrl($sampleUrl);
-
-    /**
-     * Retrieve sample type ('url' or 'file')
-     *
-     * @return string|null
-     */
-    public function getSampleType();
-
-    /**
-     * Set sample type ('url' or 'file')
-     *
-     * @param string $sampleType
-     * @return $this
-     */
-    public function setSampleType($sampleType);
-
-    /**
-     * Retrieve existing extension attributes object or create a new one.
-     *
-     * @return \Magento\Downloadable\Api\Data\LinkContentExtensionInterface|null
-     */
-    public function getExtensionAttributes();
-
-    /**
-     * Set an extension attributes object.
-     *
-     * @param \Magento\Downloadable\Api\Data\LinkContentExtensionInterface $extensionAttributes
-     * @return $this
-     */
-    public function setExtensionAttributes(
-        \Magento\Downloadable\Api\Data\LinkContentExtensionInterface $extensionAttributes
-    );
-}
diff --git a/app/code/Magento/Downloadable/Api/Data/LinkInterface.php b/app/code/Magento/Downloadable/Api/Data/LinkInterface.php
index 0152a1a256540db9b0cab423e2804bd906475245..6fe62e070349e96c265a7d6d5e32da64de0eb976 100644
--- a/app/code/Magento/Downloadable/Api/Data/LinkInterface.php
+++ b/app/code/Magento/Downloadable/Api/Data/LinkInterface.php
@@ -119,9 +119,24 @@ interface LinkInterface extends \Magento\Framework\Api\ExtensibleDataInterface
     public function setLinkFile($linkFile);
 
     /**
-     * Return URL or NULL when type is 'file'
+     * Return file content
      *
-     * @return string|null file URL
+     * @return \Magento\Downloadable\Api\Data\File\ContentInterface|null
+     */
+    public function getLinkFileContent();
+
+    /**
+     * Set file content
+     *
+     * @param \Magento\Downloadable\Api\Data\File\ContentInterface $linkFileContent
+     * @return $this
+     */
+    public function setLinkFileContent(\Magento\Downloadable\Api\Data\File\ContentInterface $linkFileContent = null);
+
+    /**
+     * Return link url or null when type is 'file'
+     *
+     * @return string|null
      */
     public function getLinkUrl();
 
@@ -159,6 +174,23 @@ interface LinkInterface extends \Magento\Framework\Api\ExtensibleDataInterface
      */
     public function setSampleFile($sampleFile);
 
+    /**
+     * Return sample file content when type is 'file'
+     *
+     * @return \Magento\Downloadable\Api\Data\File\ContentInterface|null relative file path
+     */
+    public function getSampleFileContent();
+
+    /**
+     * Set sample file content
+     *
+     * @param \Magento\Downloadable\Api\Data\File\ContentInterface $sampleFileContent
+     * @return $this
+     */
+    public function setSampleFileContent(
+        \Magento\Downloadable\Api\Data\File\ContentInterface $sampleFileContent = null
+    );
+
     /**
      * Return URL or NULL when type is 'file'
      *
diff --git a/app/code/Magento/Downloadable/Api/Data/SampleContentInterface.php b/app/code/Magento/Downloadable/Api/Data/SampleContentInterface.php
deleted file mode 100644
index b4b0580bda1879b6aa75ab70371f6c522b7d1100..0000000000000000000000000000000000000000
--- a/app/code/Magento/Downloadable/Api/Data/SampleContentInterface.php
+++ /dev/null
@@ -1,104 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Downloadable\Api\Data;
-
-/**
- * @codeCoverageIgnore
- */
-interface SampleContentInterface extends \Magento\Framework\Api\ExtensibleDataInterface
-{
-    /**
-     * Retrieve sample title
-     *
-     * @return string
-     */
-    public function getTitle();
-
-    /**
-     * Set sample title
-     *
-     * @param string $title
-     * @return $this
-     */
-    public function setTitle($title);
-
-    /**
-     * Retrieve sample type ('url' or 'file')
-     *
-     * @return string|null
-     */
-    public function getSampleType();
-
-    /**
-     * Set sample type ('url' or 'file')
-     *
-     * @param string $sampleType
-     * @return $this
-     */
-    public function setSampleType($sampleType);
-
-    /**
-     * Retrieve sample file content
-     *
-     * @return \Magento\Downloadable\Api\Data\File\ContentInterface|null
-     */
-    public function getSampleFile();
-
-    /**
-     * Set sample file content
-     *
-     * @param \Magento\Downloadable\Api\Data\File\ContentInterface $sampleFile
-     * @return $this
-     */
-    public function setSampleFile(\Magento\Downloadable\Api\Data\File\ContentInterface $sampleFile = null);
-
-    /**
-     * Retrieve sample sort order
-     *
-     * @return int
-     */
-    public function getSortOrder();
-
-    /**
-     * Set sample sort order
-     *
-     * @param int $sortOrder
-     * @return $this
-     */
-    public function setSortOrder($sortOrder);
-
-    /**
-     * Retrieve sample URL
-     *
-     * @return string|null
-     */
-    public function getSampleUrl();
-
-    /**
-     * Set sample URL
-     *
-     * @param string $sampleUrl
-     * @return $this
-     */
-    public function setSampleUrl($sampleUrl);
-
-    /**
-     * Retrieve existing extension attributes object or create a new one.
-     *
-     * @return \Magento\Downloadable\Api\Data\SampleContentExtensionInterface|null
-     */
-    public function getExtensionAttributes();
-
-    /**
-     * Set an extension attributes object.
-     *
-     * @param \Magento\Downloadable\Api\Data\SampleContentExtensionInterface $extensionAttributes
-     * @return $this
-     */
-    public function setExtensionAttributes(
-        \Magento\Downloadable\Api\Data\SampleContentExtensionInterface $extensionAttributes
-    );
-}
diff --git a/app/code/Magento/Downloadable/Api/Data/SampleInterface.php b/app/code/Magento/Downloadable/Api/Data/SampleInterface.php
index 3d6dfc937f3871a4a489e43c1f1912c5a7498082..8e30bf6f0e1ea0f3fc8bcf78b4261696e6119106 100644
--- a/app/code/Magento/Downloadable/Api/Data/SampleInterface.php
+++ b/app/code/Magento/Downloadable/Api/Data/SampleInterface.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\Downloadable\Api\Data;
 
+use \Magento\Downloadable\Api\Data\File\ContentInterface;
+
 /**
  * @codeCoverageIgnore
  */
@@ -82,6 +84,21 @@ interface SampleInterface extends \Magento\Framework\Api\ExtensibleDataInterface
      */
     public function setSampleFile($sampleFile);
 
+    /**
+     * Retrieve sample file content
+     *
+     * @return \Magento\Downloadable\Api\Data\File\ContentInterface|null
+     */
+    public function getSampleFileContent();
+
+    /**
+     * Set sample file content
+     *
+     * @param \Magento\Downloadable\Api\Data\File\ContentInterface $sampleFileContent
+     * @return $this
+     */
+    public function setSampleFileContent(ContentInterface $sampleFileContent = null);
+
     /**
      * Return URL or NULL when type is 'file'
      *
diff --git a/app/code/Magento/Downloadable/Api/LinkRepositoryInterface.php b/app/code/Magento/Downloadable/Api/LinkRepositoryInterface.php
index a8bd6f83d9be190834e0e92d34c039010a4d870c..3a0d8053e4f8d599af652e83d830ad6c7ead7b65 100644
--- a/app/code/Magento/Downloadable/Api/LinkRepositoryInterface.php
+++ b/app/code/Magento/Downloadable/Api/LinkRepositoryInterface.php
@@ -5,7 +5,7 @@
  */
 namespace Magento\Downloadable\Api;
 
-use Magento\Downloadable\Api\Data\LinkContentInterface;
+use Magento\Downloadable\Api\Data\LinkInterface;
 
 interface LinkRepositoryInterface
 {
@@ -17,6 +17,14 @@ interface LinkRepositoryInterface
      */
     public function getSamples($sku);
 
+    /**
+     * List of samples for downloadable product
+     *
+     * @param \Magento\Catalog\Api\Data\ProductInterface $product
+     * @return \Magento\Downloadable\Api\Data\SampleInterface[]
+     */
+    public function getSamplesByProduct(\Magento\Catalog\Api\Data\ProductInterface $product);
+
     /**
      * List of links with associated samples
      *
@@ -25,22 +33,29 @@ interface LinkRepositoryInterface
      */
     public function getLinks($sku);
 
+    /**
+     * List of links with associated samples
+     *
+     * @param \Magento\Catalog\Api\Data\ProductInterface $product
+     * @return \Magento\Downloadable\Api\Data\LinkInterface[]
+     */
+    public function getLinksByProduct(\Magento\Catalog\Api\Data\ProductInterface $product);
+
     /**
      * Update downloadable link of the given product (link type and its resources cannot be changed)
      *
      * @param string $sku
-     * @param \Magento\Downloadable\Api\Data\LinkContentInterface $linkContent
-     * @param int $linkId
+     * @param \Magento\Downloadable\Api\Data\LinkInterface $link
      * @param bool $isGlobalScopeContent
      * @return int
      */
-    public function save($sku, LinkContentInterface $linkContent, $linkId = null, $isGlobalScopeContent = false);
+    public function save($sku, LinkInterface $link, $isGlobalScopeContent = false);
 
     /**
      * Delete downloadable link
      *
-     * @param int $linkId
+     * @param int $id
      * @return bool
      */
-    public function delete($linkId);
+    public function delete($id);
 }
diff --git a/app/code/Magento/Downloadable/Api/SampleRepositoryInterface.php b/app/code/Magento/Downloadable/Api/SampleRepositoryInterface.php
index cd72680b21bae5b75bd3b245d5a867ebd8e7f168..9a52cea8819f4e413e8c5a1964e5732e5936ed6f 100644
--- a/app/code/Magento/Downloadable/Api/SampleRepositoryInterface.php
+++ b/app/code/Magento/Downloadable/Api/SampleRepositoryInterface.php
@@ -5,31 +5,29 @@
  */
 namespace Magento\Downloadable\Api;
 
-use Magento\Downloadable\Api\Data\SampleContentInterface;
+use Magento\Downloadable\Api\Data\SampleInterface;
 
 interface SampleRepositoryInterface
 {
     /**
-     * Update downloadable sample of the given product (sample type and its resource cannot be changed)
+     * Update downloadable sample of the given product
      *
-     * @param string $productSku
-     * @param \Magento\Downloadable\Api\Data\SampleContentInterface $sampleContent
-     * @param int $sampleId
+     * @param string $sku
+     * @param \Magento\Downloadable\Api\Data\SampleInterface $sample
      * @param bool $isGlobalScopeContent
      * @return int
      */
     public function save(
-        $productSku,
-        SampleContentInterface $sampleContent,
-        $sampleId = null,
+        $sku,
+        SampleInterface $sample,
         $isGlobalScopeContent = false
     );
 
     /**
      * Delete downloadable sample
      *
-     * @param int $sampleId
+     * @param int $id
      * @return bool
      */
-    public function delete($sampleId);
+    public function delete($id);
 }
diff --git a/app/code/Magento/Downloadable/Model/Link.php b/app/code/Magento/Downloadable/Model/Link.php
index 84de54915ab0edec47b492ac19a2fde4f5d131b4..66703a9dccb811ce294d5c4b39b053db7ec07cc2 100644
--- a/app/code/Magento/Downloadable/Model/Link.php
+++ b/app/code/Magento/Downloadable/Model/Link.php
@@ -43,9 +43,11 @@ class Link extends \Magento\Framework\Model\AbstractExtensibleModel implements C
     const KEY_NUMBER_OF_DOWNLOADS = 'number_of_downloads';
     const KEY_LINK_TYPE = 'link_type';
     const KEY_LINK_FILE = 'link_file';
+    const KEY_LINK_FILE_CONTENT = 'link_file_content';
     const KEY_LINK_URL = 'link_url';
     const KEY_SAMPLE_TYPE = 'sample_type';
     const KEY_SAMPLE_FILE = 'sample_file';
+    const KEY_SAMPLE_FILE_CONTENT = 'sample_file_content';
     const KEY_SAMPLE_URL = 'sample_url';
     /**#@-*/
 
@@ -213,6 +215,16 @@ class Link extends \Magento\Framework\Model\AbstractExtensibleModel implements C
         return $this->getData(self::KEY_LINK_FILE);
     }
 
+    /**
+     * Return file content
+     *
+     * @return \Magento\Downloadable\Api\Data\File\ContentInterface|null
+     */
+    public function getLinkFileContent()
+    {
+        return $this->getData(self::KEY_LINK_FILE_CONTENT);
+    }
+
     /**
      * {@inheritdoc}
      * @codeCoverageIgnore
@@ -240,6 +252,16 @@ class Link extends \Magento\Framework\Model\AbstractExtensibleModel implements C
         return $this->getData(self::KEY_SAMPLE_FILE);
     }
 
+    /**
+     * Return sample file content when type is 'file'
+     *
+     * @return \Magento\Downloadable\Api\Data\File\ContentInterface|null relative file path
+     */
+    public function getSampleFileContent()
+    {
+        return $this->getData(self::KEY_SAMPLE_FILE_CONTENT);
+    }
+
     /**
      * {@inheritdoc}
      * @codeCoverageIgnore
@@ -320,6 +342,17 @@ class Link extends \Magento\Framework\Model\AbstractExtensibleModel implements C
         return $this->setData(self::KEY_LINK_FILE, $linkFile);
     }
 
+    /**
+     * Set file content
+     *
+     * @param \Magento\Downloadable\Api\Data\File\ContentInterface $linkFileContent
+     * @return $this
+     */
+    public function setLinkFileContent(\Magento\Downloadable\Api\Data\File\ContentInterface $linkFileContent = null)
+    {
+        return $this->setData(self::KEY_LINK_FILE_CONTENT, $linkFileContent);
+    }
+
     /**
      * Set URL
      *
@@ -351,6 +384,19 @@ class Link extends \Magento\Framework\Model\AbstractExtensibleModel implements C
         return $this->setData(self::KEY_SAMPLE_FILE, $sampleFile);
     }
 
+    /**
+     * Set sample file content
+     *
+     * @param \Magento\Downloadable\Api\Data\File\ContentInterface $sampleFileContent
+     * @return $this
+     */
+    public function setSampleFileContent(
+        \Magento\Downloadable\Api\Data\File\ContentInterface $sampleFileContent = null
+    ) {
+        return $this->setData(self::KEY_SAMPLE_FILE_CONTENT, $sampleFileContent);
+    }
+
+
     /**
      * Set URL
      *
diff --git a/app/code/Magento/Downloadable/Model/Link/Content.php b/app/code/Magento/Downloadable/Model/Link/Content.php
deleted file mode 100644
index a40f76faf1cff5c353a8406943c9b51b4f95e428..0000000000000000000000000000000000000000
--- a/app/code/Magento/Downloadable/Model/Link/Content.php
+++ /dev/null
@@ -1,268 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Downloadable\Model\Link;
-
-use Magento\Downloadable\Api\Data\LinkContentInterface;
-
-/**
- * @codeCoverageIgnore
- */
-class Content extends \Magento\Framework\Model\AbstractExtensibleModel implements LinkContentInterface
-{
-    const TITLE = 'title';
-    const PRICE = 'price';
-    const NUMBER_OF_DOWNLOADS = 'number_of_downloads';
-    const SHAREABLE = 'shareable';
-    const SORT_ORDER = 'sort_order';
-    const LINK_FILE = 'link_file';
-    const LINK_URL = 'link_url';
-    const LINK_TYPE = 'link_type';
-    const SAMPLE_FILE = 'sample_file';
-    const SAMPLE_URL = 'sample_url';
-    const SAMPLE_TYPE = 'sample_type';
-
-    /**
-     * {@inheritdoc}
-     * @codeCoverageIgnore
-     */
-    public function getTitle()
-    {
-        return $this->getData(self::TITLE);
-    }
-
-    /**
-     * {@inheritdoc}
-     * @codeCoverageIgnore
-     */
-    public function getSortOrder()
-    {
-        return $this->getData(self::SORT_ORDER);
-    }
-
-    /**
-     * {@inheritdoc}
-     * @codeCoverageIgnore
-     */
-    public function getPrice()
-    {
-        return $this->getData(self::PRICE);
-    }
-
-    /**
-     * {@inheritdoc}
-     * @codeCoverageIgnore
-     */
-    public function getNumberOfDownloads()
-    {
-        return $this->getData(self::NUMBER_OF_DOWNLOADS);
-    }
-
-    /**
-     * {@inheritdoc}
-     * @codeCoverageIgnore
-     */
-    public function isShareable()
-    {
-        return $this->getData(self::SHAREABLE);
-    }
-
-    /**
-     * {@inheritdoc}
-     * @codeCoverageIgnore
-     */
-    public function getLinkFile()
-    {
-        return $this->getData(self::LINK_FILE);
-    }
-
-    /**
-     * {@inheritdoc}
-     * @codeCoverageIgnore
-     */
-    public function getLinkUrl()
-    {
-        return $this->getData(self::LINK_URL);
-    }
-
-    /**
-     * {@inheritdoc}
-     * @codeCoverageIgnore
-     */
-    public function getLinkType()
-    {
-        return $this->getData(self::LINK_TYPE);
-    }
-
-    /**
-     * {@inheritdoc}
-     * @codeCoverageIgnore
-     */
-    public function getSampleFile()
-    {
-        return $this->getData(self::SAMPLE_FILE);
-    }
-
-    /**
-     * {@inheritdoc}
-     * @codeCoverageIgnore
-     */
-    public function getSampleUrl()
-    {
-        return $this->getData(self::SAMPLE_URL);
-    }
-
-    /**
-     * {@inheritdoc}
-     * @codeCoverageIgnore
-     */
-    public function getSampleType()
-    {
-        return $this->getData(self::SAMPLE_TYPE);
-    }
-
-    /**
-     * Set sample title
-     *
-     * @param string $title
-     * @return $this
-     */
-    public function setTitle($title)
-    {
-        return $this->setData(self::TITLE, $title);
-    }
-
-    /**
-     * Set sample sort order
-     *
-     * @param int $sortOrder
-     * @return $this
-     */
-    public function setSortOrder($sortOrder)
-    {
-        return $this->setData(self::SORT_ORDER, $sortOrder);
-    }
-
-    /**
-     * Set link price
-     *
-     * @param string $price
-     * @return $this
-     */
-    public function setPrice($price)
-    {
-        return $this->setData(self::PRICE, $price);
-    }
-
-    /**
-     * Set number of allowed downloads of the link
-     *
-     * @param int $numberOfDownloads
-     * @return $this
-     */
-    public function setNumberOfDownloads($numberOfDownloads)
-    {
-        return $this->setData(self::NUMBER_OF_DOWNLOADS, $numberOfDownloads);
-    }
-
-    /**
-     * Set whether link is shareable
-     *
-     * @param bool $shareable
-     * @return $this
-     */
-    public function setShareable($shareable)
-    {
-        return $this->setData(self::SHAREABLE, $shareable);
-    }
-
-    /**
-     * Set link file content
-     *
-     * @param \Magento\Downloadable\Api\Data\File\ContentInterface $linkFile
-     * @return $this
-     */
-    public function setLinkFile(\Magento\Downloadable\Api\Data\File\ContentInterface $linkFile = null)
-    {
-        return $this->setData(self::LINK_FILE, $linkFile);
-    }
-
-    /**
-     * Set link URL
-     *
-     * @param string $linkUrl
-     * @return $this
-     */
-    public function setLinkUrl($linkUrl)
-    {
-        return $this->setData(self::LINK_URL, $linkUrl);
-    }
-
-    /**
-     * Set link type ('url' or 'file')
-     *
-     * @param string $linkType
-     * @return $this
-     */
-    public function setLinkType($linkType)
-    {
-        return $this->setData(self::LINK_TYPE, $linkType);
-    }
-
-    /**
-     * Retrieve sample file content
-     *
-     * @param \Magento\Downloadable\Api\Data\File\ContentInterface $sampleFile
-     * @return $this
-     */
-    public function setSampleFile(\Magento\Downloadable\Api\Data\File\ContentInterface $sampleFile = null)
-    {
-        return $this->setData(self::SAMPLE_FILE, $sampleFile);
-    }
-
-    /**
-     * Set sample URL
-     *
-     * @param string $sampleUrl
-     * @return $this
-     */
-    public function setSampleUrl($sampleUrl)
-    {
-        return $this->setData(self::SAMPLE_URL, $sampleUrl);
-    }
-
-    /**
-     * Set sample type ('url' or 'file')
-     *
-     * @param string $sampleType
-     * @return $this
-     */
-    public function setSampleType($sampleType)
-    {
-        return $this->setData(self::SAMPLE_TYPE, $sampleType);
-    }
-
-    /**
-     * {@inheritdoc}
-     *
-     * @return \Magento\Downloadable\Api\Data\LinkContentExtensionInterface|null
-     */
-    public function getExtensionAttributes()
-    {
-        return $this->_getExtensionAttributes();
-    }
-
-    /**
-     * {@inheritdoc}
-     *
-     * @param \Magento\Downloadable\Api\Data\LinkContentExtensionInterface $extensionAttributes
-     * @return $this
-     */
-    public function setExtensionAttributes(
-        \Magento\Downloadable\Api\Data\LinkContentExtensionInterface $extensionAttributes
-    ) {
-        return $this->_setExtensionAttributes($extensionAttributes);
-    }
-}
diff --git a/app/code/Magento/Downloadable/Model/Link/ContentValidator.php b/app/code/Magento/Downloadable/Model/Link/ContentValidator.php
index 708302b7871c21c7bd1921b7a522019cbcd25aef..f1bf1d2dcbe85f819a0af7091d8806bee9cdcc12 100644
--- a/app/code/Magento/Downloadable/Model/Link/ContentValidator.php
+++ b/app/code/Magento/Downloadable/Model/Link/ContentValidator.php
@@ -5,7 +5,7 @@
  */
 namespace Magento\Downloadable\Model\Link;
 
-use Magento\Downloadable\Api\Data\LinkContentInterface;
+use Magento\Downloadable\Api\Data\LinkInterface;
 use Magento\Downloadable\Model\File\ContentValidator as FileContentValidator;
 use Magento\Framework\Exception\InputException;
 use Magento\Framework\Url\Validator as UrlValidator;
@@ -37,43 +37,50 @@ class ContentValidator
     /**
      * Check if link content is valid
      *
-     * @param LinkContentInterface $linkContent
+     * @param LinkInterface $link
+     * @param bool $validateLinkContent
+     * @param bool $validateSampleContent
      * @return bool
      * @throws InputException
      */
-    public function isValid(LinkContentInterface $linkContent)
+    public function isValid(LinkInterface $link, $validateLinkContent = true, $validateSampleContent = true)
     {
-        if (!is_numeric($linkContent->getPrice()) || $linkContent->getPrice() < 0) {
+        if (!is_numeric($link->getPrice()) || $link->getPrice() < 0) {
             throw new InputException(__('Link price must have numeric positive value.'));
         }
-        if (!is_int($linkContent->getNumberOfDownloads()) || $linkContent->getNumberOfDownloads() < 0) {
+        if (!is_int($link->getNumberOfDownloads()) || $link->getNumberOfDownloads() < 0) {
             throw new InputException(__('Number of downloads must be a positive integer.'));
         }
-        if (!is_int($linkContent->getSortOrder()) || $linkContent->getSortOrder() < 0) {
+        if (!is_int($link->getSortOrder()) || $link->getSortOrder() < 0) {
             throw new InputException(__('Sort order must be a positive integer.'));
         }
 
-        $this->validateLinkResource($linkContent);
-        $this->validateSampleResource($linkContent);
+        if ($validateLinkContent) {
+            $this->validateLinkResource($link);
+        }
+        if ($validateSampleContent) {
+            $this->validateSampleResource($link);
+        }
         return true;
     }
 
     /**
      * Validate link resource (file or URL)
      *
-     * @param LinkContentInterface $linkContent
+     * @param LinkInterface $link
      * @throws InputException
      * @return void
      */
-    protected function validateLinkResource(LinkContentInterface $linkContent)
+    protected function validateLinkResource(LinkInterface $link)
     {
-        if ($linkContent->getLinkType() == 'url'
-            && !$this->urlValidator->isValid($linkContent->getLinkUrl())
+        if ($link->getLinkType() == 'url'
+            && !$this->urlValidator->isValid($link->getLinkUrl())
         ) {
             throw new InputException(__('Link URL must have valid format.'));
         }
-        if ($linkContent->getLinkType() == 'file'
-            && (!$linkContent->getLinkFile() || !$this->fileContentValidator->isValid($linkContent->getLinkFile()))
+        if ($link->getLinkType() == 'file'
+            && (!$link->getLinkFileContent()
+                || !$this->fileContentValidator->isValid($link->getLinkFileContent()))
         ) {
             throw new InputException(__('Provided file content must be valid base64 encoded data.'));
         }
@@ -82,19 +89,20 @@ class ContentValidator
     /**
      * Validate sample resource (file or URL)
      *
-     * @param LinkContentInterface $linkContent
+     * @param LinkInterface $link
      * @throws InputException
      * @return void
      */
-    protected function validateSampleResource(LinkContentInterface $linkContent)
+    protected function validateSampleResource(LinkInterface $link)
     {
-        if ($linkContent->getSampleType() == 'url'
-            && !$this->urlValidator->isValid($linkContent->getSampleUrl())
+        if ($link->getSampleType() == 'url'
+            && !$this->urlValidator->isValid($link->getSampleUrl())
         ) {
             throw new InputException(__('Sample URL must have valid format.'));
         }
-        if ($linkContent->getSampleType() == 'file'
-            && (!$linkContent->getSampleFile() || !$this->fileContentValidator->isValid($linkContent->getSampleFile()))
+        if ($link->getSampleType() == 'file'
+            && (!$link->getSampleFileContent()
+                || !$this->fileContentValidator->isValid($link->getSampleFileContent()))
         ) {
             throw new InputException(__('Provided file content must be valid base64 encoded data.'));
         }
diff --git a/app/code/Magento/Downloadable/Model/LinkRepository.php b/app/code/Magento/Downloadable/Model/LinkRepository.php
index 426e8bf63f21ed644dae4394470c8bf71d6482b4..bca06682ba718dee04cdd59e0edbfc275cc18efb 100644
--- a/app/code/Magento/Downloadable/Model/LinkRepository.php
+++ b/app/code/Magento/Downloadable/Model/LinkRepository.php
@@ -5,7 +5,7 @@
  */
 namespace Magento\Downloadable\Model;
 
-use Magento\Downloadable\Api\Data\LinkContentInterface;
+use Magento\Downloadable\Api\Data\LinkInterface;
 use Magento\Downloadable\Api\Data\File\ContentUploaderInterface;
 use Magento\Framework\Exception\InputException;
 use Magento\Framework\Exception\NoSuchEntityException;
@@ -92,9 +92,18 @@ class LinkRepository implements \Magento\Downloadable\Api\LinkRepositoryInterfac
      */
     public function getLinks($sku)
     {
-        $linkList = [];
         /** @var \Magento\Catalog\Model\Product $product */
         $product = $this->productRepository->get($sku);
+        return $this->getLinksByProduct($product);
+    }
+
+    /**
+     * @param \Magento\Catalog\Api\Data\ProductInterface $product
+     * @return array
+     */
+    public function getLinksByProduct(\Magento\Catalog\Api\Data\ProductInterface $product)
+    {
+        $linkList = [];
         $links = $this->downloadableType->getLinks($product);
         /** @var \Magento\Downloadable\Model\Link $link */
         foreach ($links as $link) {
@@ -152,9 +161,17 @@ class LinkRepository implements \Magento\Downloadable\Api\LinkRepositoryInterfac
      */
     public function getSamples($sku)
     {
-        $sampleList = [];
-        /** @var \Magento\Catalog\Model\Product $product */
         $product = $this->productRepository->get($sku);
+        return $this->getSamplesByProduct($product);
+    }
+
+    /**
+     * @param \Magento\Catalog\Api\Data\ProductInterface $product
+     * @return array
+     */
+    public function getSamplesByProduct(\Magento\Catalog\Api\Data\ProductInterface $product)
+    {
+        $sampleList = [];
         $samples = $this->downloadableType->getSamples($product);
         /** @var \Magento\Downloadable\Model\Sample $sample */
         foreach ($samples as $sample) {
@@ -181,113 +198,149 @@ class LinkRepository implements \Magento\Downloadable\Api\LinkRepositoryInterfac
      * @SuppressWarnings(PHPMD.CyclomaticComplexity)
      * @SuppressWarnings(PHPMD.NPathComplexity)
      */
-    public function save($sku, LinkContentInterface $linkContent, $linkId = null, $isGlobalScopeContent = false)
+    public function save($sku, LinkInterface $link, $isGlobalScopeContent = false)
     {
         $product = $this->productRepository->get($sku, true);
-        if ($linkId) {
-
-            /** @var $link \Magento\Downloadable\Model\Link */
-            $link = $this->linkFactory->create()->load($linkId);
-            if (!$link->getId()) {
-                throw new NoSuchEntityException(__('There is no downloadable link with provided ID.'));
-            }
-            if ($link->getProductId() != $product->getId()) {
-                throw new InputException(__('Provided downloadable link is not related to given product.'));
-            }
-            if (!$this->contentValidator->isValid($linkContent)) {
-                throw new InputException(__('Provided link information is invalid.'));
-            }
-            if ($isGlobalScopeContent) {
-                $product->setStoreId(0);
-            }
-            $title = $linkContent->getTitle();
-            if (empty($title)) {
-                if ($isGlobalScopeContent) {
-                    throw new InputException(__('Link title cannot be empty.'));
-                }
-                // use title from GLOBAL scope
-                $link->setTitle(null);
-            } else {
-                $link->setTitle($linkContent->getTitle());
-            }
-
-            $link->setProductId($product->getId())
-                ->setStoreId($product->getStoreId())
-                ->setWebsiteId($product->getStore()->getWebsiteId())
-                ->setProductWebsiteIds($product->getWebsiteIds())
-                ->setSortOrder($linkContent->getSortOrder())
-                ->setPrice($linkContent->getPrice())
-                ->setIsShareable($linkContent->isShareable())
-                ->setNumberOfDownloads($linkContent->getNumberOfDownloads())
-                ->save();
-            return $link->getId();
+        if ($link->getId() !== null) {
+            return $this->updateLink($product, $link, $isGlobalScopeContent);
         } else {
-            $product = $this->productRepository->get($sku, true);
             if ($product->getTypeId() !== \Magento\Downloadable\Model\Product\Type::TYPE_DOWNLOADABLE) {
                 throw new InputException(__('Product type of the product must be \'downloadable\'.'));
             }
-            if (!$this->contentValidator->isValid($linkContent)) {
+            if (!$this->contentValidator->isValid($link)) {
                 throw new InputException(__('Provided link information is invalid.'));
             }
 
-            if (!in_array($linkContent->getLinkType(), ['url', 'file'])) {
+            if (!in_array($link->getLinkType(), ['url', 'file'])) {
                 throw new InputException(__('Invalid link type.'));
             }
-            $title = $linkContent->getTitle();
+            $title = $link->getTitle();
             if (empty($title)) {
                 throw new InputException(__('Link title cannot be empty.'));
             }
+            return $this->saveLink($product, $link, $isGlobalScopeContent);
+        }
+    }
 
-            $linkData = [
-                'link_id' => 0,
-                'is_delete' => 0,
-                'type' => $linkContent->getLinkType(),
-                'sort_order' => $linkContent->getSortOrder(),
-                'title' => $linkContent->getTitle(),
-                'price' => $linkContent->getPrice(),
-                'number_of_downloads' => $linkContent->getNumberOfDownloads(),
-                'is_shareable' => $linkContent->isShareable(),
-            ];
+    /**
+     * @param \Magento\Catalog\Api\Data\ProductInterface $product
+     * @param LinkInterface $link
+     * @param bool $isGlobalScopeContent
+     * @return int
+     */
+    protected function saveLink(
+        \Magento\Catalog\Api\Data\ProductInterface $product,
+        LinkInterface $link,
+        $isGlobalScopeContent
+    ) {
+        $linkData = [
+            'link_id' => $link->getid() === null ? 0 : $link->getid(),
+            'is_delete' => 0,
+            'type' => $link->getLinkType(),
+            'sort_order' => $link->getSortOrder(),
+            'title' => $link->getTitle(),
+            'price' => $link->getPrice(),
+            'number_of_downloads' => $link->getNumberOfDownloads(),
+            'is_shareable' => $link->getIsShareable(),
+        ];
 
-            if ($linkContent->getLinkType() == 'file') {
-                $linkData['file'] = $this->jsonEncoder->encode(
+        if ($link->getLinkType() == 'file' && $link->getLinkFile() === null) {
+            $linkData['file'] = $this->jsonEncoder->encode(
+                [
+                    $this->fileContentUploader->upload($link->getLinkFileContent(), 'link_file'),
+                ]
+            );
+        } elseif ($link->getLinkType() === 'url') {
+            $linkData['link_url'] = $link->getLinkUrl();
+        } else {
+            //existing link file
+            $linkData['file'] = $this->jsonEncoder->encode(
+                [
                     [
-                        $this->fileContentUploader->upload($linkContent->getLinkFile(), 'link_file'),
+                        'file' => $link->getLinkFile(),
+                        'status' => 'old',
                     ]
-                );
-            } else {
-                $linkData['link_url'] = $linkContent->getLinkUrl();
-            }
+                ]
+            );
+        }
 
-            if ($linkContent->getSampleType() == 'file') {
-                $linkData['sample']['type'] = 'file';
-                $linkData['sample']['file'] = $this->jsonEncoder->encode(
-                    [
-                        $this->fileContentUploader->upload($linkContent->getSampleFile(), 'link_sample_file'),
-                    ]
-                );
-            } elseif ($linkContent->getSampleType() == 'url') {
-                $linkData['sample']['type'] = 'url';
-                $linkData['sample']['url'] = $linkContent->getSampleUrl();
-            }
+        if ($link->getSampleType() == 'file' && $link->getSampleFile() === null) {
+            $linkData['sample']['type'] = 'file';
+            $linkData['sample']['file'] = $this->jsonEncoder->encode(
+                [
+                    $this->fileContentUploader->upload($link->getSampleFileContent(), 'link_sample_file'),
+                ]
+            );
+        } elseif ($link->getSampleType() == 'url') {
+            $linkData['sample']['type'] = 'url';
+            $linkData['sample']['url'] = $link->getSampleUrl();
+        }
 
-            $downloadableData = ['link' => [$linkData]];
-            $product->setDownloadableData($downloadableData);
+        $downloadableData = ['link' => [$linkData]];
+        $product->setDownloadableData($downloadableData);
+        if ($isGlobalScopeContent) {
+            $product->setStoreId(0);
+        }
+        $this->downloadableType->save($product);
+        return $product->getLastAddedLinkId();
+    }
+
+    /**
+     * @param \Magento\Catalog\Api\Data\ProductInterface $product
+     * @param LinkInterface $link
+     * @param bool $isGlobalScopeContent
+     * @return mixed
+     * @throws InputException
+     * @throws NoSuchEntityException
+     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+     * @SuppressWarnings(PHPMD.NPathComplexity)
+     */
+    protected function updateLink(
+        \Magento\Catalog\Api\Data\ProductInterface $product,
+        LinkInterface $link,
+        $isGlobalScopeContent
+    ) {
+        /** @var $existingLink \Magento\Downloadable\Model\Link */
+        $existingLink = $this->linkFactory->create()->load($link->getId());
+        if (!$existingLink->getId()) {
+            throw new NoSuchEntityException(__('There is no downloadable link with provided ID.'));
+        }
+        if ($existingLink->getProductId() != $product->getId()) {
+            throw new InputException(__('Provided downloadable link is not related to given product.'));
+        }
+        $validateLinkContent = $link->getLinkFileContent() === null ? false : true;
+        $validateSampleContent = $link->getSampleFileContent() === null ? false : true;
+        if (!$this->contentValidator->isValid($link, $validateLinkContent, $validateSampleContent)) {
+            throw new InputException(__('Provided link information is invalid.'));
+        }
+        if ($isGlobalScopeContent) {
+            $product->setStoreId(0);
+        }
+        $title = $link->getTitle();
+        if (empty($title)) {
             if ($isGlobalScopeContent) {
-                $product->setStoreId(0);
+                throw new InputException(__('Link title cannot be empty.'));
             }
-            $product->save();
-            return $product->getLastAddedLinkId();
         }
+
+        if ($link->getLinkType() == 'file' && $link->getLinkFileContent() === null) {
+            $link->setLinkFile($existingLink->getLinkFile());
+        }
+        if ($link->getSampleType() == 'file' && $link->getSampleFileContent() === null) {
+            $link->setSampleFile($existingLink->getSampleFile());
+        }
+
+        $this->saveLink($product, $link, $isGlobalScopeContent);
+        return $existingLink->getId();
     }
 
     /**
      * {@inheritdoc}
      */
-    public function delete($linkId)
+    public function delete($id)
     {
         /** @var $link \Magento\Downloadable\Model\Link */
-        $link = $this->linkFactory->create()->load($linkId);
+        $link = $this->linkFactory->create()->load($id);
         if (!$link->getId()) {
             throw new NoSuchEntityException(__('There is no downloadable link with provided ID.'));
         }
diff --git a/app/code/Magento/Downloadable/Model/Observer.php b/app/code/Magento/Downloadable/Model/Observer.php
index 0fd516bfa9fafc120ee467f52725eb0e974de334..68dc8f018d7f00aef5a9556f6622d518bb924142 100644
--- a/app/code/Magento/Downloadable/Model/Observer.php
+++ b/app/code/Magento/Downloadable/Model/Observer.php
@@ -114,10 +114,10 @@ class Observer
             //order not saved in the database
             return $this;
         }
-        $product = $orderItem->getProduct();
-        if ($product && $product->getTypeId() != \Magento\Downloadable\Model\Product\Type::TYPE_DOWNLOADABLE) {
+        if ($orderItem->getProductType() != \Magento\Downloadable\Model\Product\Type::TYPE_DOWNLOADABLE) {
             return $this;
         }
+        $product = $orderItem->getProduct();
         $purchasedLink = $this->_createPurchasedModel()->load($orderItem->getId(), 'order_item_id');
         if ($purchasedLink->getId()) {
             return $this;
diff --git a/app/code/Magento/Downloadable/Model/Plugin/AfterProductLoad.php b/app/code/Magento/Downloadable/Model/Plugin/AfterProductLoad.php
new file mode 100644
index 0000000000000000000000000000000000000000..83466a0fa080f34d7aa3d38fbcfd0fd8905d1101
--- /dev/null
+++ b/app/code/Magento/Downloadable/Model/Plugin/AfterProductLoad.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Downloadable\Model\Plugin;
+
+class AfterProductLoad
+{
+    /**
+     * @var \Magento\Downloadable\Api\LinkRepositoryInterface
+     */
+    protected $linkRepository;
+
+    /**
+     * @var \Magento\Catalog\Api\Data\ProductExtensionFactory
+     */
+    protected $productExtensionFactory;
+
+    /**
+     * @param \Magento\Downloadable\Api\LinkRepositoryInterface $linkRepository
+     * @param \Magento\Catalog\Api\Data\ProductExtensionFactory $productExtensionFactory
+     */
+    public function __construct(
+        \Magento\Downloadable\Api\LinkRepositoryInterface $linkRepository,
+        \Magento\Catalog\Api\Data\ProductExtensionFactory $productExtensionFactory
+    ) {
+        $this->linkRepository = $linkRepository;
+        $this->productExtensionFactory = $productExtensionFactory;
+    }
+
+    /**
+     * @param \Magento\Catalog\Model\Product $product
+     * @return \Magento\Catalog\Model\Product
+     */
+    public function afterLoad(
+        \Magento\Catalog\Model\Product $product
+    ) {
+        if ($product->getTypeId() != \Magento\Downloadable\Model\Product\Type::TYPE_DOWNLOADABLE) {
+            return $product;
+        }
+
+        $productExtension = $product->getExtensionAttributes();
+        if ($productExtension === null) {
+            $productExtension = $this->productExtensionFactory->create();
+        }
+        $links = $this->linkRepository->getLinksByProduct($product);
+        if ($links !== null) {
+            $productExtension->setDownloadableProductLinks($links);
+        }
+        $samples = $this->linkRepository->getSamplesByProduct($product);
+        if ($samples !== null) {
+            $productExtension->setDownloadableProductSamples($samples);
+        }
+
+        $product->setExtensionAttributes($productExtension);
+
+        return $product;
+    }
+}
diff --git a/app/code/Magento/Downloadable/Model/Plugin/AroundProductRepositorySave.php b/app/code/Magento/Downloadable/Model/Plugin/AroundProductRepositorySave.php
new file mode 100644
index 0000000000000000000000000000000000000000..13dd932c3a7683109c4fcef022556abb0dbfa519
--- /dev/null
+++ b/app/code/Magento/Downloadable/Model/Plugin/AroundProductRepositorySave.php
@@ -0,0 +1,145 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Downloadable\Model\Plugin;
+
+class AroundProductRepositorySave
+{
+    /**
+     * @var \Magento\Downloadable\Api\LinkRepositoryInterface
+     */
+    protected $linkRepository;
+
+    /**
+     * @var \Magento\Downloadable\Api\SampleRepositoryInterface
+     */
+    protected $sampleRepository;
+
+    /**
+     * @param \Magento\Downloadable\Api\LinkRepositoryInterface $linkRepository
+     * @param \Magento\Downloadable\Api\SampleRepositoryInterface $sampleRepository
+     */
+    public function __construct(
+        \Magento\Downloadable\Api\LinkRepositoryInterface $linkRepository,
+        \Magento\Downloadable\Api\SampleRepositoryInterface $sampleRepository
+    ) {
+        $this->linkRepository = $linkRepository;
+        $this->sampleRepository = $sampleRepository;
+    }
+
+    /**
+     * @param \Magento\Catalog\Api\ProductRepositoryInterface $subject
+     * @param callable $proceed
+     * @param \Magento\Catalog\Api\Data\ProductInterface $product
+     * @param bool $saveOptions
+     * @return \Magento\Catalog\Api\Data\ProductInterface
+     * @throws \Magento\Framework\Exception\CouldNotSaveException
+     */
+    public function aroundSave(
+        \Magento\Catalog\Api\ProductRepositoryInterface $subject,
+        \Closure $proceed,
+        \Magento\Catalog\Api\Data\ProductInterface $product,
+        $saveOptions = false
+    ) {
+        /** @var \Magento\Catalog\Api\Data\ProductInterface $result */
+        $result = $proceed($product, $saveOptions);
+
+        if ($product->getTypeId() != \Magento\Downloadable\Model\Product\Type::TYPE_DOWNLOADABLE) {
+            return $result;
+        }
+
+        /* @var \Magento\Catalog\Api\Data\ProductExtensionInterface $options */
+        $extendedAttributes = $product->getExtensionAttributes();
+        if ($extendedAttributes === null) {
+            return $result;
+        }
+        $links = $extendedAttributes->getDownloadableProductLinks();
+        $samples = $extendedAttributes->getDownloadableProductSamples();
+
+        if ($links === null && $samples === null) {
+            return $result;
+        }
+
+        if ($links !== null) {
+            $this->saveLinks($result, $links);
+        }
+        if ($samples !== null) {
+            $this->saveSamples($result, $samples);
+        }
+
+        return $subject->get($result->getSku(), false, $result->getStoreId(), true);
+    }
+
+    /**
+     * @param \Magento\Catalog\Api\Data\ProductInterface $product
+     * @param \Magento\Downloadable\Api\Data\LinkInterface[] $links
+     * @return $this
+     */
+    protected function saveLinks(\Magento\Catalog\Api\Data\ProductInterface $product, array $links)
+    {
+        $existingLinkIds = [];
+        //get existing links from extension attribute
+        $extensionAttributes = $product->getExtensionAttributes();
+        if ($extensionAttributes !== null) {
+            $existingLinks = $extensionAttributes->getDownloadableProductLinks();
+            if ($existingLinks !== null) {
+                foreach ($existingLinks as $existingLink) {
+                    $existingLinkIds[] = $existingLink->getId();
+                }
+            }
+        }
+
+        $updatedLinkIds = [];
+        foreach ($links as $link) {
+            $linkId = $link->getId();
+            if ($linkId) {
+                $updatedLinkIds[] = $linkId;
+            }
+            $this->linkRepository->save($product->getSku(), $link);
+        }
+        $linkIdsToDelete = array_diff($existingLinkIds, $updatedLinkIds);
+
+        foreach ($linkIdsToDelete as $linkId) {
+            $this->linkRepository->delete($linkId);
+        }
+        return $this;
+    }
+
+    /**
+     * @param \Magento\Catalog\Api\Data\ProductInterface $product
+     * @param \Magento\Downloadable\Api\Data\SampleInterface[] $samples
+     * @return $this
+     */
+    protected function saveSamples(\Magento\Catalog\Api\Data\ProductInterface $product, array $samples)
+    {
+        $existingSampleIds = [];
+        $extensionAttributes = $product->getExtensionAttributes();
+        if ($extensionAttributes !== null) {
+            $existingSamples = $extensionAttributes->getDownloadableProductSamples();
+            if ($existingSamples !== null) {
+                foreach ($existingSamples as $existingSample) {
+                    $existingSampleIds[] = $existingSample->getId();
+                }
+            }
+        }
+
+        $updatedSampleIds = [];
+        foreach ($samples as $sample) {
+            $sampleId = $sample->getId();
+            if ($sampleId) {
+                $updatedSampleIds[] = $sampleId;
+            }
+            $this->sampleRepository->save($product->getSku(), $sample);
+        }
+        $sampleIdsToDelete = array_diff($existingSampleIds, $updatedSampleIds);
+
+        foreach ($sampleIdsToDelete as $sampleId) {
+            $this->sampleRepository->delete($sampleId);
+        }
+        return $this;
+    }
+}
diff --git a/app/code/Magento/Downloadable/Model/Sample.php b/app/code/Magento/Downloadable/Model/Sample.php
index 07dd821050aad1d60ae18abc38211afdd1fb4a55..4909fe6a39e649e071b47859b77a136eb31a1241 100644
--- a/app/code/Magento/Downloadable/Model/Sample.php
+++ b/app/code/Magento/Downloadable/Model/Sample.php
@@ -27,6 +27,7 @@ class Sample extends \Magento\Framework\Model\AbstractExtensibleModel implements
     const KEY_SORT_ORDER = 'sort_order';
     const KEY_SAMPLE_TYPE = 'sample_type';
     const KEY_SAMPLE_FILE = 'sample_file';
+    const KEY_SAMPLE_FILE_CONTENT = 'sample_file_content';
     const KEY_SAMPLE_URL = 'sample_url';
     /**#@-*/
 
@@ -163,6 +164,15 @@ class Sample extends \Magento\Framework\Model\AbstractExtensibleModel implements
         return $this->getData(self::KEY_SAMPLE_FILE);
     }
 
+    /**
+     * {@inheritdoc}
+     * @codeCoverageIgnore
+     */
+    public function getSampleFileContent()
+    {
+        return $this->getData(self::KEY_SAMPLE_FILE_CONTENT);
+    }
+
     /**
      * {@inheritdoc}
      * @codeCoverageIgnore
@@ -214,6 +224,17 @@ class Sample extends \Magento\Framework\Model\AbstractExtensibleModel implements
         return $this->setData(self::KEY_SAMPLE_FILE, $sampleFile);
     }
 
+    /**
+     * Set sample file content
+     *
+     * @param \Magento\Downloadable\Api\Data\File\ContentInterface $sampleFileContent
+     * @return $this
+     */
+    public function setSampleFileContent(\Magento\Downloadable\Api\Data\File\ContentInterface $sampleFileContent = null)
+    {
+        return $this->setData(self::KEY_SAMPLE_FILE_CONTENT, $sampleFileContent);
+    }
+
     /**
      * Set sample URL
      *
diff --git a/app/code/Magento/Downloadable/Model/Sample/Content.php b/app/code/Magento/Downloadable/Model/Sample/Content.php
deleted file mode 100644
index 0fcf613353966548cfbf6ec83e2ca47837ff9f54..0000000000000000000000000000000000000000
--- a/app/code/Magento/Downloadable/Model/Sample/Content.php
+++ /dev/null
@@ -1,142 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Downloadable\Model\Sample;
-
-use Magento\Downloadable\Api\Data\SampleContentInterface;
-
-/**
- * @codeCoverageIgnore
- */
-class Content extends \Magento\Framework\Model\AbstractExtensibleModel implements SampleContentInterface
-{
-    const TITLE = 'title';
-    const SORT_ORDER = 'sort_order';
-    const SAMPLE_FILE = 'sample_file';
-    const SAMPLE_URL = 'sample_url';
-    const SAMPLE_TYPE = 'sample_type';
-
-    /**
-     * {@inheritdoc}
-     * @codeCoverageIgnore
-     */
-    public function getTitle()
-    {
-        return $this->getData(self::TITLE);
-    }
-
-    /**
-     * {@inheritdoc}
-     * @codeCoverageIgnore
-     */
-    public function getSampleType()
-    {
-        return $this->getData(self::SAMPLE_TYPE);
-    }
-
-    /**
-     * {@inheritdoc}
-     * @codeCoverageIgnore
-     */
-    public function getSampleFile()
-    {
-        return $this->getData(self::SAMPLE_FILE);
-    }
-
-    /**
-     * {@inheritdoc}
-     * @codeCoverageIgnore
-     */
-    public function getSortOrder()
-    {
-        return $this->getData(self::SORT_ORDER);
-    }
-
-    /**
-     * {@inheritdoc}
-     * @codeCoverageIgnore
-     */
-    public function getSampleUrl()
-    {
-        return $this->getData(self::SAMPLE_URL);
-    }
-
-    /**
-     * Set sample title
-     *
-     * @param string $title
-     * @return $this
-     */
-    public function setTitle($title)
-    {
-        return $this->setData(self::TITLE, $title);
-    }
-
-    /**
-     * Set sample type ('url' or 'file')
-     *
-     * @param string $sampleType
-     * @return $this
-     */
-    public function setSampleType($sampleType)
-    {
-        return $this->setData(self::SAMPLE_TYPE, $sampleType);
-    }
-
-    /**
-     * Set sample file content
-     *
-     * @param \Magento\Downloadable\Api\Data\File\ContentInterface $sampleFile
-     * @return $this
-     */
-    public function setSampleFile(\Magento\Downloadable\Api\Data\File\ContentInterface $sampleFile = null)
-    {
-        return $this->setData(self::SAMPLE_FILE, $sampleFile);
-    }
-
-    /**
-     * Set sample sort order
-     *
-     * @param int $sortOrder
-     * @return $this
-     */
-    public function setSortOrder($sortOrder)
-    {
-        return $this->setData(self::SORT_ORDER, $sortOrder);
-    }
-
-    /**
-     * Set sample URL
-     *
-     * @param string $sampleUrl
-     * @return $this
-     */
-    public function setSampleUrl($sampleUrl)
-    {
-        return $this->setData(self::SAMPLE_URL, $sampleUrl);
-    }
-
-    /**
-     * {@inheritdoc}
-     *
-     * @return \Magento\Downloadable\Api\Data\SampleContentExtensionInterface|null
-     */
-    public function getExtensionAttributes()
-    {
-        return $this->_getExtensionAttributes();
-    }
-
-    /**
-     * {@inheritdoc}
-     *
-     * @param \Magento\Downloadable\Api\Data\SampleContentExtensionInterface $extensionAttributes
-     * @return $this
-     */
-    public function setExtensionAttributes(
-        \Magento\Downloadable\Api\Data\SampleContentExtensionInterface $extensionAttributes
-    ) {
-        return $this->_setExtensionAttributes($extensionAttributes);
-    }
-}
diff --git a/app/code/Magento/Downloadable/Model/Sample/ContentValidator.php b/app/code/Magento/Downloadable/Model/Sample/ContentValidator.php
index 294bd783d463560a5846eada1cc400f5e6a97ce7..83f44d1a5c1b07c20229193db238f53d93cfad6f 100644
--- a/app/code/Magento/Downloadable/Model/Sample/ContentValidator.php
+++ b/app/code/Magento/Downloadable/Model/Sample/ContentValidator.php
@@ -5,7 +5,7 @@
  */
 namespace Magento\Downloadable\Model\Sample;
 
-use Magento\Downloadable\Api\Data\SampleContentInterface;
+use Magento\Downloadable\Api\Data\SampleInterface;
 use Magento\Downloadable\Model\File\ContentValidator as FileContentValidator;
 use Magento\Framework\Exception\InputException;
 use Magento\Framework\Url\Validator as UrlValidator;
@@ -37,38 +37,41 @@ class ContentValidator
     /**
      * Check if sample content is valid
      *
-     * @param SampleContentInterface $sampleContent
+     * @param SampleInterface $sample
+     * @param bool $validateSampleContent
      * @return bool
      * @throws InputException
      */
-    public function isValid(SampleContentInterface $sampleContent)
+    public function isValid(SampleInterface $sample, $validateSampleContent = true)
     {
-        if (!is_int($sampleContent->getSortOrder()) || $sampleContent->getSortOrder() < 0) {
+        if (!is_int($sample->getSortOrder()) || $sample->getSortOrder() < 0) {
             throw new InputException(__('Sort order must be a positive integer.'));
         }
 
-        $this->validateSampleResource($sampleContent);
+        if ($validateSampleContent) {
+            $this->validateSampleResource($sample);
+        }
         return true;
     }
 
     /**
      * Validate sample resource (file or URL)
      *
-     * @param SampleContentInterface $sampleContent
+     * @param SampleInterface $sample
      * @throws InputException
      * @return void
      */
-    protected function validateSampleResource(SampleContentInterface $sampleContent)
+    protected function validateSampleResource(SampleInterface $sample)
     {
-        $sampleFile = $sampleContent->getSampleFile();
-        if ($sampleContent->getSampleType() == 'file'
+        $sampleFile = $sample->getSampleFileContent();
+        if ($sample->getSampleType() == 'file'
             && (!$sampleFile || !$this->fileContentValidator->isValid($sampleFile))
         ) {
             throw new InputException(__('Provided file content must be valid base64 encoded data.'));
         }
 
-        if ($sampleContent->getSampleType() == 'url'
-            && !$this->urlValidator->isValid($sampleContent->getSampleUrl())
+        if ($sample->getSampleType() == 'url'
+            && !$this->urlValidator->isValid($sample->getSampleUrl())
         ) {
             throw new InputException(__('Sample URL must have valid format.'));
         }
diff --git a/app/code/Magento/Downloadable/Model/SampleRepository.php b/app/code/Magento/Downloadable/Model/SampleRepository.php
index b97702bd9adaf8c143dbf0f62823c460121fe02c..f357e6a5d8541ce450fab6ee85cdb782dd8fcc4e 100644
--- a/app/code/Magento/Downloadable/Model/SampleRepository.php
+++ b/app/code/Magento/Downloadable/Model/SampleRepository.php
@@ -8,12 +8,17 @@ namespace Magento\Downloadable\Model;
 use Magento\Catalog\Api\ProductRepositoryInterface;
 use Magento\Downloadable\Model\SampleFactory;
 use Magento\Downloadable\Api\Data\File\ContentUploaderInterface;
-use Magento\Downloadable\Api\Data\SampleContentInterface;
+use Magento\Downloadable\Api\Data\SampleInterface;
 use Magento\Downloadable\Model\Sample\ContentValidator;
 use Magento\Framework\Exception\InputException;
 use Magento\Framework\Exception\NoSuchEntityException;
 use Magento\Framework\Json\EncoderInterface;
 
+/**
+ * Class SampleRepository
+ * @package Magento\Downloadable\Model
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
 class SampleRepository implements \Magento\Downloadable\Api\SampleRepositoryInterface
 {
     /**
@@ -21,6 +26,11 @@ class SampleRepository implements \Magento\Downloadable\Api\SampleRepositoryInte
      */
     protected $productRepository;
 
+    /**
+     * @var \Magento\Downloadable\Model\Product\Type
+     */
+    protected $downloadableType;
+
     /**
      * @var ContentValidator
      */
@@ -38,6 +48,7 @@ class SampleRepository implements \Magento\Downloadable\Api\SampleRepositoryInte
 
     /**
      * @param ProductRepositoryInterface $productRepository
+     * @param \Magento\Downloadable\Model\Product\Type $downloadableType
      * @param ContentValidator $contentValidator
      * @param ContentUploaderInterface $fileContentUploader
      * @param EncoderInterface $jsonEncoder
@@ -45,12 +56,14 @@ class SampleRepository implements \Magento\Downloadable\Api\SampleRepositoryInte
      */
     public function __construct(
         ProductRepositoryInterface $productRepository,
+        \Magento\Downloadable\Model\Product\Type $downloadableType,
         ContentValidator $contentValidator,
         ContentUploaderInterface $fileContentUploader,
         EncoderInterface $jsonEncoder,
         SampleFactory $sampleFactory
     ) {
         $this->productRepository = $productRepository;
+        $this->downloadableType = $downloadableType;
         $this->contentValidator = $contentValidator;
         $this->fileContentUploader = $fileContentUploader;
         $this->jsonEncoder = $jsonEncoder;
@@ -58,106 +71,153 @@ class SampleRepository implements \Magento\Downloadable\Api\SampleRepositoryInte
     }
 
     /**
-     * {@inheritdoc}
+     * Update downloadable sample of the given product
+     *
+     * @param string $sku
+     * @param \Magento\Downloadable\Api\Data\SampleInterface $sample
+     * @param bool $isGlobalScopeContent
+     * @return int
      * @SuppressWarnings(PHPMD.CyclomaticComplexity)
      */
     public function save(
-        $productSku,
-        SampleContentInterface $sampleContent,
-        $sampleId = null,
+        $sku,
+        SampleInterface $sample,
         $isGlobalScopeContent = false
     ) {
-        $product = $this->productRepository->get($productSku, true);
+        $product = $this->productRepository->get($sku, true);
 
+        $sampleId = $sample->getId();
         if ($sampleId) {
-
-            /** @var $sample \Magento\Downloadable\Model\Sample */
-            $sample = $this->sampleFactory->create()->load($sampleId);
-
-            if (!$sample->getId()) {
-                throw new NoSuchEntityException(__('There is no downloadable sample with provided ID.'));
-            }
-
-            if ($sample->getProductId() != $product->getId()) {
-                throw new InputException(__('Provided downloadable sample is not related to given product.'));
-            }
-            if (!$this->contentValidator->isValid($sampleContent)) {
-                throw new InputException(__('Provided sample information is invalid.'));
-            }
-            if ($isGlobalScopeContent) {
-                $product->setStoreId(0);
-            }
-
-            $title = $sampleContent->getTitle();
-            if (empty($title)) {
-                if ($isGlobalScopeContent) {
-                    throw new InputException(__('Sample title cannot be empty.'));
-                }
-                // use title from GLOBAL scope
-                $sample->setTitle(null);
-            } else {
-                $sample->setTitle($sampleContent->getTitle());
-            }
-
-            $sample->setProductId($product->getId())
-                ->setStoreId($product->getStoreId())
-                ->setSortOrder($sampleContent->getSortOrder())
-                ->save();
-
-            return $sample->getId();
+            return $this->updateSample($product, $sample, $isGlobalScopeContent);
         } else {
-
             if ($product->getTypeId() !== \Magento\Downloadable\Model\Product\Type::TYPE_DOWNLOADABLE) {
                 throw new InputException(__('Product type of the product must be \'downloadable\'.'));
             }
-            if (!$this->contentValidator->isValid($sampleContent)) {
+            if (!$this->contentValidator->isValid($sample)) {
                 throw new InputException(__('Provided sample information is invalid.'));
             }
 
-            if (!in_array($sampleContent->getSampleType(), ['url', 'file'])) {
+            if (!in_array($sample->getSampleType(), ['url', 'file'])) {
                 throw new InputException(__('Invalid sample type.'));
             }
 
-            $title = $sampleContent->getTitle();
+            $title = $sample->getTitle();
             if (empty($title)) {
                 throw new InputException(__('Sample title cannot be empty.'));
             }
 
-            $sampleData = [
-                'sample_id' => 0,
-                'is_delete' => 0,
-                'type' => $sampleContent->getSampleType(),
-                'sort_order' => $sampleContent->getSortOrder(),
-                'title' => $sampleContent->getTitle(),
-            ];
+            return $this->saveSample($product, $sample, $isGlobalScopeContent);
+        }
+    }
 
-            if ($sampleContent->getSampleType() == 'file') {
-                $sampleData['file'] = $this->jsonEncoder->encode(
+    /**
+     * @param \Magento\Catalog\Api\Data\ProductInterface $product
+     * @param SampleInterface $sample
+     * @param bool $isGlobalScopeContent
+     * @return int
+     */
+    protected function saveSample(
+        \Magento\Catalog\Api\Data\ProductInterface $product,
+        SampleInterface $sample,
+        $isGlobalScopeContent
+    ) {
+        $sampleData = [
+            'sample_id' => $sample->getid() === null ? 0 : $sample->getid(),
+            'is_delete' => 0,
+            'type' => $sample->getSampleType(),
+            'sort_order' => $sample->getSortOrder(),
+            'title' => $sample->getTitle(),
+        ];
+
+        if ($sample->getSampleType() == 'file' && $sample->getSampleFile() === null) {
+            $sampleData['file'] = $this->jsonEncoder->encode(
+                [
+                    $this->fileContentUploader->upload($sample->getSampleFileContent(), 'sample'),
+                ]
+            );
+        } elseif ($sample->getSampleType() === 'url') {
+            $sampleData['sample_url'] = $sample->getSampleUrl();
+        } else {
+            //existing file
+            $sampleData['file'] = $this->jsonEncoder->encode(
+                [
                     [
-                        $this->fileContentUploader->upload($sampleContent->getSampleFile(), 'sample'),
-                    ]
-                );
-            } else {
-                $sampleData['sample_url'] = $sampleContent->getSampleUrl();
-            }
+                        'file' => $sample->getSampleFile(),
+                        'status' => 'old',
+                    ],
+                ]
+            );
+        }
+
+        $downloadableData = ['sample' => [$sampleData]];
+        $product->setDownloadableData($downloadableData);
+        if ($isGlobalScopeContent) {
+            $product->setStoreId(0);
+        }
+        $this->downloadableType->save($product);
+        return $product->getLastAddedSampleId();
+    }
+
+    /**
+     * @param \Magento\Catalog\Api\Data\ProductInterface $product
+     * @param SampleInterface $sample
+     * @param bool $isGlobalScopeContent
+     * @return int
+     * @throws InputException
+     * @throws NoSuchEntityException
+     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+     * @SuppressWarnings(PHPMD.NPathComplexity)
+     */
+    protected function updateSample(
+        \Magento\Catalog\Api\Data\ProductInterface $product,
+        SampleInterface $sample,
+        $isGlobalScopeContent
+    ) {
+        $sampleId = $sample->getId();
+        /** @var $existingSample \Magento\Downloadable\Model\Sample */
+        $existingSample = $this->sampleFactory->create()->load($sampleId);
 
-            $downloadableData = ['sample' => [$sampleData]];
-            $product->setDownloadableData($downloadableData);
+        if (!$existingSample->getId()) {
+            throw new NoSuchEntityException(__('There is no downloadable sample with provided ID.'));
+        }
+
+        if ($existingSample->getProductId() != $product->getId()) {
+            throw new InputException(__('Provided downloadable sample is not related to given product.'));
+        }
+
+        $validateFileContent = $sample->getSampleFileContent() === null ? false : true;
+        if (!$this->contentValidator->isValid($sample, $validateFileContent)) {
+            throw new InputException(__('Provided sample information is invalid.'));
+        }
+        if ($isGlobalScopeContent) {
+            $product->setStoreId(0);
+        }
+
+        $title = $sample->getTitle();
+        if (empty($title)) {
             if ($isGlobalScopeContent) {
-                $product->setStoreId(0);
+                throw new InputException(__('Sample title cannot be empty.'));
             }
-            $product->save();
-            return $product->getLastAddedSampleId();
+            // use title from GLOBAL scope
+            $existingSample->setTitle(null);
+        } else {
+            $existingSample->setTitle($sample->getTitle());
+        }
+
+        if ($sample->getSampleType() === 'file' && $sample->getSampleFileContent() === null) {
+            $sample->setSampleFile($existingSample->getSampleFile());
         }
+        $this->saveSample($product, $sample, $isGlobalScopeContent);
+        return $existingSample->getId();
     }
 
     /**
      * {@inheritdoc}
      */
-    public function delete($sampleId)
+    public function delete($id)
     {
         /** @var $sample \Magento\Downloadable\Model\Sample */
-        $sample = $this->sampleFactory->create()->load($sampleId);
+        $sample = $this->sampleFactory->create()->load($id);
         if (!$sample->getId()) {
             throw new NoSuchEntityException(__('There is no downloadable sample with provided ID.'));
         }
diff --git a/app/code/Magento/Downloadable/Test/Unit/Model/Link/ContentValidatorTest.php b/app/code/Magento/Downloadable/Test/Unit/Model/Link/ContentValidatorTest.php
index 6e7a6555514b345535e784fc4b2e3abf8839c195..685d116b2b700cd10a286a22b604b435597ad3bb 100644
--- a/app/code/Magento/Downloadable/Test/Unit/Model/Link/ContentValidatorTest.php
+++ b/app/code/Magento/Downloadable/Test/Unit/Model/Link/ContentValidatorTest.php
@@ -52,12 +52,14 @@ class ContentValidatorTest extends \PHPUnit_Framework_TestCase
         );
         $this->linkFileMock = $this->getMock('\Magento\Downloadable\Api\Data\File\ContentInterface');
         $this->sampleFileMock = $this->getMock('\Magento\Downloadable\Api\Data\File\ContentInterface');
-        $this->validator = new \Magento\Downloadable\Model\Link\ContentValidator($this->fileValidatorMock, $this->urlValidatorMock);
+        $this->validator = new ContentValidator($this->fileValidatorMock, $this->urlValidatorMock);
     }
 
     public function testIsValid()
     {
-        $linkContentData = [
+        $linkFileContentMock = $this->getMock('Magento\Downloadable\Api\Data\File\ContentInterface');
+        $sampleFileContentMock = $this->getMock('Magento\Downloadable\Api\Data\File\ContentInterface');
+        $linkData = [
             'title' => 'Title',
             'sort_order' => 1,
             'price' => 10.1,
@@ -65,11 +67,53 @@ class ContentValidatorTest extends \PHPUnit_Framework_TestCase
             'number_of_downloads' => 100,
             'link_type' => 'file',
             'sample_type' => 'file',
+            'link_file_content' => $linkFileContentMock,
+            'sample_file_content' => $sampleFileContentMock,
         ];
         $this->fileValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true));
         $this->urlValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true));
-        $contentMock = $this->getLinkContentMock($linkContentData);
-        $this->assertTrue($this->validator->isValid($contentMock));
+        $linkMock = $this->getLinkMock($linkData);
+        $this->assertTrue($this->validator->isValid($linkMock));
+    }
+
+    public function testIsValidSkipLinkContent()
+    {
+        $sampleFileContentMock = $this->getMock('Magento\Downloadable\Api\Data\File\ContentInterface');
+        $linkData = [
+            'title' => 'Title',
+            'sort_order' => 1,
+            'price' => 10.1,
+            'shareable' => true,
+            'number_of_downloads' => 100,
+            'link_type' => 'url',
+            'link_url' => 'http://example.com',
+            'sample_type' => 'file',
+            'sample_file_content' => $sampleFileContentMock,
+        ];
+        $this->fileValidatorMock->expects($this->once())->method('isValid')->will($this->returnValue(true));
+        $this->urlValidatorMock->expects($this->never())->method('isValid')->will($this->returnValue(true));
+        $linkMock = $this->getLinkMock($linkData);
+        $this->assertTrue($this->validator->isValid($linkMock, false));
+    }
+
+    public function testIsValidSkipSampleContent()
+    {
+        $sampleFileContentMock = $this->getMock('Magento\Downloadable\Api\Data\File\ContentInterface');
+        $linkData = [
+            'title' => 'Title',
+            'sort_order' => 1,
+            'price' => 10.1,
+            'shareable' => true,
+            'number_of_downloads' => 100,
+            'link_type' => 'url',
+            'link_url' => 'http://example.com',
+            'sample_type' => 'file',
+            'sample_file_content' => $sampleFileContentMock,
+        ];
+        $this->fileValidatorMock->expects($this->never())->method('isValid')->will($this->returnValue(true));
+        $this->urlValidatorMock->expects($this->once())->method('isValid')->will($this->returnValue(true));
+        $linkMock = $this->getLinkMock($linkData);
+        $this->assertTrue($this->validator->isValid($linkMock, true, false));
     }
 
     /**
@@ -91,7 +135,7 @@ class ContentValidatorTest extends \PHPUnit_Framework_TestCase
         ];
         $this->fileValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true));
         $this->urlValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true));
-        $contentMock = $this->getLinkContentMock($linkContentData);
+        $contentMock = $this->getLinkMock($linkContentData);
         $this->validator->isValid($contentMock);
     }
 
@@ -126,7 +170,7 @@ class ContentValidatorTest extends \PHPUnit_Framework_TestCase
         ];
         $this->fileValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true));
         $this->urlValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true));
-        $contentMock = $this->getLinkContentMock($linkContentData);
+        $contentMock = $this->getLinkMock($linkContentData);
         $this->validator->isValid($contentMock);
     }
 
@@ -160,7 +204,7 @@ class ContentValidatorTest extends \PHPUnit_Framework_TestCase
         ];
         $this->urlValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true));
         $this->fileValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true));
-        $contentMock = $this->getLinkContentMock($linkContentData);
+        $contentMock = $this->getLinkMock($linkContentData);
         $this->validator->isValid($contentMock);
     }
 
@@ -177,51 +221,58 @@ class ContentValidatorTest extends \PHPUnit_Framework_TestCase
     }
 
     /**
-     * @param array $linkContentData
+     * @param array $linkData
      * @return \PHPUnit_Framework_MockObject_MockObject
      */
-    protected function getLinkContentMock(array $linkContentData)
+    protected function getLinkMock(array $linkData)
     {
-        $contentMock = $this->getMock('\Magento\Downloadable\Api\Data\LinkContentInterface');
-        $contentMock->expects($this->any())->method('getTitle')->will($this->returnValue(
-            $linkContentData['title']
+        $linkMock = $this->getMock('\Magento\Downloadable\Api\Data\LinkInterface');
+        $linkMock->expects($this->any())->method('getTitle')->will($this->returnValue(
+            $linkData['title']
         ));
-        $contentMock->expects($this->any())->method('getPrice')->will($this->returnValue(
-            $linkContentData['price']
+        $linkMock->expects($this->any())->method('getPrice')->will($this->returnValue(
+            $linkData['price']
         ));
-        $contentMock->expects($this->any())->method('getSortOrder')->will($this->returnValue(
-            $linkContentData['sort_order']
+        $linkMock->expects($this->any())->method('getSortOrder')->will($this->returnValue(
+            $linkData['sort_order']
         ));
-        $contentMock->expects($this->any())->method('isShareable')->will($this->returnValue(
-            $linkContentData['shareable']
+        $linkMock->expects($this->any())->method('isShareable')->will($this->returnValue(
+            $linkData['shareable']
         ));
-        $contentMock->expects($this->any())->method('getNumberOfDownloads')->will($this->returnValue(
-            $linkContentData['number_of_downloads']
+        $linkMock->expects($this->any())->method('getNumberOfDownloads')->will($this->returnValue(
+            $linkData['number_of_downloads']
         ));
-        $contentMock->expects($this->any())->method('getLinkType')->will($this->returnValue(
-            $linkContentData['link_type']
+        $linkMock->expects($this->any())->method('getLinkType')->will($this->returnValue(
+            $linkData['link_type']
         ));
-        $contentMock->expects($this->any())->method('getLinkFile')->will($this->returnValue(
+        $linkMock->expects($this->any())->method('getLinkFile')->will($this->returnValue(
             $this->linkFileMock
         ));
-        if (isset($linkContentData['link_url'])) {
-            $contentMock->expects($this->any())->method('getLinkUrl')->will($this->returnValue(
-                $linkContentData['link_url']
+        if (isset($linkData['link_url'])) {
+            $linkMock->expects($this->any())->method('getLinkUrl')->will($this->returnValue(
+                $linkData['link_url']
             ));
         }
-        if (isset($linkContentData['sample_url'])) {
-            $contentMock->expects($this->any())->method('getSampleUrl')->will($this->returnValue(
-                $linkContentData['sample_url']
+        if (isset($linkData['sample_url'])) {
+            $linkMock->expects($this->any())->method('getSampleUrl')->will($this->returnValue(
+                $linkData['sample_url']
             ));
         }
-        if (isset($linkContentData['sample_type'])) {
-            $contentMock->expects($this->any())->method('getSampleType')->will($this->returnValue(
-                $linkContentData['sample_type']
+        if (isset($linkData['sample_type'])) {
+            $linkMock->expects($this->any())->method('getSampleType')->will($this->returnValue(
+                $linkData['sample_type']
             ));
         }
-        $contentMock->expects($this->any())->method('getSampleFile')->will($this->returnValue(
+        if (isset($linkData['link_file_content'])) {
+            $linkMock->expects($this->any())->method('getLinkFileContent')->willReturn($linkData['link_file_content']);
+        }
+        if (isset($linkData['sample_file_content'])) {
+            $linkMock->expects($this->any())->method('getSampleFileContent')
+                ->willReturn($linkData['sample_file_content']);
+        }
+        $linkMock->expects($this->any())->method('getSampleFile')->will($this->returnValue(
             $this->sampleFileMock
         ));
-        return $contentMock;
+        return $linkMock;
     }
 }
diff --git a/app/code/Magento/Downloadable/Test/Unit/Model/LinkRepositoryTest.php b/app/code/Magento/Downloadable/Test/Unit/Model/LinkRepositoryTest.php
index 06c849f969cd47da2759747c05254ef143d2b759..d4ec184847edcbdbca8feb4e8a08c04f1b664766 100644
--- a/app/code/Magento/Downloadable/Test/Unit/Model/LinkRepositoryTest.php
+++ b/app/code/Magento/Downloadable/Test/Unit/Model/LinkRepositoryTest.php
@@ -128,69 +128,80 @@ class LinkRepositoryTest extends \PHPUnit_Framework_TestCase
     }
 
     /**
-     * @param array $linkContentData
+     * @param array $linkData
      * @return \PHPUnit_Framework_MockObject_MockObject
      */
-    protected function getLinkContentMock(array $linkContentData)
+    protected function getLinkMock(array $linkData)
     {
-        $contentMock = $this->getMock(
-            '\Magento\Downloadable\Api\Data\LinkContentInterface',
+        $linkMock = $this->getMock(
+            '\Magento\Downloadable\Api\Data\LinkInterface',
             [],
             [],
             '',
             false
         );
 
-        $contentMock->expects($this->any())->method('getPrice')->will(
+        if (isset($linkData['id'])) {
+            $linkMock->expects($this->any())->method('getId')->willReturn($linkData['id']);
+        }
+
+        $linkMock->expects($this->any())->method('getPrice')->will(
             $this->returnValue(
-                $linkContentData['price']
+                $linkData['price']
             )
         );
-        $contentMock->expects($this->any())->method('getTitle')->will(
+        $linkMock->expects($this->any())->method('getTitle')->will(
             $this->returnValue(
-                $linkContentData['title']
+                $linkData['title']
             )
         );
-        $contentMock->expects($this->any())->method('getSortOrder')->will(
+        $linkMock->expects($this->any())->method('getSortOrder')->will(
             $this->returnValue(
-                $linkContentData['sort_order']
+                $linkData['sort_order']
             )
         );
-        $contentMock->expects($this->any())->method('getNumberOfDownloads')->will(
+        $linkMock->expects($this->any())->method('getNumberOfDownloads')->will(
             $this->returnValue(
-                $linkContentData['number_of_downloads']
+                $linkData['number_of_downloads']
             )
         );
-        $contentMock->expects($this->any())->method('isShareable')->will(
+        $linkMock->expects($this->any())->method('getIsShareable')->will(
             $this->returnValue(
-                $linkContentData['shareable']
+                $linkData['is_shareable']
             )
         );
-        if (isset($linkContentData['link_type'])) {
-            $contentMock->expects($this->any())->method('getLinkType')->will(
+        if (isset($linkData['link_type'])) {
+            $linkMock->expects($this->any())->method('getLinkType')->will(
                 $this->returnValue(
-                    $linkContentData['link_type']
+                    $linkData['link_type']
                 )
             );
         }
-        if (isset($linkContentData['link_url'])) {
-            $contentMock->expects($this->any())->method('getLinkUrl')->will(
+        if (isset($linkData['link_url'])) {
+            $linkMock->expects($this->any())->method('getLinkUrl')->will(
                 $this->returnValue(
-                    $linkContentData['link_url']
+                    $linkData['link_url']
                 )
             );
         }
-        return $contentMock;
+        if (isset($linkData['link_file'])) {
+            $linkMock->expects($this->any())->method('getLinkFile')->will(
+                $this->returnValue(
+                    $linkData['link_file']
+                )
+            );
+        }
+        return $linkMock;
     }
 
     public function testCreate()
     {
         $productSku = 'simple';
-        $linkContentData = [
+        $linkData = [
             'title' => 'Title',
             'sort_order' => 1,
             'price' => 10.1,
-            'shareable' => true,
+            'is_shareable' => true,
             'number_of_downloads' => 100,
             'link_type' => 'url',
             'link_url' => 'http://example.com/',
@@ -198,8 +209,8 @@ class LinkRepositoryTest extends \PHPUnit_Framework_TestCase
         $this->repositoryMock->expects($this->any())->method('get')->with($productSku, true)
             ->will($this->returnValue($this->productMock));
         $this->productMock->expects($this->any())->method('getTypeId')->will($this->returnValue('downloadable'));
-        $linkContentMock = $this->getLinkContentMock($linkContentData);
-        $this->contentValidatorMock->expects($this->any())->method('isValid')->with($linkContentMock)
+        $linkMock = $this->getLinkMock($linkData);
+        $this->contentValidatorMock->expects($this->any())->method('isValid')->with($linkMock)
             ->will($this->returnValue(true));
 
         $this->productMock->expects($this->once())->method('setDownloadableData')->with(
@@ -208,19 +219,20 @@ class LinkRepositoryTest extends \PHPUnit_Framework_TestCase
                     [
                         'link_id' => 0,
                         'is_delete' => 0,
-                        'type' => $linkContentData['link_type'],
-                        'sort_order' => $linkContentData['sort_order'],
-                        'title' => $linkContentData['title'],
-                        'price' => $linkContentData['price'],
-                        'number_of_downloads' => $linkContentData['number_of_downloads'],
-                        'is_shareable' => $linkContentData['shareable'],
-                        'link_url' => $linkContentData['link_url'],
+                        'type' => $linkData['link_type'],
+                        'sort_order' => $linkData['sort_order'],
+                        'title' => $linkData['title'],
+                        'price' => $linkData['price'],
+                        'number_of_downloads' => $linkData['number_of_downloads'],
+                        'is_shareable' => $linkData['is_shareable'],
+                        'link_url' => $linkData['link_url'],
                     ],
                 ],
             ]
         );
-        $this->productMock->expects($this->once())->method('save');
-        $this->service->save($productSku, $linkContentMock, null);
+        $this->productTypeMock->expects($this->once())->method('save')
+            ->with($this->productMock);
+        $this->service->save($productSku, $linkMock);
     }
 
     /**
@@ -230,12 +242,12 @@ class LinkRepositoryTest extends \PHPUnit_Framework_TestCase
     public function testCreateThrowsExceptionIfTitleIsEmpty()
     {
         $productSku = 'simple';
-        $linkContentData = [
+        $linkData = [
             'title' => '',
             'sort_order' => 1,
             'price' => 10.1,
             'number_of_downloads' => 100,
-            'shareable' => true,
+            'is_shareable' => true,
             'link_type' => 'url',
             'link_url' => 'http://example.com/',
         ];
@@ -243,13 +255,13 @@ class LinkRepositoryTest extends \PHPUnit_Framework_TestCase
         $this->productMock->expects($this->any())->method('getTypeId')->will($this->returnValue('downloadable'));
         $this->repositoryMock->expects($this->any())->method('get')->with($productSku, true)
             ->will($this->returnValue($this->productMock));
-        $linkContentMock = $this->getLinkContentMock($linkContentData);
-        $this->contentValidatorMock->expects($this->any())->method('isValid')->with($linkContentMock)
+        $linkMock = $this->getLinkMock($linkData);
+        $this->contentValidatorMock->expects($this->any())->method('isValid')->with($linkMock)
             ->will($this->returnValue(true));
 
         $this->productMock->expects($this->never())->method('save');
 
-        $this->service->save($productSku, $linkContentMock, null);
+        $this->service->save($productSku, $linkMock);
     }
 
     public function testUpdate()
@@ -258,12 +270,15 @@ class LinkRepositoryTest extends \PHPUnit_Framework_TestCase
         $linkId = 1;
         $productSku = 'simple';
         $productId = 1;
-        $linkContentData = [
+        $linkData = [
+            'id' => $linkId,
             'title' => 'Updated Title',
             'sort_order' => 1,
             'price' => 10.1,
-            'shareable' => true,
+            'is_shareable' => true,
             'number_of_downloads' => 100,
+            'link_type' => 'url',
+            'link_url' => 'http://example.com/',
         ];
         $this->repositoryMock->expects($this->any())->method('get')->with($productSku, true)
             ->will($this->returnValue($this->productMock));
@@ -271,54 +286,126 @@ class LinkRepositoryTest extends \PHPUnit_Framework_TestCase
         $storeMock = $this->getMock('\Magento\Store\Model\Store', [], [], '', false);
         $storeMock->expects($this->any())->method('getWebsiteId')->will($this->returnValue($websiteId));
         $this->productMock->expects($this->any())->method('getStore')->will($this->returnValue($storeMock));
-        $linkMock = $this->getMock(
+        $existingLinkMock = $this->getMock(
             '\Magento\Downloadable\Model\Link',
             [
                 '__wakeup',
-                'setTitle',
-                'setPrice',
-                'setSortOrder',
-                'setIsShareable',
-                'setNumberOfDownloads',
                 'getId',
-                'setProductId',
-                'setStoreId',
-                'setWebsiteId',
-                'setProductWebsiteIds',
                 'load',
-                'save',
                 'getProductId'
             ],
             [],
             '',
             false
         );
-        $this->linkFactoryMock->expects($this->once())->method('create')->will($this->returnValue($linkMock));
-        $linkContentMock = $this->getLinkContentMock($linkContentData);
-        $this->contentValidatorMock->expects($this->any())->method('isValid')->with($linkContentMock)
+        $this->linkFactoryMock->expects($this->once())->method('create')->will($this->returnValue($existingLinkMock));
+        $linkMock = $this->getLinkMock($linkData);
+        $this->contentValidatorMock->expects($this->any())->method('isValid')->with($linkMock)
             ->will($this->returnValue(true));
 
-        $linkMock->expects($this->any())->method('getId')->will($this->returnValue($linkId));
-        $linkMock->expects($this->any())->method('getProductId')->will($this->returnValue($productId));
-        $linkMock->expects($this->once())->method('load')->with($linkId)->will($this->returnSelf());
-        $linkMock->expects($this->once())->method('setTitle')->with($linkContentData['title'])
-            ->will($this->returnSelf());
-        $linkMock->expects($this->once())->method('setSortOrder')->with($linkContentData['sort_order'])
-            ->will($this->returnSelf());
-        $linkMock->expects($this->once())->method('setPrice')->with($linkContentData['price'])
-            ->will($this->returnSelf());
-        $linkMock->expects($this->once())->method('setIsShareable')->with($linkContentData['shareable'])
-            ->will($this->returnSelf());
-        $linkMock->expects($this->once())->method('setNumberOfDownloads')->with($linkContentData['number_of_downloads'])
-            ->will($this->returnSelf());
-        $linkMock->expects($this->once())->method('setProductId')->with($productId)
-            ->will($this->returnSelf());
-        $linkMock->expects($this->once())->method('setStoreId')->will($this->returnSelf());
-        $linkMock->expects($this->once())->method('setWebsiteId')->with($websiteId)->will($this->returnSelf());
-        $linkMock->expects($this->once())->method('setProductWebsiteIds')->will($this->returnSelf());
-        $linkMock->expects($this->once())->method('save')->will($this->returnSelf());
-
-        $this->assertEquals($linkId, $this->service->save($productSku, $linkContentMock, $linkId));
+        $existingLinkMock->expects($this->any())->method('getId')->will($this->returnValue($linkId));
+        $existingLinkMock->expects($this->any())->method('getProductId')->will($this->returnValue($productId));
+        $existingLinkMock->expects($this->once())->method('load')->with($linkId)->will($this->returnSelf());
+
+        $this->productMock->expects($this->once())->method('setDownloadableData')->with(
+            [
+                'link' => [
+                    [
+                        'link_id' => $linkId,
+                        'is_delete' => 0,
+                        'type' => $linkData['link_type'],
+                        'sort_order' => $linkData['sort_order'],
+                        'title' => $linkData['title'],
+                        'price' => $linkData['price'],
+                        'number_of_downloads' => $linkData['number_of_downloads'],
+                        'is_shareable' => $linkData['is_shareable'],
+                        'link_url' => $linkData['link_url'],
+                    ],
+                ],
+            ]
+        );
+        $this->productTypeMock->expects($this->once())->method('save')
+            ->with($this->productMock);
+
+        $this->assertEquals($linkId, $this->service->save($productSku, $linkMock));
+    }
+
+    public function testUpdateWithExistingFile()
+    {
+        $websiteId = 1;
+        $linkId = 1;
+        $productSku = 'simple';
+        $productId = 1;
+        $linkFile = '/l/i/link.jpg';
+        $encodedFiles = "something";
+        $linkData = [
+            'id' => $linkId,
+            'title' => 'Updated Title',
+            'sort_order' => 1,
+            'price' => 10.1,
+            'is_shareable' => true,
+            'number_of_downloads' => 100,
+            'link_type' => 'file',
+            'link_file' => $linkFile,
+        ];
+        $this->repositoryMock->expects($this->any())->method('get')->with($productSku, true)
+            ->will($this->returnValue($this->productMock));
+        $this->productMock->expects($this->any())->method('getId')->will($this->returnValue($productId));
+        $storeMock = $this->getMock('\Magento\Store\Model\Store', [], [], '', false);
+        $storeMock->expects($this->any())->method('getWebsiteId')->will($this->returnValue($websiteId));
+        $this->productMock->expects($this->any())->method('getStore')->will($this->returnValue($storeMock));
+        $existingLinkMock = $this->getMock(
+            '\Magento\Downloadable\Model\Link',
+            [
+                '__wakeup',
+                'getId',
+                'load',
+                'getProductId'
+            ],
+            [],
+            '',
+            false
+        );
+        $this->linkFactoryMock->expects($this->once())->method('create')->will($this->returnValue($existingLinkMock));
+        $linkMock = $this->getLinkMock($linkData);
+        $this->contentValidatorMock->expects($this->any())->method('isValid')->with($linkMock)
+            ->will($this->returnValue(true));
+
+        $existingLinkMock->expects($this->any())->method('getId')->will($this->returnValue($linkId));
+        $existingLinkMock->expects($this->any())->method('getProductId')->will($this->returnValue($productId));
+        $existingLinkMock->expects($this->once())->method('load')->with($linkId)->will($this->returnSelf());
+
+        $this->jsonEncoderMock->expects($this->once())
+            ->method('encode')
+            ->with(
+                [
+                    [
+                        'file' => $linkFile,
+                        'status' => 'old'
+                    ]
+                ]
+            )->willReturn($encodedFiles);
+        $this->productMock->expects($this->once())->method('setDownloadableData')->with(
+            [
+                'link' => [
+                    [
+                        'link_id' => $linkId,
+                        'is_delete' => 0,
+                        'type' => $linkData['link_type'],
+                        'sort_order' => $linkData['sort_order'],
+                        'title' => $linkData['title'],
+                        'price' => $linkData['price'],
+                        'number_of_downloads' => $linkData['number_of_downloads'],
+                        'is_shareable' => $linkData['is_shareable'],
+                        'file' => $encodedFiles,
+                    ],
+                ],
+            ]
+        );
+        $this->productTypeMock->expects($this->once())->method('save')
+            ->with($this->productMock);
+
+        $this->assertEquals($linkId, $this->service->save($productSku, $linkMock));
     }
 
     /**
@@ -330,34 +417,34 @@ class LinkRepositoryTest extends \PHPUnit_Framework_TestCase
         $linkId = 1;
         $productSku = 'simple';
         $productId = 1;
-        $linkContentData = [
+        $linkData = [
+            'id' => $linkId,
             'title' => '',
             'sort_order' => 1,
             'price' => 10.1,
             'number_of_downloads' => 100,
-            'shareable' => true,
+            'is_shareable' => true,
         ];
         $this->repositoryMock->expects($this->any())->method('get')->with($productSku, true)
             ->will($this->returnValue($this->productMock));
         $this->productMock->expects($this->any())->method('getId')->will($this->returnValue($productId));
-        $linkMock = $this->getMock(
+        $existingLinkMock = $this->getMock(
             '\Magento\Downloadable\Model\Link',
             ['__wakeup', 'getId', 'load', 'save', 'getProductId'],
             [],
             '',
             false
         );
-        $linkMock->expects($this->any())->method('getId')->will($this->returnValue($linkId));
-        $linkMock->expects($this->any())->method('getProductId')->will($this->returnValue($productId));
-        $linkMock->expects($this->once())->method('load')->with($linkId)->will($this->returnSelf());
-        $this->linkFactoryMock->expects($this->once())->method('create')->will($this->returnValue($linkMock));
-        $linkContentMock = $this->getLinkContentMock($linkContentData);
+        $existingLinkMock->expects($this->any())->method('getId')->will($this->returnValue($linkId));
+        $existingLinkMock->expects($this->any())->method('getProductId')->will($this->returnValue($productId));
+        $existingLinkMock->expects($this->once())->method('load')->with($linkId)->will($this->returnSelf());
+        $this->linkFactoryMock->expects($this->once())->method('create')->will($this->returnValue($existingLinkMock));
+        $linkContentMock = $this->getLinkMock($linkData);
         $this->contentValidatorMock->expects($this->any())->method('isValid')->with($linkContentMock)
             ->will($this->returnValue(true));
 
-        $linkMock->expects($this->never())->method('save');
-
-        $this->service->save($productSku, $linkContentMock, $linkId, true);
+        $this->productTypeMock->expects($this->never())->method('save');
+        $this->service->save($productSku, $linkContentMock, true);
     }
 
     public function testDelete()
diff --git a/app/code/Magento/Downloadable/Test/Unit/Model/ObserverTest.php b/app/code/Magento/Downloadable/Test/Unit/Model/ObserverTest.php
index 99fb7ed07618d23e136ce710af5ddb93010b97aa..f372aaa2451400888c72491ba1607e751d69dc0a 100644
--- a/app/code/Magento/Downloadable/Test/Unit/Model/ObserverTest.php
+++ b/app/code/Magento/Downloadable/Test/Unit/Model/ObserverTest.php
@@ -497,6 +497,33 @@ class ObserverTest extends \PHPUnit_Framework_TestCase
         $this->assertInstanceOf('\Magento\Downloadable\Model\Observer', $result);
     }
 
+    public function testSaveDownloadableOrderItemNotDownloadableItem()
+    {
+        $itemId = 100;
+        $itemMock = $this->getMockBuilder('\Magento\Sales\Model\Order\Item')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $itemMock->expects($this->any())
+            ->method('getId')
+            ->willReturn($itemId);
+        $itemMock->expects($this->any())
+            ->method('getProductType')
+            ->willReturn('simple');
+        $itemMock->expects($this->never())
+            ->method('getProduct');
+        $event = new \Magento\Framework\Object(
+            [
+                'item' => $itemMock,
+            ]
+        );
+        $observer = new \Magento\Framework\Object(
+            [
+                'event' => $event
+            ]
+        );
+        $this->observer->saveDownloadableOrderItem($observer);
+    }
+
     /**
      * @param $id
      * @param int $statusId
diff --git a/app/code/Magento/Downloadable/Test/Unit/Model/Plugin/AfterProductLoadTest.php b/app/code/Magento/Downloadable/Test/Unit/Model/Plugin/AfterProductLoadTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..36f21e6fb5f28382cca4f4bec106d5772d125ec2
--- /dev/null
+++ b/app/code/Magento/Downloadable/Test/Unit/Model/Plugin/AfterProductLoadTest.php
@@ -0,0 +1,220 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+// @codingStandardsIgnoreFile
+
+namespace Magento\Downloadable\Test\Unit\Model\Plugin;
+
+class AfterProductLoadTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Downloadable\Model\Plugin\AfterProductLoad
+     */
+    protected $model;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $linkRepositoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productExtensionMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productExtensionFactory;
+
+    protected function setUp()
+    {
+        $this->linkRepositoryMock = $this->getMock('\Magento\Downloadable\Api\LinkRepositoryInterface');
+        $this->productExtensionFactory = $this->getMockBuilder('\Magento\Catalog\Api\Data\ProductExtensionFactory')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->model = new \Magento\Downloadable\Model\Plugin\AfterProductLoad(
+            $this->linkRepositoryMock,
+            $this->productExtensionFactory
+        );
+        $this->productMock = $this->getMockBuilder('\Magento\Catalog\Model\Product')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->productExtensionMock = $this->getMockBuilder('\Magento\Catalog\Api\Data\ProductExtension')
+            ->setMethods(['setDownloadableProductLinks', 'setDownloadableProductSamples'])->getMock();
+    }
+
+    public function testAfterLoad()
+    {
+        $this->productMock->expects($this->once())
+            ->method('getTypeId')
+            ->willReturn(\Magento\Downloadable\Model\Product\Type::TYPE_DOWNLOADABLE);
+
+        $this->productExtensionFactory->expects($this->once())
+            ->method('create')
+            ->willReturn($this->productExtensionMock);
+
+        $linkMock = $this->getMock('\Magento\Downloadable\Api\Data\LinkInterface');
+        $this->linkRepositoryMock->expects($this->once())
+            ->method('getLinksByProduct')
+            ->with($this->productMock)
+            ->willReturn([$linkMock]);
+        $sampleMock = $this->getMock('\Magento\Downloadable\Api\Data\SampleInterface');
+        $this->linkRepositoryMock->expects($this->once())
+            ->method('getSamplesByProduct')
+            ->with($this->productMock)
+            ->willReturn([$sampleMock]);
+        $this->productExtensionMock->expects($this->once())
+            ->method('setDownloadableProductLinks')
+            ->with([$linkMock])
+            ->willReturnSelf();
+        $this->productExtensionMock->expects($this->once())
+            ->method('setDownloadableProductSamples')
+            ->with([$sampleMock])
+            ->willReturnSelf();
+        $this->productMock->expects($this->once())
+            ->method('setExtensionAttributes')
+            ->with($this->productExtensionMock)
+            ->willReturnSelf();
+
+        $this->assertEquals(
+            $this->productMock,
+            $this->model->afterLoad($this->productMock)
+        );
+    }
+
+    public function testAfterLoadWithExistingExtensionAttributes()
+    {
+        $this->productMock->expects($this->once())
+            ->method('getTypeId')
+            ->willReturn(\Magento\Downloadable\Model\Product\Type::TYPE_DOWNLOADABLE);
+        $this->productMock->expects($this->once())
+            ->method('getExtensionAttributes')
+            ->willReturn($this->productExtensionMock);
+
+        $this->productExtensionFactory->expects($this->never())
+            ->method('create');
+
+        $linkMock = $this->getMock('\Magento\Downloadable\Api\Data\LinkInterface');
+        $this->linkRepositoryMock->expects($this->once())
+            ->method('getLinksByProduct')
+            ->with($this->productMock)
+            ->willReturn([$linkMock]);
+        $sampleMock = $this->getMock('\Magento\Downloadable\Api\Data\SampleInterface');
+        $this->linkRepositoryMock->expects($this->once())
+            ->method('getSamplesByProduct')
+            ->with($this->productMock)
+            ->willReturn([$sampleMock]);
+        $this->productExtensionMock->expects($this->once())
+            ->method('setDownloadableProductLinks')
+            ->with([$linkMock])
+            ->willReturnSelf();
+        $this->productExtensionMock->expects($this->once())
+            ->method('setDownloadableProductSamples')
+            ->with([$sampleMock])
+            ->willReturnSelf();
+        $this->productMock->expects($this->once())
+            ->method('setExtensionAttributes')
+            ->with($this->productExtensionMock)
+            ->willReturnSelf();
+
+        $this->assertEquals(
+            $this->productMock,
+            $this->model->afterLoad($this->productMock)
+        );
+    }
+
+    public function testAfterLoadOnlyLinks()
+    {
+        $this->productMock->expects($this->once())
+            ->method('getTypeId')
+            ->willReturn(\Magento\Downloadable\Model\Product\Type::TYPE_DOWNLOADABLE);
+
+        $this->productExtensionFactory->expects($this->once())
+            ->method('create')
+            ->willReturn($this->productExtensionMock);
+
+        $linkMock = $this->getMock('\Magento\Downloadable\Api\Data\LinkInterface');
+        $this->linkRepositoryMock->expects($this->once())
+            ->method('getLinksByProduct')
+            ->with($this->productMock)
+            ->willReturn([$linkMock]);
+        $this->linkRepositoryMock->expects($this->once())
+            ->method('getSamplesByProduct')
+            ->with($this->productMock)
+            ->willReturn(null);
+        $this->productExtensionMock->expects($this->once())
+            ->method('setDownloadableProductLinks')
+            ->with([$linkMock])
+            ->willReturnSelf();
+        $this->productExtensionMock->expects($this->never())
+            ->method('setDownloadableProductSamples');
+        $this->productMock->expects($this->once())
+            ->method('setExtensionAttributes')
+            ->with($this->productExtensionMock)
+            ->willReturnSelf();
+
+        $this->assertEquals(
+            $this->productMock,
+            $this->model->afterLoad($this->productMock)
+        );
+    }
+
+    public function testAfterLoadOnlySamples()
+    {
+        $this->productMock->expects($this->once())
+            ->method('getTypeId')
+            ->willReturn(\Magento\Downloadable\Model\Product\Type::TYPE_DOWNLOADABLE);
+
+        $this->productExtensionFactory->expects($this->once())
+            ->method('create')
+            ->willReturn($this->productExtensionMock);
+
+        $this->linkRepositoryMock->expects($this->once())
+            ->method('getLinksByProduct')
+            ->with($this->productMock)
+            ->willReturn(null);
+        $sampleMock = $this->getMock('\Magento\Downloadable\Api\Data\SampleInterface');
+        $this->linkRepositoryMock->expects($this->once())
+            ->method('getSamplesByProduct')
+            ->with($this->productMock)
+            ->willReturn([$sampleMock]);
+        $this->productExtensionMock->expects($this->never())
+            ->method('setDownloadableProductLinks');
+        $this->productExtensionMock->expects($this->once())
+            ->method('setDownloadableProductSamples')
+            ->with([$sampleMock])
+            ->willReturnSelf();
+        $this->productMock->expects($this->once())
+            ->method('setExtensionAttributes')
+            ->with($this->productExtensionMock)
+            ->willReturnSelf();
+
+        $this->assertEquals(
+            $this->productMock,
+            $this->model->afterLoad($this->productMock)
+        );
+    }
+
+    public function testAfterLoadIfProductTypeNotDownloadable()
+    {
+        $this->productMock->expects($this->once())
+            ->method('getTypeId')
+            ->willReturn(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE);
+        $this->productMock->expects($this->never())->method('getExtensionAttributes');
+        $this->productMock->expects($this->never())->method('setExtensionAttributes');
+        $this->assertEquals(
+            $this->productMock,
+            $this->model->afterLoad($this->productMock)
+        );
+    }
+}
diff --git a/app/code/Magento/Downloadable/Test/Unit/Model/Plugin/AroundProductRepositorySaveTest.php b/app/code/Magento/Downloadable/Test/Unit/Model/Plugin/AroundProductRepositorySaveTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..e33241defa659ee03c309c4ca74fe85b237a9b07
--- /dev/null
+++ b/app/code/Magento/Downloadable/Test/Unit/Model/Plugin/AroundProductRepositorySaveTest.php
@@ -0,0 +1,328 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+// @codingStandardsIgnoreFile
+
+namespace Magento\Downloadable\Test\Unit\Model\Plugin;
+
+use \Magento\Downloadable\Model\Plugin\AroundProductRepositorySave;
+
+class AroundProductRepositorySaveTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var AroundProductRepositorySave
+     */
+    protected $model;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productRepositoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $linkRepositoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $sampleRepositoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $savedProductMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productExtensionMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $existingProductExtensionMock;
+
+    /**
+     * @var \Closure
+     */
+    protected $closureMock;
+
+    protected function setUp()
+    {
+        $this->productRepositoryMock = $this->getMock('Magento\Catalog\Api\ProductRepositoryInterface');
+        $this->linkRepositoryMock = $this->getMock('Magento\Downloadable\Api\LinkRepositoryInterface');
+        $this->sampleRepositoryMock = $this->getMock('Magento\Downloadable\Api\SampleRepositoryInterface');
+        $this->productMock = $this->getMock('\Magento\Catalog\Api\Data\ProductInterface');
+        $this->savedProductMock = $this->getMock('\Magento\Catalog\Api\Data\ProductInterface');
+        $this->closureMock = function () {
+            return $this->savedProductMock;
+        };
+        $this->model = new AroundProductRepositorySave(
+            $this->linkRepositoryMock,
+            $this->sampleRepositoryMock        );
+        $this->productExtensionMock = $this->getMockBuilder('Magento\Catalog\Api\Data\ProductExtension')
+            ->setMethods(['getDownloadableProductLinks', 'getDownloadableProductSamples'])->getMock();
+        $this->existingProductExtensionMock = $this->getMockBuilder('Magento\Catalog\Api\Data\ProductExtension')
+            ->setMethods(['getDownloadableProductLinks', 'getDownloadableProductSamples'])
+            ->getMock();
+    }
+
+    public function testAroundSaveWhenProductIsSimple()
+    {
+        $this->productMock->expects($this->once())->method('getTypeId')->willReturn('simple');
+        $this->productMock->expects($this->never())->method('getExtensionAttributes');
+
+        $this->assertEquals(
+            $this->savedProductMock,
+            $this->model->aroundSave($this->productRepositoryMock, $this->closureMock, $this->productMock)
+        );
+    }
+
+    public function testAroundSaveWhenProductHasNoExtensionAttributes()
+    {
+        $this->productMock->expects($this->once())->method('getTypeId')
+            ->willReturn(\Magento\Downloadable\Model\Product\Type::TYPE_DOWNLOADABLE);
+        $this->productMock->expects($this->once())
+            ->method('getExtensionAttributes')
+            ->willReturn(null);
+
+        $this->savedProductMock->expects($this->never())->method('getExtensionAttributes');
+        $this->linkRepositoryMock->expects($this->never())->method('save');
+
+        $this->assertEquals(
+            $this->savedProductMock,
+            $this->model->aroundSave($this->productRepositoryMock, $this->closureMock, $this->productMock)
+        );
+    }
+
+    /**
+     * Input has two links and two samples, one existing and one new
+     * Existing product has two links and two samples, one will be updated and one will be deleted
+     */
+    public function testAroundSave()
+    {
+        $productSku = "downloadable_product";
+        $existingLinkId = '2';
+        $existingSampleId = '5';
+        $toBeDeletedLinkId = '3';
+        $toBeDeletedSampleId = '4';
+
+        $this->productMock->expects($this->once())->method('getTypeId')
+            ->willReturn(\Magento\Downloadable\Model\Product\Type::TYPE_DOWNLOADABLE);
+        $this->productMock->expects($this->once())
+            ->method('getExtensionAttributes')
+            ->willReturn($this->productExtensionMock);
+        $updateLinkMock = $this->getMock('\Magento\Downloadable\Api\Data\LinkInterface');
+        $updateLinkMock->expects($this->once())->method('getId')->willReturn($existingLinkId);
+        $newLinkMock = $this->getMock('\Magento\Downloadable\Api\Data\LinkInterface');
+        $newLinkMock->expects($this->once())->method('getId')->willReturn(null);
+        $this->productExtensionMock->expects($this->once())
+            ->method('getDownloadableProductLinks')
+            ->willReturn([$newLinkMock, $updateLinkMock]);
+
+        $updateSampleMock = $this->getMock('\Magento\Downloadable\Api\Data\SampleInterface');
+        $updateSampleMock->expects($this->once())->method('getId')->willReturn($existingSampleId);
+        $newSampleMock = $this->getMock('\Magento\Downloadable\Api\Data\SampleInterface');
+        $newSampleMock->expects($this->once())->method('getId')->willReturn(null);
+        $this->productExtensionMock->expects($this->once())
+            ->method('getDownloadableProductSamples')
+            ->willReturn([$updateSampleMock, $newSampleMock]);
+
+        $existingLinkMock = $this->getMock('\Magento\Downloadable\Api\Data\LinkInterface');
+        $existingLinkMock->expects($this->once())->method('getId')->willReturn($existingLinkId);
+        $toBeDeletedLinkMock = $this->getMock('\Magento\Downloadable\Api\Data\LinkInterface');
+        $toBeDeletedLinkMock->expects($this->once())->method('getId')->willReturn($toBeDeletedLinkId);
+
+        $existingSampleMock = $this->getMock('\Magento\Downloadable\Api\Data\SampleInterface');
+        $existingSampleMock->expects($this->once())->method('getId')->willReturn($existingSampleId);
+        $toBeDeletedSampleMock = $this->getMock('\Magento\Downloadable\Api\Data\SampleInterface');
+        $toBeDeletedSampleMock->expects($this->once())->method('getId')->willReturn($toBeDeletedSampleId);
+
+        $this->savedProductMock->expects($this->any())->method('getSku')->willReturn($productSku);
+        $this->savedProductMock->expects($this->exactly(2))->method('getExtensionAttributes')
+            ->willReturn($this->existingProductExtensionMock);
+        $this->existingProductExtensionMock->expects($this->once())
+            ->method('getDownloadableProductLinks')
+            ->willReturn([$existingLinkMock, $toBeDeletedLinkMock]);
+        $this->existingProductExtensionMock->expects($this->once())
+            ->method('getDownloadableProductSamples')
+            ->willReturn([$existingSampleMock, $toBeDeletedSampleMock]);
+
+        $this->linkRepositoryMock->expects($this->at(0))
+            ->method('save')
+            ->with($productSku, $updateLinkMock);
+        $this->linkRepositoryMock->expects($this->at(1))
+            ->method('save')
+            ->with($productSku, $newLinkMock);
+        $this->linkRepositoryMock->expects($this->at(2))
+            ->method('delete')
+            ->with($toBeDeletedLinkId);
+
+        $this->sampleRepositoryMock->expects($this->at(0))
+            ->method('save')
+            ->with($productSku, $updateSampleMock);
+        $this->sampleRepositoryMock->expects($this->at(1))
+            ->method('save')
+            ->with($productSku, $newSampleMock);
+        $this->sampleRepositoryMock->expects($this->at(2))
+            ->method('delete')
+            ->with($toBeDeletedSampleId);
+
+        $newProductMock = $this->getMockBuilder('Magento\Catalog\Api\Data\ProductInterface')
+            ->disableOriginalConstructor()->getMock();
+        $this->productRepositoryMock->expects($this->once())
+            ->method('get')
+            ->with($productSku, false, null, true)
+            ->willReturn($newProductMock);
+
+        $this->assertEquals(
+            $newProductMock,
+            $this->model->aroundSave($this->productRepositoryMock, $this->closureMock, $this->productMock)
+        );
+    }
+
+    /**
+     * Input has two links and no samples, one existing and one new
+     * Existing product has two links, one will be updated and one will be deleted
+     */
+    public function testAroundSaveWithOnlyLinks()
+    {
+        $productSku = "downloadable_product";
+        $existingLinkId = '2';
+        $toBeDeletedLinkId = '3';
+
+        $this->productMock->expects($this->once())->method('getTypeId')
+            ->willReturn(\Magento\Downloadable\Model\Product\Type::TYPE_DOWNLOADABLE);
+        $this->productMock->expects($this->once())
+            ->method('getExtensionAttributes')
+            ->willReturn($this->productExtensionMock);
+        $updateLinkMock = $this->getMock('\Magento\Downloadable\Api\Data\LinkInterface');
+        $updateLinkMock->expects($this->once())->method('getId')->willReturn($existingLinkId);
+        $newLinkMock = $this->getMock('\Magento\Downloadable\Api\Data\LinkInterface');
+        $newLinkMock->expects($this->once())->method('getId')->willReturn(null);
+        $this->productExtensionMock->expects($this->once())
+            ->method('getDownloadableProductLinks')
+            ->willReturn([$newLinkMock, $updateLinkMock]);
+
+        $this->productExtensionMock->expects($this->once())
+            ->method('getDownloadableProductSamples')
+            ->willReturn(null);
+
+        $existingLinkMock = $this->getMock('\Magento\Downloadable\Api\Data\LinkInterface');
+        $existingLinkMock->expects($this->once())->method('getId')->willReturn($existingLinkId);
+        $toBeDeletedLinkMock = $this->getMock('\Magento\Downloadable\Api\Data\LinkInterface');
+        $toBeDeletedLinkMock->expects($this->once())->method('getId')->willReturn($toBeDeletedLinkId);
+
+        $this->savedProductMock->expects($this->any())->method('getSku')->willReturn($productSku);
+        $this->savedProductMock->expects($this->once())->method('getExtensionAttributes')
+            ->willReturn($this->existingProductExtensionMock);
+        $this->existingProductExtensionMock->expects($this->once())
+            ->method('getDownloadableProductLinks')
+            ->willReturn([$existingLinkMock, $toBeDeletedLinkMock]);
+        $this->existingProductExtensionMock->expects($this->never())
+            ->method('getDownloadableProductSamples');
+
+        $this->linkRepositoryMock->expects($this->at(0))
+            ->method('save')
+            ->with($productSku, $updateLinkMock);
+        $this->linkRepositoryMock->expects($this->at(1))
+            ->method('save')
+            ->with($productSku, $newLinkMock);
+        $this->linkRepositoryMock->expects($this->at(2))
+            ->method('delete')
+            ->with($toBeDeletedLinkId);
+
+        $this->sampleRepositoryMock->expects($this->never())
+            ->method('save');
+
+        $newProductMock = $this->getMockBuilder('Magento\Catalog\Api\Data\ProductInterface')
+            ->disableOriginalConstructor()->getMock();
+        $this->productRepositoryMock->expects($this->once())
+            ->method('get')
+            ->with($productSku, false, null, true)
+            ->willReturn($newProductMock);
+
+        $this->assertEquals(
+            $newProductMock,
+            $this->model->aroundSave($this->productRepositoryMock, $this->closureMock, $this->productMock)
+        );
+    }
+
+    /**
+     * Input has two samples, one existing and one new
+     * Existing product has two samples, one will be updated and one will be deleted
+     */
+    public function testAroundSaveWithOnlySamples()
+    {
+        $productSku = "downloadable_product";
+        $existingSampleId = '5';
+        $toBeDeletedSampleId = '4';
+
+        $this->productMock->expects($this->once())->method('getTypeId')
+            ->willReturn(\Magento\Downloadable\Model\Product\Type::TYPE_DOWNLOADABLE);
+        $this->productMock->expects($this->once())
+            ->method('getExtensionAttributes')
+            ->willReturn($this->productExtensionMock);
+        $this->productExtensionMock->expects($this->once())
+            ->method('getDownloadableProductLinks')
+            ->willReturn(null);
+
+        $updateSampleMock = $this->getMock('\Magento\Downloadable\Api\Data\SampleInterface');
+        $updateSampleMock->expects($this->once())->method('getId')->willReturn($existingSampleId);
+        $newSampleMock = $this->getMock('\Magento\Downloadable\Api\Data\SampleInterface');
+        $newSampleMock->expects($this->once())->method('getId')->willReturn(null);
+        $this->productExtensionMock->expects($this->once())
+            ->method('getDownloadableProductSamples')
+            ->willReturn([$updateSampleMock, $newSampleMock]);
+
+        $existingSampleMock = $this->getMock('\Magento\Downloadable\Api\Data\SampleInterface');
+        $existingSampleMock->expects($this->once())->method('getId')->willReturn($existingSampleId);
+        $toBeDeletedSampleMock = $this->getMock('\Magento\Downloadable\Api\Data\SampleInterface');
+        $toBeDeletedSampleMock->expects($this->once())->method('getId')->willReturn($toBeDeletedSampleId);
+
+        $this->savedProductMock->expects($this->any())->method('getSku')->willReturn($productSku);
+        $this->savedProductMock->expects($this->once())->method('getExtensionAttributes')
+            ->willReturn($this->existingProductExtensionMock);
+        $this->existingProductExtensionMock->expects($this->never())
+            ->method('getDownloadableProductLinks');
+        $this->existingProductExtensionMock->expects($this->once())
+            ->method('getDownloadableProductSamples')
+            ->willReturn([$existingSampleMock, $toBeDeletedSampleMock]);
+
+        $this->linkRepositoryMock->expects($this->never())
+            ->method('save');
+
+        $this->sampleRepositoryMock->expects($this->at(0))
+            ->method('save')
+            ->with($productSku, $updateSampleMock);
+        $this->sampleRepositoryMock->expects($this->at(1))
+            ->method('save')
+            ->with($productSku, $newSampleMock);
+        $this->sampleRepositoryMock->expects($this->at(2))
+            ->method('delete')
+            ->with($toBeDeletedSampleId);
+
+        $newProductMock = $this->getMockBuilder('Magento\Catalog\Api\Data\ProductInterface')
+            ->disableOriginalConstructor()->getMock();
+        $this->productRepositoryMock->expects($this->once())
+            ->method('get')
+            ->with($productSku, false, null, true)
+            ->willReturn($newProductMock);
+
+        $this->assertEquals(
+            $newProductMock,
+            $this->model->aroundSave($this->productRepositoryMock, $this->closureMock, $this->productMock)
+        );
+    }
+}
diff --git a/app/code/Magento/Downloadable/Test/Unit/Model/Sample/ContentValidatorTest.php b/app/code/Magento/Downloadable/Test/Unit/Model/Sample/ContentValidatorTest.php
index 8a94c4b8ba1279711a75d133a7697b5cf49738c5..517563a68cd8b58ee2baba39bf71ca479dd55005 100644
--- a/app/code/Magento/Downloadable/Test/Unit/Model/Sample/ContentValidatorTest.php
+++ b/app/code/Magento/Downloadable/Test/Unit/Model/Sample/ContentValidatorTest.php
@@ -51,15 +51,17 @@ class ContentValidatorTest extends \PHPUnit_Framework_TestCase
             false
         );
         $this->sampleFileMock = $this->getMock('\Magento\Downloadable\Api\Data\File\ContentInterface');
-        $this->validator = new \Magento\Downloadable\Model\Sample\ContentValidator($this->fileValidatorMock, $this->urlValidatorMock);
+        $this->validator = new ContentValidator($this->fileValidatorMock, $this->urlValidatorMock);
     }
 
     public function testIsValid()
     {
+        $sampleFileContentMock = $this->getMock('Magento\Downloadable\Api\Data\File\ContentInterface');
         $sampleContentData = [
             'title' => 'Title',
             'sort_order' => 1,
             'sample_type' => 'file',
+            'sample_file_content' => $sampleFileContentMock,
         ];
         $this->fileValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true));
         $this->urlValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true));
@@ -103,7 +105,7 @@ class ContentValidatorTest extends \PHPUnit_Framework_TestCase
      */
     protected function getSampleContentMock(array $sampleContentData)
     {
-        $contentMock = $this->getMock('\Magento\Downloadable\Api\Data\SampleContentInterface');
+        $contentMock = $this->getMock('\Magento\Downloadable\Api\Data\SampleInterface');
         $contentMock->expects($this->any())->method('getTitle')->will($this->returnValue(
             $sampleContentData['title']
         ));
@@ -119,6 +121,10 @@ class ContentValidatorTest extends \PHPUnit_Framework_TestCase
                 $sampleContentData['sample_url']
             ));
         }
+        if (isset($sampleContentData['sample_file_content'])) {
+            $contentMock->expects($this->any())->method('getSampleFileContent')
+                ->willReturn($sampleContentData['sample_file_content']);
+        }
         $contentMock->expects($this->any())->method('getSampleFile')->will($this->returnValue(
             $this->sampleFileMock
         ));
diff --git a/app/code/Magento/Downloadable/Test/Unit/Model/SampleRepositoryTest.php b/app/code/Magento/Downloadable/Test/Unit/Model/SampleRepositoryTest.php
index 4027405e14f5c27eaf84dc245574e21d4a8a156a..7e25af50c3f6b771308ffc0eed2f79b227bd35b6 100644
--- a/app/code/Magento/Downloadable/Test/Unit/Model/SampleRepositoryTest.php
+++ b/app/code/Magento/Downloadable/Test/Unit/Model/SampleRepositoryTest.php
@@ -15,6 +15,11 @@ class SampleRepositoryTest extends \PHPUnit_Framework_TestCase
      */
     protected $repositoryMock;
 
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productTypeMock;
+
     /**
      * @var \PHPUnit_Framework_MockObject_MockObject
      */
@@ -55,6 +60,7 @@ class SampleRepositoryTest extends \PHPUnit_Framework_TestCase
             false
         );
         $this->repositoryMock = $this->getMock('\Magento\Catalog\Model\ProductRepository', [], [], '', false);
+        $this->productTypeMock = $this->getMock('\Magento\Downloadable\Model\Product\Type', [], [], '', false);
         $this->contentValidatorMock = $this->getMock(
             'Magento\Downloadable\Model\Sample\ContentValidator',
             [],
@@ -78,6 +84,7 @@ class SampleRepositoryTest extends \PHPUnit_Framework_TestCase
 
         $this->service = new \Magento\Downloadable\Model\SampleRepository(
             $this->repositoryMock,
+            $this->productTypeMock,
             $this->contentValidatorMock,
             $this->contentUploaderMock,
             $this->jsonEncoderMock,
@@ -86,35 +93,43 @@ class SampleRepositoryTest extends \PHPUnit_Framework_TestCase
     }
 
     /**
-     * @param array $sampleContentData
+     * @param array $sampleData
      * @return \PHPUnit_Framework_MockObject_MockObject
      */
-    protected function getSampleContentMock(array $sampleContentData)
+    protected function getSampleMock(array $sampleData)
     {
-        $contentMock = $this->getMock('\Magento\Downloadable\Api\Data\SampleContentInterface');
+        $sampleMock = $this->getMock('\Magento\Downloadable\Api\Data\SampleInterface');
 
-        $contentMock->expects($this->any())->method('getTitle')->will($this->returnValue($sampleContentData['title']));
-        $contentMock->expects($this->any())->method('getSortOrder')->will($this->returnValue(
-            $sampleContentData['sort_order']
+        if (isset($sampleData['id'])) {
+            $sampleMock->expects($this->any())->method('getId')->willReturn($sampleData['id']);
+        }
+        $sampleMock->expects($this->any())->method('getTitle')->will($this->returnValue($sampleData['title']));
+        $sampleMock->expects($this->any())->method('getSortOrder')->will($this->returnValue(
+            $sampleData['sort_order']
         ));
 
-        if (isset($sampleContentData['sample_type'])) {
-            $contentMock->expects($this->any())->method('getSampleType')->will($this->returnValue(
-                $sampleContentData['sample_type']
+        if (isset($sampleData['sample_type'])) {
+            $sampleMock->expects($this->any())->method('getSampleType')->will($this->returnValue(
+                $sampleData['sample_type']
+            ));
+        }
+        if (isset($sampleData['sample_url'])) {
+            $sampleMock->expects($this->any())->method('getSampleUrl')->will($this->returnValue(
+                $sampleData['sample_url']
             ));
         }
-        if (isset($sampleContentData['sample_url'])) {
-            $contentMock->expects($this->any())->method('getSampleUrl')->will($this->returnValue(
-                $sampleContentData['sample_url']
+        if (isset($sampleData['sample_file'])) {
+            $sampleMock->expects($this->any())->method('getSampleFile')->will($this->returnValue(
+                $sampleData['sample_file']
             ));
         }
-        return $contentMock;
+        return $sampleMock;
     }
 
     public function testCreate()
     {
         $productSku = 'simple';
-        $sampleContentData = [
+        $sampleData = [
             'title' => 'Title',
             'sort_order' => 1,
             'sample_type' => 'url',
@@ -123,8 +138,8 @@ class SampleRepositoryTest extends \PHPUnit_Framework_TestCase
         $this->repositoryMock->expects($this->any())->method('get')->with($productSku, true)
             ->will($this->returnValue($this->productMock));
         $this->productMock->expects($this->any())->method('getTypeId')->will($this->returnValue('downloadable'));
-        $sampleContentMock = $this->getSampleContentMock($sampleContentData);
-        $this->contentValidatorMock->expects($this->any())->method('isValid')->with($sampleContentMock)
+        $sampleMock = $this->getSampleMock($sampleData);
+        $this->contentValidatorMock->expects($this->any())->method('isValid')->with($sampleMock)
             ->will($this->returnValue(true));
 
         $this->productMock->expects($this->once())->method('setDownloadableData')->with([
@@ -132,15 +147,15 @@ class SampleRepositoryTest extends \PHPUnit_Framework_TestCase
                 [
                     'sample_id' => 0,
                     'is_delete' => 0,
-                    'type' => $sampleContentData['sample_type'],
-                    'sort_order' => $sampleContentData['sort_order'],
-                    'title' => $sampleContentData['title'],
-                    'sample_url' => $sampleContentData['sample_url'],
+                    'type' => $sampleData['sample_type'],
+                    'sort_order' => $sampleData['sort_order'],
+                    'title' => $sampleData['title'],
+                    'sample_url' => $sampleData['sample_url'],
                 ],
             ],
         ]);
-        $this->productMock->expects($this->once())->method('save');
-        $this->service->save($productSku, $sampleContentMock, null);
+        $this->productTypeMock->expects($this->once())->method('save')->with($this->productMock);
+        $this->service->save($productSku, $sampleMock);
     }
 
     /**
@@ -150,7 +165,7 @@ class SampleRepositoryTest extends \PHPUnit_Framework_TestCase
     public function testCreateThrowsExceptionIfTitleIsEmpty()
     {
         $productSku = 'simple';
-        $sampleContentData = [
+        $sampleData = [
             'title' => '',
             'sort_order' => 1,
             'sample_type' => 'url',
@@ -160,13 +175,13 @@ class SampleRepositoryTest extends \PHPUnit_Framework_TestCase
         $this->repositoryMock->expects($this->any())->method('get')->with($productSku, true)
             ->will($this->returnValue($this->productMock));
         $this->productMock->expects($this->any())->method('getTypeId')->will($this->returnValue('downloadable'));
-        $sampleContentMock = $this->getSampleContentMock($sampleContentData);
-        $this->contentValidatorMock->expects($this->any())->method('isValid')->with($sampleContentMock)
+        $sampleMock = $this->getSampleMock($sampleData);
+        $this->contentValidatorMock->expects($this->any())->method('isValid')->with($sampleMock)
             ->will($this->returnValue(true));
 
-        $this->productMock->expects($this->never())->method('save');
+        $this->productTypeMock->expects($this->never())->method('save');
 
-        $this->service->save($productSku, $sampleContentMock, null);
+        $this->service->save($productSku, $sampleMock);
     }
 
     public function testUpdate()
@@ -174,39 +189,109 @@ class SampleRepositoryTest extends \PHPUnit_Framework_TestCase
         $sampleId = 1;
         $productId = 1;
         $productSku = 'simple';
-        $sampleContentData = [
+        $sampleData = [
+            'id' => $sampleId,
             'title' => 'Updated Title',
             'sort_order' => 1,
+            'sample_type' => 'url',
+            'sample_url' => 'http://example.com/',
         ];
         $this->repositoryMock->expects($this->any())->method('get')->with($productSku, true)
             ->will($this->returnValue($this->productMock));
         $this->productMock->expects($this->any())->method('getId')->will($this->returnValue($productId));
-        $sampleMock = $this->getMock(
+        $existingSampleMock = $this->getMock(
             '\Magento\Downloadable\Model\Sample',
-            ['__wakeup', 'setTitle', 'setSortOrder', 'getId', 'setProductId', 'setStoreId',
-                'load', 'save', 'getProductId'],
+            ['__wakeup', 'getId', 'load', 'getProductId'],
             [],
             '',
             false
         );
-        $this->sampleFactoryMock->expects($this->once())->method('create')->will($this->returnValue($sampleMock));
-        $sampleContentMock = $this->getSampleContentMock($sampleContentData);
-        $this->contentValidatorMock->expects($this->any())->method('isValid')->with($sampleContentMock)
+        $this->sampleFactoryMock->expects($this->once())->method('create')
+            ->will($this->returnValue($existingSampleMock));
+        $sampleMock = $this->getSampleMock($sampleData);
+        $this->contentValidatorMock->expects($this->any())->method('isValid')->with($sampleMock)
             ->will($this->returnValue(true));
 
-        $sampleMock->expects($this->any())->method('getId')->will($this->returnValue($sampleId));
-        $sampleMock->expects($this->any())->method('getProductId')->will($this->returnValue($productId));
-        $sampleMock->expects($this->once())->method('load')->with($sampleId)->will($this->returnSelf());
-        $sampleMock->expects($this->once())->method('setTitle')->with($sampleContentData['title'])
-            ->will($this->returnSelf());
-        $sampleMock->expects($this->once())->method('setSortOrder')->with($sampleContentData['sort_order'])
-            ->will($this->returnSelf());
-        $sampleMock->expects($this->once())->method('setProductId')->with($productId)
-            ->will($this->returnSelf());
-        $sampleMock->expects($this->once())->method('setStoreId')->will($this->returnSelf());
-        $sampleMock->expects($this->once())->method('save')->will($this->returnSelf());
-
-        $this->assertEquals($sampleId, $this->service->save($productSku, $sampleContentMock, $sampleId));
+        $existingSampleMock->expects($this->any())->method('getId')->will($this->returnValue($sampleId));
+        $existingSampleMock->expects($this->any())->method('getProductId')->will($this->returnValue($productId));
+        $existingSampleMock->expects($this->once())->method('load')->with($sampleId)->will($this->returnSelf());
+
+        $this->productMock->expects($this->once())->method('setDownloadableData')->with([
+            'sample' => [
+                [
+                    'sample_id' => $sampleId,
+                    'is_delete' => 0,
+                    'type' => $sampleData['sample_type'],
+                    'sort_order' => $sampleData['sort_order'],
+                    'title' => $sampleData['title'],
+                    'sample_url' => $sampleData['sample_url'],
+                ],
+            ],
+        ]);
+        $this->productTypeMock->expects($this->once())->method('save')->with($this->productMock);
+
+        $this->assertEquals($sampleId, $this->service->save($productSku, $sampleMock));
+    }
+
+    public function testUpdateWithExistingFile()
+    {
+        $sampleId = 1;
+        $productId = 1;
+        $productSku = 'simple';
+        $sampleFile = '/s/a/sample.jpg';
+        $encodedFile = 'something';
+        $sampleData = [
+            'id' => $sampleId,
+            'title' => 'Updated Title',
+            'sort_order' => 1,
+            'sample_type' => 'file',
+            'sample_file' => $sampleFile,
+        ];
+        $this->repositoryMock->expects($this->any())->method('get')->with($productSku, true)
+            ->will($this->returnValue($this->productMock));
+        $this->productMock->expects($this->any())->method('getId')->will($this->returnValue($productId));
+        $existingSampleMock = $this->getMock(
+            '\Magento\Downloadable\Model\Sample',
+            ['__wakeup', 'getId', 'load', 'getProductId'],
+            [],
+            '',
+            false
+        );
+        $this->sampleFactoryMock->expects($this->once())->method('create')
+            ->will($this->returnValue($existingSampleMock));
+        $sampleMock = $this->getSampleMock($sampleData);
+        $this->contentValidatorMock->expects($this->any())->method('isValid')->with($sampleMock)
+            ->will($this->returnValue(true));
+
+        $existingSampleMock->expects($this->any())->method('getId')->will($this->returnValue($sampleId));
+        $existingSampleMock->expects($this->any())->method('getProductId')->will($this->returnValue($productId));
+        $existingSampleMock->expects($this->once())->method('load')->with($sampleId)->will($this->returnSelf());
+
+        $this->jsonEncoderMock->expects($this->once())
+            ->method('encode')
+            ->with(
+                [
+                    [
+                        'file' => $sampleFile,
+                        'status' => 'old',
+                    ]
+                ]
+            )->willReturn($encodedFile);
+        $this->productMock->expects($this->once())->method('setDownloadableData')->with([
+            'sample' => [
+                [
+                    'sample_id' => $sampleId,
+                    'is_delete' => 0,
+                    'type' => $sampleData['sample_type'],
+                    'sort_order' => $sampleData['sort_order'],
+                    'title' => $sampleData['title'],
+                    'file' => $encodedFile,
+                ],
+            ],
+        ]);
+        $this->productTypeMock->expects($this->once())->method('save')->with($this->productMock);
+
+        $this->assertEquals($sampleId, $this->service->save($productSku, $sampleMock));
     }
 
     /**
@@ -218,31 +303,33 @@ class SampleRepositoryTest extends \PHPUnit_Framework_TestCase
         $sampleId = 1;
         $productSku = 'simple';
         $productId = 1;
-        $sampleContentData = [
+        $sampleData = [
+            'id' => $sampleId,
             'title' => '',
             'sort_order' => 1,
         ];
         $this->repositoryMock->expects($this->any())->method('get')->with($productSku, true)
             ->will($this->returnValue($this->productMock));
         $this->productMock->expects($this->any())->method('getId')->will($this->returnValue($productId));
-        $sampleMock = $this->getMock(
+        $existingSampleMock = $this->getMock(
             '\Magento\Downloadable\Model\Sample',
             ['__wakeup', 'getId', 'load', 'save', 'getProductId'],
             [],
             '',
             false
         );
-        $sampleMock->expects($this->any())->method('getId')->will($this->returnValue($sampleId));
-        $sampleMock->expects($this->once())->method('load')->with($sampleId)->will($this->returnSelf());
-        $sampleMock->expects($this->any())->method('getProductId')->will($this->returnValue($productId));
-        $this->sampleFactoryMock->expects($this->once())->method('create')->will($this->returnValue($sampleMock));
-        $sampleContentMock = $this->getSampleContentMock($sampleContentData);
-        $this->contentValidatorMock->expects($this->any())->method('isValid')->with($sampleContentMock)
+        $existingSampleMock->expects($this->any())->method('getId')->will($this->returnValue($sampleId));
+        $existingSampleMock->expects($this->once())->method('load')->with($sampleId)->will($this->returnSelf());
+        $existingSampleMock->expects($this->any())->method('getProductId')->will($this->returnValue($productId));
+        $this->sampleFactoryMock->expects($this->once())->method('create')
+            ->will($this->returnValue($existingSampleMock));
+        $sampleMock = $this->getSampleMock($sampleData);
+        $this->contentValidatorMock->expects($this->any())->method('isValid')->with($sampleMock)
             ->will($this->returnValue(true));
 
-        $sampleMock->expects($this->never())->method('save');
+        $this->productTypeMock->expects($this->never())->method('save');
 
-        $this->service->save($productSku, $sampleContentMock, $sampleId, true);
+        $this->service->save($productSku, $sampleMock, true);
     }
 
     public function testDelete()
diff --git a/app/code/Magento/Downloadable/composer.json b/app/code/Magento/Downloadable/composer.json
index 69f7d646d0ffd16100c2deddc801ab123ab375ad..0d193d70b390aec33ca02dc0f4bab3f640a738f0 100644
--- a/app/code/Magento/Downloadable/composer.json
+++ b/app/code/Magento/Downloadable/composer.json
@@ -3,28 +3,28 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/module-customer": "0.74.0-beta6",
-        "magento/module-tax": "0.74.0-beta6",
-        "magento/module-theme": "0.74.0-beta6",
-        "magento/module-eav": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-sales": "0.74.0-beta6",
-        "magento/module-checkout": "0.74.0-beta6",
-        "magento/module-directory": "0.74.0-beta6",
-        "magento/module-wishlist": "0.74.0-beta6",
-        "magento/module-gift-message": "0.74.0-beta6",
-        "magento/module-catalog-inventory": "0.74.0-beta6",
-        "magento/module-msrp": "0.74.0-beta6",
-        "magento/module-config": "0.74.0-beta6",
-        "magento/module-media-storage": "0.74.0-beta6",
-        "magento/module-quote": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/module-customer": "0.74.0-beta7",
+        "magento/module-tax": "0.74.0-beta7",
+        "magento/module-theme": "0.74.0-beta7",
+        "magento/module-eav": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-sales": "0.74.0-beta7",
+        "magento/module-checkout": "0.74.0-beta7",
+        "magento/module-directory": "0.74.0-beta7",
+        "magento/module-wishlist": "0.74.0-beta7",
+        "magento/module-gift-message": "0.74.0-beta7",
+        "magento/module-catalog-inventory": "0.74.0-beta7",
+        "magento/module-msrp": "0.74.0-beta7",
+        "magento/module-config": "0.74.0-beta7",
+        "magento/module-media-storage": "0.74.0-beta7",
+        "magento/module-quote": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Downloadable/etc/di.xml b/app/code/Magento/Downloadable/etc/di.xml
index 9b492b051acc779329be9e761c9ede86ce6752e7..acb63729a578108f11e7b5f9d59c60d3d1e00745 100644
--- a/app/code/Magento/Downloadable/etc/di.xml
+++ b/app/code/Magento/Downloadable/etc/di.xml
@@ -58,12 +58,16 @@
             </argument>
         </arguments>
     </type>
+    <type name="Magento\Catalog\Model\Product">
+        <plugin name="downloadableAfterLoad" type="\Magento\Downloadable\Model\Plugin\AfterProductLoad"/>
+    </type>
+    <type name="Magento\Catalog\Api\ProductRepositoryInterface">
+        <plugin name="downloadableAroundSave" type="\Magento\Downloadable\Model\Plugin\AroundProductRepositorySave"/>
+    </type>
     <preference for="\Magento\Downloadable\Api\LinkRepositoryInterface" type="\Magento\Downloadable\Model\LinkRepository" />
     <preference for="\Magento\Downloadable\Api\SampleRepositoryInterface" type="\Magento\Downloadable\Model\SampleRepository" />
     <preference for="\Magento\Downloadable\Api\Data\LinkInterface" type="\Magento\Downloadable\Model\Link" />
     <preference for="\Magento\Downloadable\Api\Data\SampleInterface" type="\Magento\Downloadable\Model\Sample" />
-    <preference for="\Magento\Downloadable\Api\Data\SampleContentInterface" type="\Magento\Downloadable\Model\Sample\Content" />
-    <preference for="\Magento\Downloadable\Api\Data\LinkContentInterface" type="\Magento\Downloadable\Model\Link\Content" />
     <preference for="\Magento\Downloadable\Api\Data\File\ContentInterface" type="\Magento\Downloadable\Model\File\Content" />
     <preference for="\Magento\Downloadable\Api\Data\File\ContentUploaderInterface" type="\Magento\Downloadable\Model\File\ContentUploader" />
     <preference for="\Magento\Downloadable\Model\Product\TypeHandler\TypeHandlerInterface" type="\Magento\Downloadable\Model\Product\TypeHandler\TypeHandler" />
diff --git a/app/code/Magento/Downloadable/etc/service_data_attributes.xml b/app/code/Magento/Downloadable/etc/service_data_attributes.xml
new file mode 100644
index 0000000000000000000000000000000000000000..80cc1cb0abf9ff457b97d12eddc9b3b6ee519784
--- /dev/null
+++ b/app/code/Magento/Downloadable/etc/service_data_attributes.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Api/etc/service_data_attributes.xsd">
+    <extension_attributes for="Magento\Catalog\Api\Data\ProductInterface">
+        <attribute code="downloadable_product_links" type="Magento\Downloadable\Api\Data\LinkInterface[]" />
+        <attribute code="downloadable_product_samples" type="Magento\Downloadable\Api\Data\SampleInterface[]" />
+    </extension_attributes>
+</config>
diff --git a/app/code/Magento/Downloadable/etc/webapi.xml b/app/code/Magento/Downloadable/etc/webapi.xml
index 0291fe5322f8328380ab63b58dfd7b8b8322dbe2..7f597119f9e74db7142d3baa866ec3c697c67e45 100644
--- a/app/code/Magento/Downloadable/etc/webapi.xml
+++ b/app/code/Magento/Downloadable/etc/webapi.xml
@@ -25,13 +25,13 @@
             <resource ref="Magento_Downloadable::downloadable" />
         </resources>
     </route>
-    <route url="/V1/products/:sku/downloadable-links/:linkId" method="PUT">
+    <route url="/V1/products/:sku/downloadable-links/:id" method="PUT">
         <service class="Magento\Downloadable\Api\LinkRepositoryInterface" method="save"/>
         <resources>
             <resource ref="Magento_Downloadable::downloadable" />
         </resources>
     </route>
-    <route url="/V1/products/downloadable-links/:linkId" method="DELETE">
+    <route url="/V1/products/downloadable-links/:id" method="DELETE">
         <service class="Magento\Downloadable\Api\LinkRepositoryInterface" method="delete"/>
         <resources>
             <resource ref="Magento_Downloadable::downloadable" />
@@ -43,13 +43,13 @@
             <resource ref="Magento_Downloadable::downloadable" />
         </resources>
     </route>
-    <route url="/V1/products/:sku/downloadable-links/samples/:sampleId" method="PUT">
+    <route url="/V1/products/:sku/downloadable-links/samples/:id" method="PUT">
     <service class="Magento\Downloadable\Api\SampleRepositoryInterface" method="save"/>
     <resources>
         <resource ref="Magento_Downloadable::downloadable" />
     </resources>
 </route>
-    <route url="/V1/products/downloadable-links/samples/:sampleId" method="DELETE">
+    <route url="/V1/products/downloadable-links/samples/:id" method="DELETE">
         <service class="Magento\Downloadable\Api\SampleRepositoryInterface" method="delete"/>
         <resources>
             <resource ref="Magento_Downloadable::downloadable" />
diff --git a/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable/links.phtml b/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable/links.phtml
index dada69c3e47a9ba4ee7732276d71affd02ea4667..8196069e692019324ad8295aaa7a6d70be207d0c 100644
--- a/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable/links.phtml
+++ b/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable/links.phtml
@@ -39,7 +39,7 @@
     <div class="admin__field admin__field-wide">
         <div class="admin__field-control">
             <div class="admin__control-table-wrapper">
-                <table cellspacing="0" class="admin__control-table">
+                <table class="admin__control-table">
                     <thead>
                         <tr>
                             <th class="col-title _required"><span><?php echo __('Title') ?></span></th>
@@ -163,7 +163,7 @@ require([
             '</td>'+
             '<td class="col-sort"><input type="text" name="downloadable[link][<%- data.id %>][sort_order]" value="<%- data.sort_order %>" class="input-text admin__control-text sort" /></td>'+
             '<td class="col-action">'+
-                '<button id="downloadable_link_<%- data.id %>_delete_button" type="button" class="action-remove"><span><?php echo __('Delete'); ?></span></button>'+
+                '<button id="downloadable_link_<%- data.id %>_delete_button" type="button" class="action-delete"><span><?php echo __('Delete'); ?></span></button>'+
             '</td>'+
         '</tr>';
 
@@ -310,7 +310,7 @@ require([
                 }
             },
             bindRemoveButtons : function(){
-                var buttons = $$('tbody#link_items_body .action-remove');
+                var buttons = $$('tbody#link_items_body .action-delete');
                 for(var i=0;i<buttons.length;i++){
                     if(!$(buttons[i]).binded && !$(buttons[i]).hasClassName('disabled')){
                         $(buttons[i]).binded = true;
diff --git a/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable/samples.phtml b/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable/samples.phtml
index 82ba490f0cf862ddce3e8a84944e889443979a62..11f7ee94465e6c143b1a6037c5b3ffebd59a21a7 100644
--- a/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable/samples.phtml
+++ b/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable/samples.phtml
@@ -31,7 +31,7 @@ $block->getConfigJson();
     <div class="admin__field admin__field-wide">
         <div class="admin__field-control">
             <div class="admin__control-table-wrapper">
-                <table cellspacing="0" class="admin__control-table">
+                <table class="admin__control-table">
                     <thead>
                         <tr>
                             <th class="_required col-title"><span><?php echo __('Title') ?></span></th>
@@ -102,7 +102,7 @@ require([
                             '</td>'+
                             '<td class="col-sort"><input type="text" name="downloadable[sample][<%- data.id %>][sort_order]" value="<%- data.sort_order %>" class="input-text sort admin__control-text" /></td>'+
                             '<td class="col-actions">'+
-                                '<button type="button" class="action-remove"><span>Delete</span></button>'+
+                                '<button type="button" class="action-delete"><span>Delete</span></button>'+
                             '</td>'+
                         '</tr>';
         sampleItems = {
@@ -183,7 +183,7 @@ require([
                 }
             },
             bindRemoveButtons: function() {
-                var buttons = $$('tbody#sample_items_body .action-remove');
+                var buttons = $$('tbody#sample_items_body .action-delete');
                 for(var i=0;i<buttons.length;i++){
                     if(!$(buttons[i]).binded){
                         $(buttons[i]).binded = true;
diff --git a/app/code/Magento/Downloadable/view/adminhtml/templates/sales/items/column/downloadable/name.phtml b/app/code/Magento/Downloadable/view/adminhtml/templates/sales/items/column/downloadable/name.phtml
index 79f67d109af865df0a47bcb29e0003d86b152c83..aa6712c6d459d0938ff92651aa3516465aa69039 100644
--- a/app/code/Magento/Downloadable/view/adminhtml/templates/sales/items/column/downloadable/name.phtml
+++ b/app/code/Magento/Downloadable/view/adminhtml/templates/sales/items/column/downloadable/name.phtml
@@ -10,11 +10,14 @@
 
 <?php if ($_item = $block->getItem()): ?>
     <div class="product-title"><?php echo $_item->getName() ?></div>
-    <div><strong><?php echo __('SKU') ?>:</strong> <?php echo implode('<br />', $this->helper('Magento\Catalog\Helper\Data')->splitSku($block->escapeHtml($block->getSku()))); ?></div>
+    <div class="product-sku-block">
+        <span><?php echo __('SKU') ?>:</span>
+        <?php echo implode('<br />', $this->helper('Magento\Catalog\Helper\Data')->splitSku($block->escapeHtml($block->getSku()))); ?>
+    </div>
     <?php if ($block->getOrderOptions()): ?>
         <dl class="item-options">
         <?php foreach ($block->getOrderOptions() as $_option): ?>
-            <dt><?php echo $_option['label'] ?></dt>
+            <dt><?php echo $_option['label'] ?>:</dt>
             <dd>
             <?php if (isset($_option['custom_view']) && $_option['custom_view']): ?>
                 <?php echo $_option['value'];?>
@@ -39,7 +42,7 @@ require(['prototype'], function(){
     <?php endif; ?>
     <?php if ($block->getLinks()): ?>
         <dl class="item-options">
-            <dt><?php echo $block->getLinksTitle(); ?></dt>
+            <dt><?php echo $block->getLinksTitle(); ?>:</dt>
             <?php foreach ($block->getLinks()->getPurchasedItems() as $_link): ?>
                 <dd><?php echo $block->escapeHtml($_link->getLinkTitle()) ?> (<?php echo $_link->getNumberOfDownloadsUsed() . ' / ' . ($_link->getNumberOfDownloadsBought() ? $_link->getNumberOfDownloadsBought() : __('U')) ?>)</dd>
             <?php endforeach; ?>
diff --git a/app/code/Magento/Eav/Model/Entity/AbstractEntity.php b/app/code/Magento/Eav/Model/Entity/AbstractEntity.php
index ac8c5805f4b72f8727d09a4a4cbc71a0f05c2258..c8fa8214eab58921da003c19e9a5c55b4a3d66c1 100755
--- a/app/code/Magento/Eav/Model/Entity/AbstractEntity.php
+++ b/app/code/Magento/Eav/Model/Entity/AbstractEntity.php
@@ -31,14 +31,14 @@ abstract class AbstractEntity extends \Magento\Framework\Model\Resource\Abstract
     /**
      * Read connection
      *
-     * @var \Magento\Framework\DB\Adapter\Pdo\Mysql
+     * @var \Magento\Framework\DB\Adapter\Pdo\Mysql | string
      */
     protected $_read;
 
     /**
      * Write connection
      *
-     * @var \Magento\Framework\DB\Adapter\Pdo\Mysql
+     * @var \Magento\Framework\DB\Adapter\Pdo\Mysql | string
      */
     protected $_write;
 
diff --git a/app/code/Magento/Eav/composer.json b/app/code/Magento/Eav/composer.json
index 48ba714ad64dafc7360bb73aa31e87ac3a96ac0d..b67c368db4d0263cd85abde008a6fdae9063b397 100644
--- a/app/code/Magento/Eav/composer.json
+++ b/app/code/Magento/Eav/composer.json
@@ -3,16 +3,16 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/module-config": "0.74.0-beta6",
-        "magento/module-media-storage": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/module-config": "0.74.0-beta7",
+        "magento/module-media-storage": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Eav/etc/di.xml b/app/code/Magento/Eav/etc/di.xml
index 3dfebf456c7ff4ae26f6f8a118431872c7c2f67e..00524114f784dd3bc859a8395a9c1d23012433cc 100644
--- a/app/code/Magento/Eav/etc/di.xml
+++ b/app/code/Magento/Eav/etc/di.xml
@@ -57,4 +57,9 @@
             </argument>
         </arguments>
     </type>
+    <type name="Magento\Eav\Model\Entity\Attribute">
+        <arguments>
+            <argument name="reservedAttributeList" xsi:type="object">Magento\Catalog\Model\Product\ReservedAttributeList\Proxy</argument>
+        </arguments>
+    </type>
 </config>
diff --git a/app/code/Magento/Email/Model/BackendTemplate.php b/app/code/Magento/Email/Model/BackendTemplate.php
index be5b232564a67e139724e96f6d7a51a89702ed9c..c8bc6b34398e0c492f9123cfaeedc8182da23299 100644
--- a/app/code/Magento/Email/Model/BackendTemplate.php
+++ b/app/code/Magento/Email/Model/BackendTemplate.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\Email\Model;
 
+use Magento\Framework\App\Config\ScopeConfigInterface;
+
 /**
  * Adminhtml email template model
  *
@@ -78,7 +80,7 @@ class BackendTemplate extends Template
             return [];
         }
 
-        $configData = $this->_scopeConfig->getValue(null, \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT);
+        $configData = $this->_scopeConfig->getValue(null, ScopeConfigInterface::SCOPE_TYPE_DEFAULT);
         $paths = $this->_findEmailTemplateUsages($templateCode, $configData, '');
         return $paths;
     }
diff --git a/app/code/Magento/Email/composer.json b/app/code/Magento/Email/composer.json
index afc6d37eb433e3b75b32196ad86b641530dbb796..1a17463f5c6eaecae56d40b2f087b987c1ec1d23 100644
--- a/app/code/Magento/Email/composer.json
+++ b/app/code/Magento/Email/composer.json
@@ -3,16 +3,16 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-config": "0.74.0-beta6",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-cms": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-variable": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-config": "0.74.0-beta7",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-cms": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-variable": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Fedex/composer.json b/app/code/Magento/Fedex/composer.json
index 4e2b254631e2af230d799ecfca6b01371e26afcf..2fa84179799528959e83982cfd815454ce43f311 100644
--- a/app/code/Magento/Fedex/composer.json
+++ b/app/code/Magento/Fedex/composer.json
@@ -3,20 +3,20 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-shipping": "0.74.0-beta6",
-        "magento/module-directory": "0.74.0-beta6",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/module-sales": "0.74.0-beta6",
-        "magento/module-catalog-inventory": "0.74.0-beta6",
-        "magento/module-quote": "0.74.0-beta6",
-        "magento/module-config": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-shipping": "0.74.0-beta7",
+        "magento/module-directory": "0.74.0-beta7",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/module-sales": "0.74.0-beta7",
+        "magento/module-catalog-inventory": "0.74.0-beta7",
+        "magento/module-quote": "0.74.0-beta7",
+        "magento/module-config": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "lib-libxml": "*",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/GiftMessage/composer.json b/app/code/Magento/GiftMessage/composer.json
index 68ce2c1de0918b500fa744563995ea560aa00240..b7da7641a3318d3952c2c24a75fa491fe886c920 100644
--- a/app/code/Magento/GiftMessage/composer.json
+++ b/app/code/Magento/GiftMessage/composer.json
@@ -3,20 +3,20 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/module-checkout": "0.74.0-beta6",
-        "magento/module-multishipping": "0.74.0-beta6",
-        "magento/module-sales": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-customer": "0.74.0-beta6",
-        "magento/module-eav": "0.74.0-beta6",
-        "magento/module-quote": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/module-checkout": "0.74.0-beta7",
+        "magento/module-multishipping": "0.74.0-beta7",
+        "magento/module-sales": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-customer": "0.74.0-beta7",
+        "magento/module-eav": "0.74.0-beta7",
+        "magento/module-quote": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/GiftMessage/etc/data_object.xml b/app/code/Magento/GiftMessage/etc/service_data_attributes.xml
similarity index 64%
rename from app/code/Magento/GiftMessage/etc/data_object.xml
rename to app/code/Magento/GiftMessage/etc/service_data_attributes.xml
index a1255cc8a161a5a8d28090697088a87ede8920e7..f02c0a717e169224d0b7d450e861f38d7176dc7f 100644
--- a/app/code/Magento/GiftMessage/etc/data_object.xml
+++ b/app/code/Magento/GiftMessage/etc/service_data_attributes.xml
@@ -5,11 +5,11 @@
  * See COPYING.txt for license details.
  */
 -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Api/etc/data_object.xsd">
-    <custom_attributes for="Magento\Sales\Api\Data\OrderInterface">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Api/etc/service_data_attributes.xsd">
+    <extension_attributes for="Magento\Sales\Api\Data\OrderInterface">
         <attribute code="gift_message" type="Magento\GiftMessage\Api\Data\MessageInterface" />
-    </custom_attributes>
-    <custom_attributes for="Magento\Sales\Api\Data\OrderItemInterface">
+    </extension_attributes>
+    <extension_attributes for="Magento\Sales\Api\Data\OrderItemInterface">
         <attribute code="gift_message" type="Magento\GiftMessage\Api\Data\MessageInterface" />
-    </custom_attributes>
+    </extension_attributes>
 </config>
diff --git a/app/code/Magento/GiftMessage/view/adminhtml/templates/sales/order/create/giftoptions.phtml b/app/code/Magento/GiftMessage/view/adminhtml/templates/sales/order/create/giftoptions.phtml
index 3b6710cb9e1450263c494d2ee40e9860b66a4a69..b810ccccd95d8f23085677614fd4b2279705688c 100644
--- a/app/code/Magento/GiftMessage/view/adminhtml/templates/sales/order/create/giftoptions.phtml
+++ b/app/code/Magento/GiftMessage/view/adminhtml/templates/sales/order/create/giftoptions.phtml
@@ -12,8 +12,8 @@
 <?php if ($_item): ?>
     <?php $_childHtml = trim($block->getChildHtml('', false));?>
     <?php if ($_childHtml): ?>
-        <tr class="border">
-            <td colspan="8">
+        <tr class="row-gift-options">
+            <td colspan="7">
                 <a class="action-link" href="#" id="gift_options_link_<?php echo $_item->getId() ?>"><?php echo __('Gift Options') ?></a>
                 <script>
 require([
diff --git a/app/code/Magento/GoogleAdwords/composer.json b/app/code/Magento/GoogleAdwords/composer.json
index 81dcd88401f817917d78a4ef6c7662e1cef9e6b8..3aa69ec189227a3ebce792f590d80dc771b01a15 100644
--- a/app/code/Magento/GoogleAdwords/composer.json
+++ b/app/code/Magento/GoogleAdwords/composer.json
@@ -3,13 +3,13 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-sales": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-sales": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/GoogleAdwords/etc/di.xml b/app/code/Magento/GoogleAdwords/etc/di.xml
new file mode 100644
index 0000000000000000000000000000000000000000..293db157d7c38cca198df46a541016f71c97dd54
--- /dev/null
+++ b/app/code/Magento/GoogleAdwords/etc/di.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
+    <type name="Magento\GoogleAdwords\Model\Observer">
+        <arguments>
+            <argument name="collection" xsi:type="object">Magento\Sales\Model\Resource\Order\Collection\Proxy</argument>
+        </arguments>
+    </type>
+</config>
diff --git a/app/code/Magento/GoogleAnalytics/composer.json b/app/code/Magento/GoogleAnalytics/composer.json
index 68cfa226900d210e823aae6eb94a46500ba21fd0..3a46c54505deea1536e2d8b0fc8ac690f9448633 100644
--- a/app/code/Magento/GoogleAnalytics/composer.json
+++ b/app/code/Magento/GoogleAnalytics/composer.json
@@ -3,14 +3,14 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-sales": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
-        "magento/module-cookie": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-sales": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
+        "magento/module-cookie": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/GoogleOptimizer/composer.json b/app/code/Magento/GoogleOptimizer/composer.json
index a20b62e29cb95b1840d2dfc056c0e6df5b9638a2..5ef9e22e90d5654ee85e50d05e854b7319f48cdb 100644
--- a/app/code/Magento/GoogleOptimizer/composer.json
+++ b/app/code/Magento/GoogleOptimizer/composer.json
@@ -3,16 +3,16 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-google-analytics": "0.74.0-beta6",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/module-cms": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-google-analytics": "0.74.0-beta7",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/module-cms": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items.php
index 1a7253c6c788cf98453a2221537b92fcc7992cae..0ec30477e3866e7d7582241f0892d6fa860d67d1 100644
--- a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items.php
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items.php
@@ -7,12 +7,10 @@ namespace Magento\GoogleShopping\Controller\Adminhtml\Googleshopping;
 
 use Magento\Backend\App\Action;
 use Magento\Framework\Notification\NotifierInterface;
+use Magento\Framework\Controller\ResultFactory;
 
 /**
  * GoogleShopping Admin Items Controller
- *
- * @name       \Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Items
- * @author     Magento Core Team <core@magentocommerce.com>
  */
 class Items extends \Magento\Backend\App\Action
 {
@@ -55,7 +53,7 @@ class Items extends \Magento\Backend\App\Action
      * Redirect user to Google Captcha challenge
      *
      * @param \Zend_Gdata_App_CaptchaRequiredException $e
-     * @return void
+     * @return \Magento\Framework\Controller\ResultInterface
      */
     protected function _redirectToCaptcha($e)
     {
@@ -68,12 +66,13 @@ class Items extends \Magento\Backend\App\Action
             ]
         );
         if ($this->getRequest()->isAjax()) {
-            $this->getResponse()->representJson(
-                $this->_objectManager->get('Magento\Framework\Json\Helper\Data')
-                    ->jsonEncode(['redirect' => $redirectUrl])
-            );
+            /** @var \Magento\Framework\Controller\Result\Json $resultJson */
+            $resultJson = $this->resultFactory->create(ResultFactory::TYPE_JSON);
+            return $resultJson->setData(['redirect' => $redirectUrl]);
         } else {
-            $this->_redirect($redirectUrl);
+            /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
+            $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
+            return $resultRedirect->setUrl($redirectUrl);
         }
     }
 
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/ConfirmCaptcha.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/ConfirmCaptcha.php
index ab9061908528a8d2cc1786b291096e190ae97702..ef6a9807e247bfe195da7c0aad055eb0e1a821ff 100644
--- a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/ConfirmCaptcha.php
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/ConfirmCaptcha.php
@@ -1,6 +1,5 @@
 <?php
 /**
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
@@ -35,39 +34,34 @@ class ConfirmCaptcha extends \Magento\GoogleShopping\Controller\Adminhtml\Google
     /**
      * Confirm CAPTCHA
      *
-     * @return void
+     * @return \Magento\Framework\Controller\ResultInterface
      */
     public function execute()
     {
         $storeId = $this->_getStore()->getId();
         try {
-            $this->_objectManager->create(
-                'Magento\GoogleShopping\Model\Service'
-            )->getClient(
-                $storeId,
-                $this->urlDecoder->decode(
-                    $this->getRequest()->getParam('captcha_token')
-                ),
-                $this->getRequest()->getParam('user_confirm')
-            );
+            $this->_objectManager->create('Magento\GoogleShopping\Model\Service')
+                ->getClient(
+                    $storeId,
+                    $this->urlDecoder->decode($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;
+            return $this->_redirectToCaptcha($e);
         } catch (\Zend_Gdata_App_Exception $e) {
             $this->messageManager->addError(
-                $this->_objectManager->get(
-                    'Magento\GoogleShopping\Helper\Data'
-                )->parseGdataExceptionMessage(
-                    $e->getMessage()
-                )
+                $this->_objectManager->get('Magento\GoogleShopping\Helper\Data')
+                    ->parseGdataExceptionMessage($e->getMessage())
             );
         } catch (\Exception $e) {
             $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $this->messageManager->addError(__('Something went wrong during Captcha confirmation.'));
         }
 
-        $this->_redirect('adminhtml/*/index', ['store' => $storeId]);
+        /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
+        $resultRedirect = $this->resultFactory->create(\Magento\Framework\Controller\ResultFactory::TYPE_REDIRECT);
+        return $resultRedirect->setPath('adminhtml/*/index', ['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
index 7bd43f98baa86da153c1ad3984d05720acdef6f1..c0565fd7d89b67cbf1ce1bbee6eef31180fdd0d8 100644
--- a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/Grid.php
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/Grid.php
@@ -6,22 +6,43 @@
  */
 namespace Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Items;
 
+use Magento\Backend\App\Action;
+use Magento\Framework\Notification\NotifierInterface;
+
 class Grid extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Items
 {
+    /**
+     * @var \Magento\Framework\View\LayoutFactory
+     */
+    protected $layoutFactory;
+
+    /**
+     * @param Action\Context $context
+     * @param NotifierInterface $notifier
+     * @param \Magento\Framework\Url\EncoderInterface $urlEncoder
+     * @param \Magento\Framework\View\LayoutFactory $layoutFactory
+     */
+    public function __construct(
+        Action\Context $context,
+        NotifierInterface $notifier,
+        \Magento\Framework\Url\EncoderInterface $urlEncoder,
+        \Magento\Framework\View\LayoutFactory $layoutFactory
+    ) {
+        $this->layoutFactory = $layoutFactory;
+        parent::__construct($context, $notifier, $urlEncoder);
+    }
+
     /**
      * Grid with Google Content items
      *
-     * @return void
+     * @return \Magento\Framework\Controller\Result\Raw
      */
     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()
-        );
+        /** @var \Magento\Framework\Controller\Result\Raw $resultRaw */
+        $resultRaw = $this->resultFactory->create(\Magento\Framework\Controller\ResultFactory::TYPE_RAW);
+        /** @var \Magento\GoogleShopping\Block\Adminhtml\Items\Item $block */
+        $block = $this->layoutFactory->create()->createBlock('Magento\GoogleShopping\Block\Adminhtml\Items\Item');
+        return $resultRaw->setContents($block->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
index 56380c2148cfacfde955603861af9d03fa33fbb4..092ac1d0a4471fb21333cfa312cbeaf090d682cb 100644
--- a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/Index.php
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/Index.php
@@ -35,54 +35,36 @@ class Index extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\
         $this->urlDecoder = $urlDecoder;
     }
 
-    /**
-     * 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
+     * @return \Magento\Backend\Model\View\Result\Page|\Magento\Backend\Model\View\Result\Redirect
      */
     public function execute()
     {
         if (0 === (int)$this->getRequest()->getParam('store')) {
-            $this->_redirect(
+            /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
+            $resultRedirect = $this->resultFactory->create(\Magento\Framework\Controller\ResultFactory::TYPE_REDIRECT);
+            return $resultRedirect->setPath(
                 'adminhtml/*/',
                 [
-                    'store' => $this->_objectManager->get(
-                        'Magento\Store\Model\StoreManagerInterface'
-                    )->getStore()->getId(),
+                    'store' => $this->_objectManager->get('Magento\Store\Model\StoreManagerInterface')
+                        ->getStore()->getId(),
                     '_current' => true
                 ]
             );
-            return;
         }
 
-        $this->_initAction();
-        $this->_view->getPage()->getConfig()->getTitle()->prepend(__('Google Content Items'));
+        /** @var \Magento\Backend\Model\View\Result\Page $resultPage */
+        $resultPage = $this->resultFactory->create(\Magento\Framework\Controller\ResultFactory::TYPE_PAGE);
+        $resultPage->setActiveMenu('Magento_GoogleShopping::catalog_googleshopping_items')
+            ->addBreadcrumb(__('Catalog'), __('Catalog'))
+            ->addBreadcrumb(__('Google Content'), __('Google Content'));
+        $resultPage->getConfig()->getTitle()->prepend(__('Google Content Items'));
 
-        $contentBlock = $this->_view->getLayout()->createBlock(
-            'Magento\GoogleShopping\Block\Adminhtml\Items'
-        )->setStore(
-            $this->_getStore()
-        );
+        $contentBlock = $resultPage->getLayout()
+            ->createBlock('Magento\GoogleShopping\Block\Adminhtml\Items')
+            ->setStore($this->_getStore());
 
         if ($this->getRequest()->getParam('captcha_token') && $this->getRequest()->getParam('captcha_url')) {
             $contentBlock->setGcontentCaptchaToken(
@@ -97,11 +79,8 @@ class Index extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\
             );
         }
 
-        if (!$this->_objectManager->get(
-            'Magento\GoogleShopping\Model\Config'
-        )->isValidDefaultCurrencyCode(
-            $this->_getStore()->getId()
-        )
+        if (!$this->_objectManager->get('Magento\GoogleShopping\Model\Config')
+                ->isValidDefaultCurrencyCode($this->_getStore()->getId())
         ) {
             $_countryInfo = $this->_objectManager->get(
                 'Magento\GoogleShopping\Model\Config'
@@ -110,14 +89,14 @@ class Index extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\
             );
             $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.",
+                    "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();
+        return $resultPage->addBreadcrumb(__('Items'), __('Items'))->addContent($contentBlock);
     }
 }
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/MassAdd.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/MassAdd.php
index 4af5444a043b464a7403dbf8d73e1e7cd0a93b12..4f101189769876999ba8e662e2bb2f711a653dda 100644
--- a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/MassAdd.php
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/MassAdd.php
@@ -1,6 +1,5 @@
 <?php
 /**
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
@@ -11,13 +10,14 @@ class MassAdd extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshoppin
     /**
      * Add (export) several products to Google Content
      *
-     * @return void
+     * @return \Magento\Framework\Controller\ResultInterface
+     * @throws \Magento\Framework\Exception\LocalizedException
      */
     public function execute()
     {
         $flag = $this->_getFlag();
         if ($flag->isLocked()) {
-            return;
+            return $this->resultFactory->create(\Magento\Framework\Controller\ResultFactory::TYPE_RAW);
         }
 
         session_write_close();
@@ -29,20 +29,14 @@ class MassAdd extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshoppin
 
         try {
             $flag->lock();
-            $this->_objectManager->create(
-                'Magento\GoogleShopping\Model\MassOperations'
-            )->setFlag(
-                $flag
-            )->addProducts(
-                $productIds,
-                $storeId
-            );
+            $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;
+            return $this->_redirectToCaptcha($e);
         } catch (\Exception $e) {
             $flag->unlock();
             $this->notifier->addMajor(
@@ -50,9 +44,10 @@ class MassAdd extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshoppin
                 $e->getMessage()
             );
             $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
-            return;
+            return $this->resultFactory->create(\Magento\Framework\Controller\ResultFactory::TYPE_RAW);
         }
 
         $flag->unlock();
+        return $this->resultFactory->create(\Magento\Framework\Controller\ResultFactory::TYPE_RAW);
     }
 }
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/Refresh.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/Refresh.php
index 03fc43a2939797febd4ccdcc5bb1b837a3e9783c..60795768337b509e918aa33877ee4f8b5df2b447 100644
--- a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/Refresh.php
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/Refresh.php
@@ -1,7 +1,5 @@
 <?php
 /**
- * Update items statistics and remove the items which are not available in Google Content
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
@@ -10,6 +8,9 @@
 
 namespace Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Items;
 
+/**
+ * Update items statistics and remove the items which are not available in Google Content
+ */
 class Refresh extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Items
 {
     /**
@@ -20,13 +21,13 @@ class Refresh extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshoppin
     protected $operation = 'synchronizeItems';
 
     /**
-     * {@inheritdoc}
+     * @return \Magento\Framework\Controller\ResultInterface
      */
     public function execute()
     {
         $flag = $this->_getFlag();
         if ($flag->isLocked()) {
-            return;
+            return $this->resultFactory->create(\Magento\Framework\Controller\ResultFactory::TYPE_RAW);
         }
 
         session_write_close();
@@ -38,19 +39,14 @@ class Refresh extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshoppin
         try {
             $flag->lock();
             $operation = $this->operation;
-            $this->_objectManager->create(
-                'Magento\GoogleShopping\Model\MassOperations'
-            )->setFlag(
-                $flag
-            )->$operation(
-                $itemIds
-            );
+            $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;
+            return $this->_redirectToCaptcha($e);
         } catch (\Exception $e) {
             $flag->unlock();
             $this->notifier->addMajor(
@@ -60,9 +56,10 @@ class Refresh extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshoppin
                 )
             );
             $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
-            return;
+            return $this->resultFactory->create(\Magento\Framework\Controller\ResultFactory::TYPE_RAW);
         }
 
         $flag->unlock();
+        return $this->resultFactory->create(\Magento\Framework\Controller\ResultFactory::TYPE_RAW);
     }
 }
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/Status.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/Status.php
index 02e72b6a7ccbd2cacba6d2570eeda4740d0b353e..373b05d547cc4c3818e3558a3242ecd21afeb422 100644
--- a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/Status.php
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/Status.php
@@ -11,16 +11,16 @@ class Status extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshopping
     /**
      * Retrieve background process status
      *
-     * @return \Magento\Framework\App\Response\Http
+     * @return \Magento\Framework\Controller\Result\Json
      */
     public function execute()
     {
         if ($this->getRequest()->isAjax()) {
             $this->getResponse()->setHeader('Content-Type', 'application/json');
             $params = ['is_running' => $this->_getFlag()->isLocked()];
-            return $this->getResponse()->representJson(
-                $this->_objectManager->get('Magento\Framework\Json\Helper\Data')->jsonEncode($params)
-            );
+            /** @var \Magento\Framework\Controller\Result\Json $resultJson */
+            $resultJson = $this->resultFactory->create(\Magento\Framework\Controller\ResultFactory::TYPE_JSON);
+            return $resultJson->setData($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
index a8c5ec7e749d33b799233a0b402fc79f4e9bc065..c3103f9882740b17732fa8946c3d134f75045c8c 100644
--- a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Selection/Grid.php
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Selection/Grid.php
@@ -8,20 +8,35 @@ namespace Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Selection;
 
 class Grid extends \Magento\Backend\App\Action
 {
+    /**
+     * @var \Magento\Framework\View\LayoutFactory
+     */
+    protected $layoutFactory;
+
+    /**
+     * @param \Magento\Backend\App\Action\Context $context
+     * @param \Magento\Framework\View\LayoutFactory $layoutFactory
+     */
+    public function __construct(
+        \Magento\Backend\App\Action\Context $context,
+        \Magento\Framework\View\LayoutFactory $layoutFactory
+    ) {
+        $this->layoutFactory = $layoutFactory;
+        parent::__construct($context);
+    }
+
     /**
      * Grid with available products for Google Content
      *
-     * @return void
+     * @return \Magento\Framework\Controller\Result\Raw
      */
     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()
+        /** @var \Magento\Framework\Controller\Result\Raw $resultRaw */
+        $resultRaw = $this->resultFactory->create(\Magento\Framework\Controller\ResultFactory::TYPE_RAW);
+        return $resultRaw->setContents(
+            $this->layoutFactory->create()->createBlock('Magento\GoogleShopping\Block\Adminhtml\Items\Product')
+                ->setIndex($this->getRequest()->getParam('index'))->toHtml()
         );
     }
 }
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Selection/Search.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Selection/Search.php
index 487ae3016ae2994d2d142c87cb5dfcd3e7c5b648..8a86f1fd794f8b4fdf8be9127c1a23e49fdb2dab 100644
--- a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Selection/Search.php
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Selection/Search.php
@@ -8,21 +8,35 @@ namespace Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Selection;
 
 class Search extends \Magento\Backend\App\Action
 {
+    /**
+     * @var \Magento\Framework\View\LayoutFactory
+     */
+    protected $layoutFactory;
+
+    /**
+     * @param \Magento\Backend\App\Action\Context $context
+     * @param \Magento\Framework\View\LayoutFactory $layoutFactory
+     */
+    public function __construct(
+        \Magento\Backend\App\Action\Context $context,
+        \Magento\Framework\View\LayoutFactory $layoutFactory
+    ) {
+        $this->layoutFactory = $layoutFactory;
+        parent::__construct($context);
+    }
+
     /**
      * Search result grid with available products for Google Content
      *
-     * @return void
+     * @return \Magento\Framework\Controller\Result\Raw
      */
     public function execute()
     {
-        $this->getResponse()->setBody(
-            $this->_view->getLayout()->createBlock(
-                'Magento\GoogleShopping\Block\Adminhtml\Items\Product'
-            )->setIndex(
-                $this->getRequest()->getParam('index')
-            )->setFirstShow(
-                true
-            )->toHtml()
+        /** @var \Magento\Framework\Controller\Result\Raw $resultRaw */
+        $resultRaw = $this->resultFactory->create(\Magento\Framework\Controller\ResultFactory::TYPE_RAW);
+        return $resultRaw->setContents(
+            $this->layoutFactory->create()->createBlock('Magento\GoogleShopping\Block\Adminhtml\Items\Product')
+                ->setIndex($this->getRequest()->getParam('index'))->setFirstShow(true)->toHtml()
         );
     }
 }
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types.php
index a233721ed9f907b4c715ecd96d7389851b3e6a17..068fa2cdf168fd1e33bb838ca4dfa0508f2724fd 100644
--- a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types.php
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types.php
@@ -68,21 +68,16 @@ class Types extends \Magento\Backend\App\Action
     /**
      * Initialize general settings for action
      *
-     * @return $this
+     * @return \Magento\Backend\Model\View\Result\Page
      */
-    protected function _initAction()
+    protected function initPage()
     {
-        $this->_view->loadLayout();
-        $this->_setActiveMenu(
-            'Magento_GoogleShopping::catalog_googleshopping_types'
-        )->_addBreadcrumb(
-            __('Catalog'),
-            __('Catalog')
-        )->_addBreadcrumb(
-            __('Google Content'),
-            __('Google Content')
-        );
-        return $this;
+        /** @var \Magento\Backend\Model\View\Result\Page $resultPage */
+        $resultPage = $this->resultFactory->create(\Magento\Framework\Controller\ResultFactory::TYPE_PAGE);
+        $resultPage->setActiveMenu('Magento_GoogleShopping::catalog_googleshopping_types')
+            ->addBreadcrumb(__('Catalog'), __('Catalog'))
+            ->addBreadcrumb(__('Google Content'), __('Google Content'));
+        return $resultPage;
     }
 
     /**
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Edit.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Edit.php
index 89648aa1adabaa42ab4d07e41b667056e25e5fcc..e3f5eb02d2406786e6222f31416041c308bf5f9e 100644
--- a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Edit.php
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Edit.php
@@ -11,7 +11,7 @@ class Edit extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\T
     /**
      * Edit attribute set mapping
      *
-     * @return void
+     * @return \Magento\Backend\Model\View\Result\Page|\Magento\Backend\Model\View\Result\Redirect
      */
     public function execute()
     {
@@ -21,11 +21,9 @@ class Edit extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\T
         try {
             $result = [];
             if ($typeId) {
-                $collection = $this->_objectManager->create(
-                    'Magento\GoogleShopping\Model\Resource\Attribute\Collection'
-                )->addTypeFilter(
-                    $typeId
-                )->load();
+                $collection = $this->_objectManager
+                    ->create('Magento\GoogleShopping\Model\Resource\Attribute\Collection')
+                    ->addTypeFilter($typeId)->load();
                 foreach ($collection as $attribute) {
                     $result[] = $attribute->getData();
                 }
@@ -34,19 +32,22 @@ class Edit extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\T
             $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->getPage()->getConfig()->getTitle()->prepend(__('Google Content Attribute Mapping'));
-            $this->_view->getPage()->getConfig()->getTitle()->prepend(__('Google Content Attributes'));
-            $this->_view->renderLayout();
+
+            $resultPage = $this->initPage();
+            $resultPage->addBreadcrumb($breadcrumbLabel, $breadcrumbLabel)
+                ->addContent(
+                    $resultPage->getLayout()->createBlock('Magento\GoogleShopping\Block\Adminhtml\Types\Edit')
+                );
+
+            $resultPage->getConfig()->getTitle()->prepend(__('Google Content Attribute Mapping'));
+            $resultPage->getConfig()->getTitle()->prepend(__('Google Content Attributes'));
+            return $resultPage;
         } catch (\Exception $e) {
             $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $this->messageManager->addError(__("We can't edit Attribute Set Mapping."));
-            $this->_redirect('adminhtml/*/index');
+            /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
+            $resultRedirect = $this->resultFactory->create(\Magento\Framework\Controller\ResultFactory::TYPE_REDIRECT);
+            return $resultRedirect->setPath('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
index 1418bc0242a11271ec54d23ef3768dc6cce86141..91270934b4154ba019d2766c6c8911b1f8c64964 100644
--- a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Grid.php
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Grid.php
@@ -11,11 +11,10 @@ class Grid extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\T
     /**
      * Grid for AJAX request
      *
-     * @return void
+     * @return \Magento\Framework\View\Result\Layout
      */
     public function execute()
     {
-        $this->_view->loadLayout('false');
-        $this->_view->renderLayout();
+        return $this->resultFactory->create(\Magento\Framework\Controller\ResultFactory::TYPE_LAYOUT);
     }
 }
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Index.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Index.php
index 30232cbe3d40df6ca6d84739e4d94ba98ce1720d..b6116c7316a0283956bf4f8a049e2509c2f691a6 100644
--- a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Index.php
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Index.php
@@ -11,12 +11,12 @@ class Index extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\
     /**
      * List of all maps (items)
      *
-     * @return void
+     * @return \Magento\Backend\Model\View\Result\Page
      */
     public function execute()
     {
-        $this->_initAction()->_addBreadcrumb(__('Attribute Maps'), __('Attribute Maps'));
-        $this->_view->getPage()->getConfig()->getTitle()->prepend(__('Google Content Attributes'));
-        $this->_view->renderLayout();
+        $resultPage = $this->initPage()->addBreadcrumb(__('Attribute Maps'), __('Attribute Maps'));
+        $resultPage->getConfig()->getTitle()->prepend(__('Google Content Attributes'));
+        return $resultPage;
     }
 }
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/LoadAttributeSets.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/LoadAttributeSets.php
index 6cb5d6885d1355e0049abc808c63bc297ea878c4..fc8a1dc2bd6ccf7ed9b86858edf1983d0308de52 100644
--- a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/LoadAttributeSets.php
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/LoadAttributeSets.php
@@ -1,6 +1,5 @@
 <?php
 /**
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
@@ -8,16 +7,37 @@ namespace Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Types;
 
 class LoadAttributeSets extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Types
 {
+    /**
+     * @var \Magento\Framework\View\LayoutFactory
+     */
+    protected $layoutFactory;
+
+    /**
+     * @param \Magento\Backend\App\Action\Context $context
+     * @param \Magento\Framework\Registry $coreRegistry
+     * @param \Magento\Framework\View\LayoutFactory $layoutFactory
+     */
+    public function __construct(
+        \Magento\Backend\App\Action\Context $context,
+        \Magento\Framework\Registry $coreRegistry,
+        \Magento\Framework\View\LayoutFactory $layoutFactory
+    ) {
+        $this->layoutFactory = $layoutFactory;
+        parent::__construct($context, $coreRegistry);
+    }
+
     /**
      * Get available attribute sets
      *
-     * @return void
+     * @return \Magento\Framework\Controller\Result\Raw
      * @throws \Exception
      */
     public function execute()
     {
-        $this->getResponse()->setBody(
-            $this->_view->getLayout()->getBlockSingleton('Magento\GoogleShopping\Block\Adminhtml\Types\Edit\Form')
+        /** @var \Magento\Framework\Controller\Result\Raw $resultRaw */
+        $resultRaw = $this->resultFactory->create(\Magento\Framework\Controller\ResultFactory::TYPE_RAW);
+        return $resultRaw->setContents(
+            $this->layoutFactory->create()->getBlockSingleton('Magento\GoogleShopping\Block\Adminhtml\Types\Edit\Form')
                 ->getAttributeSetsSelectElement($this->getRequest()->getParam('target_country'))
                 ->toHtml()
         );
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/LoadAttributes.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/LoadAttributes.php
index 54a0bce4af48ce45f7c35ced453aff950f94a9f3..0d817329dd869c3b8563c784190729ce2a04a394 100644
--- a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/LoadAttributes.php
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/LoadAttributes.php
@@ -8,29 +8,48 @@ namespace Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Types;
 
 class LoadAttributes extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Types
 {
+    /**
+     * @var \Magento\Framework\View\LayoutFactory
+     */
+    protected $layoutFactory;
+
+    /**
+     * @param \Magento\Backend\App\Action\Context $context
+     * @param \Magento\Framework\Registry $coreRegistry
+     * @param \Magento\Framework\View\LayoutFactory $layoutFactory
+     */
+    public function __construct(
+        \Magento\Backend\App\Action\Context $context,
+        \Magento\Framework\Registry $coreRegistry,
+        \Magento\Framework\View\LayoutFactory $layoutFactory
+    ) {
+        $this->layoutFactory = $layoutFactory;
+        parent::__construct($context, $coreRegistry);
+    }
+
     /**
      * Get Google Content attributes list
      *
-     * @return void
+     * @return \Magento\Framework\Controller\Result\Raw
      */
     public function execute()
     {
+        /** @var \Magento\Framework\Controller\Result\Raw $resultRaw */
+        $resultRaw = $this->resultFactory->create(\Magento\Framework\Controller\ResultFactory::TYPE_RAW);
         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()
+            $resultRaw->setContents(
+                $this->layoutFactory->create()
+                    ->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('Psr\Log\LoggerInterface')->critical($e);
             // just need to output text with error
             $this->messageManager->addError(__("We can't load attributes."));
         }
+        return $resultRaw;
     }
 }
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/NewAction.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/NewAction.php
index ffb8ee171b7f6fc7c7466178b5b67e04f7e481a3..86b62a33b9c033d19c3153b56161a5e769cacb1c 100644
--- a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/NewAction.php
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/NewAction.php
@@ -1,6 +1,5 @@
 <?php
 /**
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
@@ -11,25 +10,31 @@ class NewAction extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshopp
     /**
      * Create new attribute set mapping
      *
-     * @return void
+     * @return \Magento\Backend\Model\View\Result\Page|\Magento\Backend\Model\View\Result\Redirect
      */
     public function execute()
     {
         try {
             $this->_initItemType();
-            $this->_initAction()->_addBreadcrumb(
+
+            /** @var \Magento\Backend\Model\View\Result\Page $resultPage */
+            $resultPage = $this->initPage()->addBreadcrumb(
                 __('New attribute set mapping'),
                 __('New attribute set mapping')
-            )->_addContent(
-                $this->_view->getLayout()->createBlock('Magento\GoogleShopping\Block\Adminhtml\Types\Edit')
             );
-            $this->_view->getPage()->getConfig()->getTitle()->prepend(__('Google Content Attributes'));
-            $this->_view->getPage()->getConfig()->getTitle()->prepend(__('New Google Content Attribute Mapping'));
-            $this->_view->renderLayout();
+            $resultPage->addContent(
+                $resultPage->getLayout()->createBlock('Magento\GoogleShopping\Block\Adminhtml\Types\Edit')
+            );
+            $resultPage->getConfig()->getTitle()->prepend(__('Google Content Attributes'));
+            $resultPage->getConfig()->getTitle()->prepend(__('New Google Content Attribute Mapping'));
+            return $resultPage;
         } catch (\Exception $e) {
             $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $this->messageManager->addError(__("We can't create Attribute Set Mapping."));
-            $this->_redirect('adminhtml/*/index', ['store' => $this->_getStore()->getId()]);
+            /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
+            $resultRedirect = $this->resultFactory->create(\Magento\Framework\Controller\ResultFactory::TYPE_REDIRECT);
+            $resultRedirect->setPath('adminhtml/*/index', ['store' => $this->_getStore()->getId()]);
+            return $resultRedirect;
         }
     }
 }
diff --git a/app/code/Magento/GoogleShopping/Model/Attribute/Tax.php b/app/code/Magento/GoogleShopping/Model/Attribute/Tax.php
index 089f14216bdadb05a1ee8c4b4530526b46ad892a..d20e9cc0cc88c9215df5aa15b0b69cd32ccb5061 100644
--- a/app/code/Magento/GoogleShopping/Model/Attribute/Tax.php
+++ b/app/code/Magento/GoogleShopping/Model/Attribute/Tax.php
@@ -8,6 +8,7 @@ namespace Magento\GoogleShopping\Model\Attribute;
 use Magento\Framework\Parse\Zip;
 use Magento\Store\Model\Store;
 use Magento\Tax\Api\Data\TaxClassKeyInterface;
+use Magento\Tax\Model\TaxClass\Key;
 
 /**
  * Tax attribute model
@@ -179,8 +180,8 @@ class Tax extends \Magento\GoogleShopping\Model\Attribute\DefaultAttribute
                         'code' => $product->getSku(),
                         'type' => 'product',
                         'tax_class_key' => [
-                            TaxClassKeyInterface::KEY_TYPE => TaxClassKeyInterface::TYPE_ID,
-                            TaxClassKeyInterface::KEY_VALUE => $product->getTaxClassId(),
+                            Key::KEY_TYPE => TaxClassKeyInterface::TYPE_ID,
+                            Key::KEY_VALUE => $product->getTaxClassId(),
                         ],
                         'unit_price' => $product->getPrice(),
                         'quantity' => 1,
@@ -204,8 +205,8 @@ class Tax extends \Magento\GoogleShopping\Model\Attribute\DefaultAttribute
                         'billing_address' => $billingAddressDataArray,
                         'shipping_address' => $shippingAddressDataArray,
                         'customer_tax_class_key' => [
-                            TaxClassKeyInterface::KEY_TYPE => TaxClassKeyInterface::TYPE_ID,
-                            TaxClassKeyInterface::KEY_VALUE => $defaultCustomerTaxClassId,
+                            Key::KEY_TYPE => TaxClassKeyInterface::TYPE_ID,
+                            Key::KEY_VALUE => $defaultCustomerTaxClassId,
                         ],
                         'items' => [
                             $quoteDetailsItemDataArray,
diff --git a/app/code/Magento/GoogleShopping/composer.json b/app/code/Magento/GoogleShopping/composer.json
index 267a3c8cb23aeea71338a8532432c3e4a133ce26..6960954e41d5609fece948947ce2eb7bf0f89ed2 100644
--- a/app/code/Magento/GoogleShopping/composer.json
+++ b/app/code/Magento/GoogleShopping/composer.json
@@ -3,18 +3,18 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/module-customer": "0.74.0-beta6",
-        "magento/module-directory": "0.74.0-beta6",
-        "magento/module-eav": "0.74.0-beta6",
-        "magento/module-tax": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/module-customer": "0.74.0-beta7",
+        "magento/module-directory": "0.74.0-beta7",
+        "magento/module-eav": "0.74.0-beta7",
+        "magento/module-tax": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/GroupedImportExport/composer.json b/app/code/Magento/GroupedImportExport/composer.json
index 2d66faa4f5b3761512df683740754d918999fe0c..b74fc2be667c10aebcb7067d20923281e1c17cf0 100644
--- a/app/code/Magento/GroupedImportExport/composer.json
+++ b/app/code/Magento/GroupedImportExport/composer.json
@@ -3,16 +3,16 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/module-import-export": "0.74.0-beta6",
-        "magento/module-catalog-import-export": "0.74.0-beta6",
-        "magento/module-grouped-product": "0.74.0-beta6",
-        "magento/module-eav": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/module-import-export": "0.74.0-beta7",
+        "magento/module-catalog-import-export": "0.74.0-beta7",
+        "magento/module-grouped-product": "0.74.0-beta7",
+        "magento/module-eav": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php b/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php
index d856527779116c8c6795c79d704fc90a892bfcd2..5ee51f1ecbfb45622fd6f8c28955de99da4c2874 100644
--- a/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php
+++ b/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php
@@ -480,7 +480,7 @@ class Grouped extends \Magento\Catalog\Model\Product\Type\AbstractType
      */
     public function beforeSave($product)
     {
-        if ($product->hasData('product_options')) {
+        if ($product->hasData('product_options') && !empty($product->getData('product_options'))) {
             throw new \Exception('Custom options for grouped product type are not supported');
         }
         return parent::beforeSave($product);
diff --git a/app/code/Magento/GroupedProduct/Test/Unit/Model/ProductTest.php b/app/code/Magento/GroupedProduct/Test/Unit/Model/ProductTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..04d7f729f8c86ad5a0c85435bfa266584cf3fbb1
--- /dev/null
+++ b/app/code/Magento/GroupedProduct/Test/Unit/Model/ProductTest.php
@@ -0,0 +1,430 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+// @codingStandardsIgnoreFile
+
+namespace Magento\GroupedProduct\Test\Unit\Model;
+
+use \Magento\Catalog\Model\Product;
+
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
+
+/**
+ * Product Test
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ * @SuppressWarnings(PHPMD.TooManyFields)
+ *
+ */
+class ProductTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var ObjectManagerHelper
+     */
+    protected $objectManagerHelper;
+
+    /**
+     * @var \Magento\Catalog\Model\Product
+     */
+    protected $model;
+
+    /**
+     * @var \Magento\Framework\Module\Manager|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $moduleManager;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $stockItemFactoryMock;
+
+    /**
+     * @var \Magento\Indexer\Model\IndexerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $categoryIndexerMock;
+
+    /**
+     * @var \Magento\Catalog\Model\Indexer\Product\Flat\Processor|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productFlatProcessor;
+
+    /**
+     * @var \Magento\Catalog\Model\Indexer\Product\Price\Processor|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productPriceProcessor;
+
+    /**
+     * @var Product\Type|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productTypeInstanceMock;
+
+    /**
+     * @var Product\Option|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $optionInstanceMock;
+
+    /**
+     * @var \Magento\Framework\Pricing\PriceInfo\Base|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_priceInfoMock;
+
+    /**
+     * @var \Magento\Store\Model\Store|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $store;
+
+    /**
+     * @var \Magento\Catalog\Model\Resource\Product|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $resource;
+
+    /**
+     * @var \Magento\Framework\Registry|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $registry;
+
+    /**
+     * @var \Magento\Catalog\Model\Category|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $category;
+
+    /**
+     * @var \Magento\Store\Model\Website|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $website;
+
+    /**
+     * @var \Magento\Indexer\Model\IndexerRegistry|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $indexerRegistryMock;
+
+    /**
+     * @var \Magento\Catalog\Api\CategoryRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $categoryRepository;
+
+    /**
+     * @var \Magento\Catalog\Helper\Product|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $_catalogProduct;
+
+    /**
+     * @var \Magento\Catalog\Model\Product\Image\Cache|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $imageCache;
+
+    /**
+     * @var \Magento\Catalog\Model\Product\Image\CacheFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $imageCacheFactory;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $mediaGalleryEntryFactoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productLinkFactory;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $dataObjectHelperMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $metadataServiceMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $attributeValueFactory;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $linkTypeProviderMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $entityCollectionProviderMock;
+
+    /**
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     */
+    public function setUp()
+    {
+        $this->categoryIndexerMock = $this->getMockForAbstractClass('\Magento\Indexer\Model\IndexerInterface');
+
+        $this->moduleManager = $this->getMock(
+            'Magento\Framework\Module\Manager',
+            ['isEnabled'],
+            [],
+            '',
+            false
+        );
+        $this->stockItemFactoryMock = $this->getMock(
+            'Magento\CatalogInventory\Api\Data\StockItemInterfaceFactory',
+            ['create'],
+            [],
+            '',
+            false
+        );
+        $this->dataObjectHelperMock = $this->getMockBuilder('\Magento\Framework\Api\DataObjectHelper')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->productFlatProcessor = $this->getMock(
+            'Magento\Catalog\Model\Indexer\Product\Flat\Processor',
+            [],
+            [],
+            '',
+            false
+        );
+
+        $this->_priceInfoMock = $this->getMock('Magento\Framework\Pricing\PriceInfo\Base', [], [], '', false);
+        $this->productTypeInstanceMock = $this->getMock('Magento\Catalog\Model\Product\Type', [], [], '', false);
+        $this->productPriceProcessor = $this->getMock(
+            'Magento\Catalog\Model\Indexer\Product\Price\Processor',
+            [],
+            [],
+            '',
+            false
+        );
+
+        $stateMock = $this->getMock('Magento\FrameworkApp\State', ['getAreaCode'], [], '', false);
+        $stateMock->expects($this->any())
+            ->method('getAreaCode')
+            ->will($this->returnValue(\Magento\Backend\App\Area\FrontNameResolver::AREA_CODE));
+
+        $eventManagerMock = $this->getMock('Magento\Framework\Event\ManagerInterface');
+        $actionValidatorMock = $this->getMock(
+            '\Magento\Framework\Model\ActionValidator\RemoveAction',
+            [],
+            [],
+            '',
+            false
+        );
+        $actionValidatorMock->expects($this->any())->method('isAllowed')->will($this->returnValue(true));
+        $cacheInterfaceMock = $this->getMock('Magento\Framework\App\CacheInterface');
+
+        $contextMock = $this->getMock(
+            '\Magento\Framework\Model\Context',
+            ['getEventDispatcher', 'getCacheManager', 'getAppState', 'getActionValidator'], [], '', false
+        );
+        $contextMock->expects($this->any())->method('getAppState')->will($this->returnValue($stateMock));
+        $contextMock->expects($this->any())->method('getEventDispatcher')->will($this->returnValue($eventManagerMock));
+        $contextMock->expects($this->any())
+            ->method('getCacheManager')
+            ->will($this->returnValue($cacheInterfaceMock));
+        $contextMock->expects($this->any())
+            ->method('getActionValidator')
+            ->will($this->returnValue($actionValidatorMock));
+
+        $this->optionInstanceMock = $this->getMockBuilder('Magento\Catalog\Model\Product\Option')
+            ->setMethods(['setProduct', 'saveOptions', '__wakeup', '__sleep'])
+            ->disableOriginalConstructor()->getMock();
+
+        $this->resource = $this->getMockBuilder('Magento\Catalog\Model\Resource\Product')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->registry = $this->getMockBuilder('Magento\Framework\Registry')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->category = $this->getMockBuilder('Magento\Catalog\Model\Category')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->store = $this->getMockBuilder('Magento\Store\Model\Store')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->website = $this->getMockBuilder('\Magento\Store\Model\Website')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $storeManager = $this->getMockBuilder('Magento\Store\Model\StoreManagerInterface')
+            ->disableOriginalConstructor()
+            ->getMockForAbstractClass();
+        $storeManager->expects($this->any())
+            ->method('getStore')
+            ->will($this->returnValue($this->store));
+        $storeManager->expects($this->any())
+            ->method('getWebsite')
+            ->will($this->returnValue($this->website));
+        $this->indexerRegistryMock = $this->getMock('Magento\Indexer\Model\IndexerRegistry', ['get'], [], '', false);
+        $this->categoryRepository = $this->getMock('Magento\Catalog\Api\CategoryRepositoryInterface');
+
+        $this->_catalogProduct = $this->getMock(
+            'Magento\Catalog\Helper\Product',
+            ['isDataForProductCategoryIndexerWasChanged'],
+            [],
+            '',
+            false
+        );
+
+        $this->imageCache = $this->getMockBuilder('Magento\Catalog\Model\Product\Image\Cache')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->imageCacheFactory = $this->getMockBuilder('Magento\Catalog\Model\Product\Image\CacheFactory')
+            ->disableOriginalConstructor()
+            ->setMethods(['create'])
+            ->getMock();
+
+        $this->productLinkFactory = $this->getMockBuilder('Magento\Catalog\Api\Data\ProductLinkInterfaceFactory')
+            ->disableOriginalConstructor()
+            ->setMethods(['create'])
+            ->getMock();
+
+        $this->mediaGalleryEntryFactoryMock =
+            $this->getMockBuilder('Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterfaceFactory')
+                ->setMethods(['create'])
+                ->disableOriginalConstructor()
+                ->getMock();
+
+        $this->metadataServiceMock = $this->getMock('\Magento\Catalog\Api\ProductAttributeRepositoryInterface');
+        $this->attributeValueFactory = $this->getMockBuilder('Magento\Framework\Api\AttributeValueFactory')
+            ->disableOriginalConstructor()->getMock();
+        $this->linkTypeProviderMock = $this->getMock('Magento\Catalog\Model\Product\LinkTypeProvider',
+            ['getLinkTypes'], [], '', false);
+        $this->entityCollectionProviderMock = $this->getMock('Magento\Catalog\Model\ProductLink\CollectionProvider',
+            ['getCollection'], [], '', false);
+
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+        $this->model = $this->objectManagerHelper->getObject(
+            'Magento\Catalog\Model\Product',
+            [
+                'context' => $contextMock,
+                'catalogProductType' => $this->productTypeInstanceMock,
+                'productFlatIndexerProcessor' => $this->productFlatProcessor,
+                'productPriceIndexerProcessor' => $this->productPriceProcessor,
+                'catalogProductOption' => $this->optionInstanceMock,
+                'storeManager' => $storeManager,
+                'resource' => $this->resource,
+                'registry' => $this->registry,
+                'moduleManager' => $this->moduleManager,
+                'stockItemFactory' => $this->stockItemFactoryMock,
+                'dataObjectHelper' => $this->dataObjectHelperMock,
+                'indexerRegistry' => $this->indexerRegistryMock,
+                'categoryRepository' => $this->categoryRepository,
+                'catalogProduct' => $this->_catalogProduct,
+                'imageCacheFactory' => $this->imageCacheFactory,
+                'productLinkFactory' => $this->productLinkFactory,
+                'mediaGalleryEntryFactory' => $this->mediaGalleryEntryFactoryMock,
+                'metadataService' => $this->metadataServiceMock,
+                'customAttributeFactory' => $this->attributeValueFactory,
+                'entityCollectionProvider' => $this->entityCollectionProviderMock,
+                'linkTypeProvider' => $this->linkTypeProviderMock,
+                'data' => ['id' => 1]
+            ]
+        );
+
+    }
+
+    /**
+     *  Test for getProductLinks() with associated product links
+     */
+    public function testGetProductLinks()
+    {
+        $this->markTestIncomplete('Skipped due to https://jira.corp.x.com/browse/MAGETWO-36926');
+        $linkTypes = ['related' => 1, 'upsell' => 4, 'crosssell' => 5, 'associated' => 3];
+        $this->linkTypeProviderMock->expects($this->once())
+            ->method('getLinkTypes')
+            ->willReturn($linkTypes);
+
+        $inputRelatedLink = $this->objectManagerHelper->getObject('Magento\Catalog\Model\ProductLink\Link');
+        $inputRelatedLink->setProductSku("Simple Product 1");
+        $inputRelatedLink->setLinkType("related");
+        $inputRelatedLink->setData("sku", "Simple Product 2");
+        $inputRelatedLink->setData("type", "simple");
+        $inputRelatedLink->setPosition(0);
+
+        $customData = ["attribute_code" => "qty", "value" => 1];
+        $inputGroupLink = $this->objectManagerHelper->getObject('Magento\Catalog\Model\ProductLink\Link');
+        $inputGroupLink->setProductSku("Simple Product 1");
+        $inputGroupLink->setLinkType("associated");
+        $inputGroupLink->setData("sku", "Simple Product 2");
+        $inputGroupLink->setData("type", "simple");
+        $inputGroupLink->setPosition(0);
+        $inputGroupLink["custom_attributes"] = [$customData];
+
+        $outputRelatedLink = $this->objectManagerHelper->getObject('Magento\Catalog\Model\ProductLink\Link');
+        $outputRelatedLink->setProductSku("Simple Product 1");
+        $outputRelatedLink->setLinkType("related");
+        $outputRelatedLink->setLinkedProductSku("Simple Product 2");
+        $outputRelatedLink->setLinkedProductType("simple");
+        $outputRelatedLink->setPosition(0);
+
+        $groupExtension = $this->objectManagerHelper->getObject('Magento\Catalog\Api\Data\ProductLinkExtension');
+        $reflectionOfExtension = new \ReflectionClass('Magento\Catalog\Api\Data\ProductLinkExtension');
+        $method = $reflectionOfExtension->getMethod('setData');
+        $method->setAccessible(true);
+        $method->invokeArgs($groupExtension, array('qty', 1));
+
+        $outputGroupLink = $this->objectManagerHelper->getObject('Magento\Catalog\Model\ProductLink\Link');
+        $outputGroupLink->setProductSku("Simple Product 1");
+        $outputGroupLink->setLinkType("associated");
+        $outputGroupLink->setLinkedProductSku("Simple Product 2");
+        $outputGroupLink->setLinkedProductType("simple");
+        $outputGroupLink->setPosition(0);
+        $outputGroupLink->setExtensionAttributes($groupExtension);
+
+        $this->entityCollectionProviderMock->expects($this->at(0))
+            ->method('getCollection')
+            ->with($this->model, 'related')
+            ->willReturn([$inputRelatedLink]);
+        $this->entityCollectionProviderMock->expects($this->at(1))
+            ->method('getCollection')
+            ->with($this->model, 'upsell')
+            ->willReturn([]);
+        $this->entityCollectionProviderMock->expects($this->at(2))
+            ->method('getCollection')
+            ->with($this->model, 'crosssell')
+            ->willReturn([]);
+        $this->entityCollectionProviderMock->expects($this->at(3))
+            ->method('getCollection')
+            ->with($this->model, 'associated')
+            ->willReturn([$inputGroupLink]);
+
+        $expectedOutput = [$outputRelatedLink, $outputGroupLink];
+        $typeInstanceMock = $this->getMock(
+            'Magento\ConfigurableProduct\Model\Product\Type\Simple', ["getSku"], [], '', false);
+        $typeInstanceMock
+            ->expects($this->atLeastOnce())
+            ->method('getSku')
+            ->willReturn("Simple Product 1");
+        $this->model->setTypeInstance($typeInstanceMock);
+
+        $productLink1 = $this->objectManagerHelper->getObject('Magento\Catalog\Model\ProductLink\Link');
+        $productLink2 = $this->objectManagerHelper->getObject('Magento\Catalog\Model\ProductLink\Link');
+        $this->productLinkFactory->expects($this->at(0))
+            ->method('create')
+            ->willReturn($productLink1);
+        $this->productLinkFactory->expects($this->at(1))
+            ->method('create')
+            ->willReturn($productLink2);
+
+        $extension = $this->objectManagerHelper->getObject('Magento\Catalog\Api\Data\ProductLinkExtension');
+        $productLink2->setExtensionAttributes($extension);
+
+        $links = $this->model->getProductLinks();
+        // Match the links
+        $matches = 0;
+        foreach ($links as $link) {
+            foreach ($expectedOutput as $expected) {
+                if ($expected->getData() == $link->getData()) {
+                    $matches++;
+                }
+            }
+        }
+        $this->assertEquals($matches, 2);
+    }
+}
diff --git a/app/code/Magento/GroupedProduct/composer.json b/app/code/Magento/GroupedProduct/composer.json
index cdd8818ca6b36d0d881e58e187ae078e61590d0c..69f557ba1be410195e5790a509f47302711c3173 100644
--- a/app/code/Magento/GroupedProduct/composer.json
+++ b/app/code/Magento/GroupedProduct/composer.json
@@ -3,22 +3,22 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/module-catalog-inventory": "0.74.0-beta6",
-        "magento/module-sales": "0.74.0-beta6",
-        "magento/module-checkout": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-eav": "0.74.0-beta6",
-        "magento/module-customer": "0.74.0-beta6",
-        "magento/module-media-storage": "0.74.0-beta6",
-        "magento/module-msrp": "0.74.0-beta6",
-        "magento/module-quote": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/module-catalog-inventory": "0.74.0-beta7",
+        "magento/module-sales": "0.74.0-beta7",
+        "magento/module-checkout": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-eav": "0.74.0-beta7",
+        "magento/module-customer": "0.74.0-beta7",
+        "magento/module-media-storage": "0.74.0-beta7",
+        "magento/module-msrp": "0.74.0-beta7",
+        "magento/module-quote": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/GroupedProduct/etc/data_object.xml b/app/code/Magento/GroupedProduct/etc/service_data_attributes.xml
similarity index 66%
rename from app/code/Magento/GroupedProduct/etc/data_object.xml
rename to app/code/Magento/GroupedProduct/etc/service_data_attributes.xml
index d6a76ebaa081f2e742c78e66d70dc504c460bdde..0618cc9286cfd8ccb0cab46f6a505b05a39c4ee2 100644
--- a/app/code/Magento/GroupedProduct/etc/data_object.xml
+++ b/app/code/Magento/GroupedProduct/etc/service_data_attributes.xml
@@ -5,8 +5,8 @@
  * See COPYING.txt for license details.
  */
 -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Api/etc/data_object.xsd">
-    <custom_attributes for="Magento\Catalog\Api\Data\ProductLinkInterface">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Api/etc/service_data_attributes.xsd">
+    <extension_attributes for="Magento\Catalog\Api\Data\ProductLinkInterface">
         <attribute code="qty" type="float" />
-    </custom_attributes>
+    </extension_attributes>
 </config>
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 0a09bcdf7488f7cc713a1a13a9f8b05e1027262d..08f14bf4c075522f0ef228743d89de74221b1b21 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
@@ -20,7 +20,7 @@
         <?php if ((!$_product->isAvailable() && !$_skipSaleableCheck) || !$_hasAssociatedProducts): ?>
             <p class="availability out-of-stock"><?php echo __('Availability:') ?> <span><?php echo __('Out of stock') ?></span></p>
         <?php endif; ?>
-        <table class="data-table table-info grouped-items-table" id="super-product-table">
+        <table class="data-table admin__table-primary grouped-items-table" id="super-product-table">
             <thead>
                 <tr class="headings">
                     <th class="col-id"><?php echo __('ID') ?></th>
diff --git a/app/code/Magento/ImportExport/composer.json b/app/code/Magento/ImportExport/composer.json
index 747df1717017a7ddeffb4d80ef8640f23e2f5dfd..cc859dbe4b4f79012ea771cf2434247ea9b8cd5c 100644
--- a/app/code/Magento/ImportExport/composer.json
+++ b/app/code/Magento/ImportExport/composer.json
@@ -3,17 +3,17 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-eav": "0.74.0-beta6",
-        "magento/module-indexer": "0.74.0-beta6",
-        "magento/module-media-storage": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-eav": "0.74.0-beta7",
+        "magento/module-indexer": "0.74.0-beta7",
+        "magento/module-media-storage": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "ext-ctype": "*",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/ImportExport/view/adminhtml/templates/import/form/after.phtml b/app/code/Magento/ImportExport/view/adminhtml/templates/import/form/after.phtml
index 98557c0254c317fbcb7b6803508e9759e222e90b..26275ec71c97b8efd83193db658f05ac0632d576 100644
--- a/app/code/Magento/ImportExport/view/adminhtml/templates/import/form/after.phtml
+++ b/app/code/Magento/ImportExport/view/adminhtml/templates/import/form/after.phtml
@@ -9,7 +9,7 @@
         <span class="icon-head head-edit-form fieldset-legend"
             id="import_validation_container_header"><?php echo __('Validation Results'); ?></span>
     </div><br>
-    <div id="import_validation_messages" class="fieldset admin__scope"><!-- --></div>
+    <div id="import_validation_messages" class="fieldset"><!-- --></div>
 </div>
 <script>
 require(['jquery', 'prototype'], function(jQuery){
diff --git a/app/code/Magento/Indexer/composer.json b/app/code/Magento/Indexer/composer.json
index 13b2594e6abd971cfa42adbb147d542bb9f30c3a..b346637038367b28a5ad2c08d5d57e1bed717eaa 100644
--- a/app/code/Magento/Indexer/composer.json
+++ b/app/code/Magento/Indexer/composer.json
@@ -3,14 +3,14 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-page-cache": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta4",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-page-cache": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Integration/composer.json b/app/code/Magento/Integration/composer.json
index 9fa6582f0d0cd4bb38e11ceed92222616d1abd5a..0c5cf5c42e60e1228d5701fe8df076f5f3c64547 100644
--- a/app/code/Magento/Integration/composer.json
+++ b/app/code/Magento/Integration/composer.json
@@ -3,16 +3,16 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-customer": "0.74.0-beta6",
-        "magento/module-user": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
-        "magento/module-authorization": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-customer": "0.74.0-beta7",
+        "magento/module-user": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
+        "magento/module-authorization": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/LayeredNavigation/composer.json b/app/code/Magento/LayeredNavigation/composer.json
index ed19740fa51a2ec85a258179adb1147d47cbe49e..3651e00bcad830257b36b43b9ca6ff3da9ca0fe4 100644
--- a/app/code/Magento/LayeredNavigation/composer.json
+++ b/app/code/Magento/LayeredNavigation/composer.json
@@ -3,13 +3,13 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-config": "0.74.0-beta6",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-config": "0.74.0-beta7",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Log/composer.json b/app/code/Magento/Log/composer.json
index 5179484e4165391b9d64e747c7cde887bacdc2c5..3673638d5fdf881571d1fc6d10276dd7c134415d 100644
--- a/app/code/Magento/Log/composer.json
+++ b/app/code/Magento/Log/composer.json
@@ -3,15 +3,15 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-customer": "0.74.0-beta6",
-        "magento/module-eav": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-customer": "0.74.0-beta7",
+        "magento/module-eav": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/MediaStorage/composer.json b/app/code/Magento/MediaStorage/composer.json
index 1a140593019d9982ad679be6ab959f95baf4ac63..e2ff84226413e9021790faeec53aa2c04734bc46 100644
--- a/app/code/Magento/MediaStorage/composer.json
+++ b/app/code/Magento/MediaStorage/composer.json
@@ -3,14 +3,14 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-config": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-config": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Msrp/composer.json b/app/code/Magento/Msrp/composer.json
index 5e288eaebe15fdb2d3d2c35d2fa2ca7de5fd5dae..3ddcf10eef3fd3ae49d4bd7ab71c2f74fe5da3df 100644
--- a/app/code/Magento/Msrp/composer.json
+++ b/app/code/Magento/Msrp/composer.json
@@ -3,19 +3,19 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-bundle": "0.74.0-beta6",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/module-downloadable": "0.74.0-beta6",
-        "magento/module-eav": "0.74.0-beta6",
-        "magento/module-grouped-product": "0.74.0-beta6",
-        "magento/module-tax": "0.74.0-beta6",
-        "magento/module-quote": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-bundle": "0.74.0-beta7",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/module-downloadable": "0.74.0-beta7",
+        "magento/module-eav": "0.74.0-beta7",
+        "magento/module-grouped-product": "0.74.0-beta7",
+        "magento/module-tax": "0.74.0-beta7",
+        "magento/module-quote": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Multishipping/composer.json b/app/code/Magento/Multishipping/composer.json
index ebcccdf5ade42bf663bb71b3bf0c100e6800df47..8b782fc5aa17d9f3702bf2e6babe60e105e3eccf 100644
--- a/app/code/Magento/Multishipping/composer.json
+++ b/app/code/Magento/Multishipping/composer.json
@@ -3,19 +3,19 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-checkout": "0.74.0-beta6",
-        "magento/module-sales": "0.74.0-beta6",
-        "magento/module-payment": "0.74.0-beta6",
-        "magento/module-tax": "0.74.0-beta6",
-        "magento/module-customer": "0.74.0-beta6",
-        "magento/module-theme": "0.74.0-beta6",
-        "magento/module-quote": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-checkout": "0.74.0-beta7",
+        "magento/module-sales": "0.74.0-beta7",
+        "magento/module-payment": "0.74.0-beta7",
+        "magento/module-tax": "0.74.0-beta7",
+        "magento/module-customer": "0.74.0-beta7",
+        "magento/module-theme": "0.74.0-beta7",
+        "magento/module-quote": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Newsletter/Model/Session.php b/app/code/Magento/Newsletter/Model/Session.php
index 18d680df142601fb39eab95181cee59a79cca4cb..2ffb0b2f25236066922a7510267f10135c1a518f 100644
--- a/app/code/Magento/Newsletter/Model/Session.php
+++ b/app/code/Magento/Newsletter/Model/Session.php
@@ -8,7 +8,7 @@ namespace Magento\Newsletter\Model;
 /**
  * Newsletter session model
  */
-class Session extends \Magento\Framework\Session\Generic
+class Session extends \Magento\Framework\Session\SessionManager
 {
     /**
      * Set error message
diff --git a/app/code/Magento/Newsletter/Model/Subscriber.php b/app/code/Magento/Newsletter/Model/Subscriber.php
index f2885610281947d30f55abdccb526e6a270c6ac4..5fa2c3aa052638f3841cefcc5ddfe6bf1ef4358a 100644
--- a/app/code/Magento/Newsletter/Model/Subscriber.php
+++ b/app/code/Magento/Newsletter/Model/Subscriber.php
@@ -442,7 +442,6 @@ class Subscriber extends \Magento\Framework\Model\AbstractModel
         $this->setStatusChanged(true);
 
         try {
-            $this->save();
             if ($isConfirmNeed === true
                 && $isOwnSubscribes === false
             ) {
@@ -450,6 +449,7 @@ class Subscriber extends \Magento\Framework\Model\AbstractModel
             } else {
                 $this->sendConfirmationSuccessEmail();
             }
+            $this->save();
             return $this->getStatus();
         } catch (\Exception $e) {
             throw new \Exception($e->getMessage());
diff --git a/app/code/Magento/Newsletter/Test/Unit/Model/SubscriberTest.php b/app/code/Magento/Newsletter/Test/Unit/Model/SubscriberTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..bd8380299a52ee06f8d95a9ddea229ae2649160e
--- /dev/null
+++ b/app/code/Magento/Newsletter/Test/Unit/Model/SubscriberTest.php
@@ -0,0 +1,164 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Newsletter\Test\Unit\Model;
+
+class SubscriberTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Newsletter\Helper\Data|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $newsletterData;
+
+    /**
+     * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $scopeConfig;
+
+    /**
+     * @var \Magento\Framework\Mail\Template\TransportBuilder|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $transportBuilder;
+
+    /**
+     * @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $storeManager;
+
+    /**
+     * @var \Magento\Customer\Model\Session|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $customerSession;
+
+    /**
+     * @var \Magento\Customer\Api\CustomerRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $customerRepository;
+
+    /**
+     * @var \Magento\Customer\Api\AccountManagementInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $customerAccountManagement;
+
+    /**
+     * @var \Magento\Framework\Translate\Inline\StateInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $inlineTranslation;
+
+    /**
+     * @var \Magento\Newsletter\Model\Resource\Subscriber|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $resource;
+
+    /**
+     * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager
+     */
+    protected $objectManager;
+
+    /**
+     * @var \Magento\Newsletter\Model\Subscriber
+     */
+    protected $subscriber;
+
+    public function setUp()
+    {
+        $this->newsletterData = $this->getMock('Magento\Newsletter\Helper\Data', [], [], '', false);
+        $this->scopeConfig = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface');
+        $this->transportBuilder = $this->getMock(
+            'Magento\Framework\Mail\Template\TransportBuilder',
+            [
+                'setTemplateIdentifier',
+                'setTemplateOptions',
+                'setTemplateVars',
+                'setFrom',
+                'addTo',
+                'getTransport'
+            ],
+            [],
+            '',
+            false
+        );
+        $this->storeManager = $this->getMock('Magento\Store\Model\StoreManagerInterface');
+        $this->customerSession = $this->getMock(
+            'Magento\Customer\Model\Session',
+            [
+                'isLoggedIn',
+                'getCustomerDataObject',
+                'getCustomerId'
+            ],
+            [],
+            '',
+            false
+        );
+        $this->customerRepository = $this->getMock('Magento\Customer\Api\CustomerRepositoryInterface');
+        $this->customerAccountManagement = $this->getMock('Magento\Customer\Api\AccountManagementInterface');
+        $this->inlineTranslation = $this->getMock('Magento\Framework\Translate\Inline\StateInterface');
+        $this->resource = $this->getMock(
+            'Magento\Newsletter\Model\Resource\Subscriber',
+            [
+                'loadByEmail',
+                'getIdFieldName',
+                'save'
+            ],
+            [],
+            '',
+            false
+        );
+        $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+
+        $this->subscriber = $this->objectManager->getObject(
+            'Magento\Newsletter\Model\Subscriber',
+            [
+                'newsletterData' => $this->newsletterData,
+                'scopeConfig' => $this->scopeConfig,
+                'transportBuilder' => $this->transportBuilder,
+                'storeManager' => $this->storeManager,
+                'customerSession' => $this->customerSession,
+                'customerRepository' => $this->customerRepository,
+                'customerAccountManagement' => $this->customerAccountManagement,
+                'inlineTranslation' => $this->inlineTranslation,
+                'resource' => $this->resource
+            ]
+        );
+    }
+
+    public function testSubscribe()
+    {
+        $email = 'subscriber_email@magento.com';
+        $this->resource->expects($this->any())->method('loadByEmail')->willReturn(
+            [
+                'subscriber_status' => 3,
+                'subscriber_email' => $email,
+                'name' => 'subscriber_name'
+            ]
+        );
+        $this->resource->expects($this->any())->method('getIdFieldName')->willReturn('id_field');
+        $this->scopeConfig->expects($this->any())->method('getValue')->willReturn(true);
+        $this->customerSession->expects($this->any())->method('isLoggedIn')->willReturn(true);
+        $customerDataModel = $this->getMock('\Magento\Customer\Api\Data\CustomerInterface');
+        $this->customerSession->expects($this->any())->method('getCustomerDataObject')->willReturn($customerDataModel);
+        $this->customerSession->expects($this->any())->method('getCustomerId')->willReturn(1);
+        $customerDataModel->expects($this->any())->method('getEmail')->willReturn($email);
+        $this->customerRepository->expects($this->any())->method('getById')->willReturn($customerDataModel);
+        $customerDataModel->expects($this->any())->method('getStoreId')->willReturn(1);
+        $customerDataModel->expects($this->any())->method('getId')->willReturn(1);
+        $this->transportBuilder->expects($this->any())->method('setTemplateIdentifier')->willReturnSelf();
+        $this->transportBuilder->expects($this->any())->method('setTemplateOptions')->willReturnSelf();
+        $this->transportBuilder->expects($this->any())->method('setTemplateVars')->willReturnSelf();
+        $this->transportBuilder->expects($this->any())->method('setFrom')->willReturnSelf();
+        $this->transportBuilder->expects($this->any())->method('addTo')->willReturnSelf();
+        $storeModel = $this->getMock('\Magento\Store\Model\Store', ['getId'], [], '', false);
+        $this->scopeConfig->expects($this->any())->method('getValue')->willReturn('owner_email@magento.com');
+        $this->storeManager->expects($this->any())->method('getStore')->willReturn($storeModel);
+        $storeModel->expects($this->any())->method('getId')->willReturn(1);
+        $transport = $this->getMock('\Magento\Framework\Mail\TransportInterface');
+        $this->transportBuilder->expects($this->any())->method('getTransport')->willReturn($transport);
+        $transport->expects($this->any())->method('sendMessage')->willReturnSelf();
+        $inlineTranslation = $this->getMock('Magento\Framework\Translate\Inline\StateInterface');
+        $inlineTranslation->expects($this->any())->method('resume')->willReturnSelf();
+        $this->resource->expects($this->atLeastOnce())->method('save')->willReturnSelf();
+        $this->assertEquals(1, $this->subscriber->subscribe($email));
+    }
+}
diff --git a/app/code/Magento/Newsletter/composer.json b/app/code/Magento/Newsletter/composer.json
index 2393d31c94a9e4d4840e0276b8d84bff76ea6237..27860c523bb2d47c78a20cf2e5efbb39ea2d53bc 100644
--- a/app/code/Magento/Newsletter/composer.json
+++ b/app/code/Magento/Newsletter/composer.json
@@ -3,20 +3,20 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-customer": "0.74.0-beta6",
-        "magento/module-widget": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-cms": "0.74.0-beta6",
-        "magento/module-email": "0.74.0-beta6",
-        "magento/module-cron": "0.74.0-beta6",
-        "magento/module-eav": "0.74.0-beta6",
-        "magento/module-require-js": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-customer": "0.74.0-beta7",
+        "magento/module-widget": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-cms": "0.74.0-beta7",
+        "magento/module-email": "0.74.0-beta7",
+        "magento/module-cron": "0.74.0-beta7",
+        "magento/module-eav": "0.74.0-beta7",
+        "magento/module-require-js": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Newsletter/view/adminhtml/layout/customer_form.xml b/app/code/Magento/Newsletter/view/adminhtml/layout/customer_index_edit.xml
similarity index 91%
rename from app/code/Magento/Newsletter/view/adminhtml/layout/customer_form.xml
rename to app/code/Magento/Newsletter/view/adminhtml/layout/customer_index_edit.xml
index 047806721e82afb9d33be6cddf5f72f1da39f182..9370c60513dc798de81b4d8a88a5b3c3b5678c1b 100644
--- a/app/code/Magento/Newsletter/view/adminhtml/layout/customer_form.xml
+++ b/app/code/Magento/Newsletter/view/adminhtml/layout/customer_index_edit.xml
@@ -7,7 +7,7 @@
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
     <body>
-        <referenceBlock name="form">
+        <referenceBlock name="customer_form">
             <block acl="Magento_Newsletter::subscriber" class="Magento\Customer\Block\Adminhtml\Edit\Tab\Newsletter" name="newsletter" />
         </referenceBlock>
     </body>
diff --git a/app/code/Magento/OfflinePayments/composer.json b/app/code/Magento/OfflinePayments/composer.json
index f47d2c7fd2030470d1926ef74a8e7376cf9a4b78..9ec612490167fd5b8f88d2260ab37b367cdf8d73 100644
--- a/app/code/Magento/OfflinePayments/composer.json
+++ b/app/code/Magento/OfflinePayments/composer.json
@@ -3,12 +3,12 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-payment": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-payment": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/OfflineShipping/composer.json b/app/code/Magento/OfflineShipping/composer.json
index b3ddea4da64c2a823e492e92649ee945bc126687..f78263edcb905f19c2530398ae58884d75166fd7 100644
--- a/app/code/Magento/OfflineShipping/composer.json
+++ b/app/code/Magento/OfflineShipping/composer.json
@@ -3,21 +3,21 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-config": "0.74.0-beta6",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-shipping": "0.74.0-beta6",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/module-sales": "0.74.0-beta6",
-        "magento/module-sales-rule": "0.74.0-beta6",
-        "magento/module-directory": "0.74.0-beta6",
-        "magento/module-checkout": "0.74.0-beta6",
-        "magento/module-quote": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-config": "0.74.0-beta7",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-shipping": "0.74.0-beta7",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/module-sales": "0.74.0-beta7",
+        "magento/module-sales-rule": "0.74.0-beta7",
+        "magento/module-directory": "0.74.0-beta7",
+        "magento/module-checkout": "0.74.0-beta7",
+        "magento/module-quote": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/PageCache/composer.json b/app/code/Magento/PageCache/composer.json
index b8ad947ba68430c71160dc994e099cc10c073d59..c5101231ec2c5549706f8f3a139191e9153df9c0 100644
--- a/app/code/Magento/PageCache/composer.json
+++ b/app/code/Magento/PageCache/composer.json
@@ -3,14 +3,14 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-config": "0.74.0-beta6",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-config": "0.74.0-beta7",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Payment/Block/Adminhtml/Transparent/Form.php b/app/code/Magento/Payment/Block/Adminhtml/Transparent/Form.php
new file mode 100644
index 0000000000000000000000000000000000000000..60717bda74798f92b9f1318da44139a16df86039
--- /dev/null
+++ b/app/code/Magento/Payment/Block/Adminhtml/Transparent/Form.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Payment\Block\Adminhtml\Transparent;
+
+class Form extends \Magento\Payment\Block\Transparent\Form
+{
+    /**
+     * On backend this block does not have any conditional checks
+     *
+     * @return bool
+     */
+    protected function shouldRender()
+    {
+        return true;
+    }
+
+    /**
+     * {inheritdoc}
+     */
+    protected function initializeMethod()
+    {
+        return;
+    }
+}
diff --git a/app/code/Magento/Payment/Block/Form.php b/app/code/Magento/Payment/Block/Form.php
index 762baad7f3741b485b73ac458eeed8a66434770d..f56d9ac3df0474b2d1f28bbbb16c35ea45510bc3 100644
--- a/app/code/Magento/Payment/Block/Form.php
+++ b/app/code/Magento/Payment/Block/Form.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\Payment\Block;
 
+use Magento\Payment\Model\MethodInterface;
+
 /**
  * Payment method form base block
  */
@@ -13,14 +15,14 @@ class Form extends \Magento\Framework\View\Element\Template
     /**
      * Retrieve payment method model
      *
-     * @return \Magento\Payment\Model\MethodInterface
+     * @return MethodInterface
      * @throws \Magento\Framework\Exception\LocalizedException
      */
     public function getMethod()
     {
         $method = $this->getData('method');
 
-        if (!$method instanceof \Magento\Payment\Model\MethodInterface) {
+        if (!$method instanceof MethodInterface) {
             throw new \Magento\Framework\Exception\LocalizedException(
                 __('We cannot retrieve the payment method model object.')
             );
@@ -28,6 +30,18 @@ class Form extends \Magento\Framework\View\Element\Template
         return $method;
     }
 
+    /**
+     * Sets payment method instance to form
+     *
+     * @param MethodInterface $method
+     * @return $this
+     */
+    public function setMethod(MethodInterface $method)
+    {
+        $this->setData('method', $method);
+        return $this;
+    }
+
     /**
      * Retrieve payment method code
      *
diff --git a/app/code/Magento/Payment/Block/Transparent/Form.php b/app/code/Magento/Payment/Block/Transparent/Form.php
new file mode 100644
index 0000000000000000000000000000000000000000..3237e6e21191af8c37ce16ff0085007d5b8d190a
--- /dev/null
+++ b/app/code/Magento/Payment/Block/Transparent/Form.php
@@ -0,0 +1,191 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Payment\Block\Transparent;
+
+use Magento\Framework\Exception\LocalizedException;
+use Magento\Payment\Model\Method\TransparentInterface;
+use Magento\Checkout\Model\Session;
+use Magento\Payment\Model\Config;
+use Magento\Framework\View\Element\Template\Context;
+
+/**
+ * Transparent form block
+ *
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Form extends \Magento\Payment\Block\Form\Cc
+{
+    /**
+     * @var Session
+     */
+    private $checkoutSession;
+
+    /**
+     * @var string
+     */
+    protected $_template = 'Magento_Payment::transparent/form.phtml';
+
+    /**
+     * @param Context $context
+     * @param Config $paymentConfig
+     * @param Session $checkoutSession
+     * @param array $data
+     */
+    public function __construct(
+        Context $context,
+        Config $paymentConfig,
+        Session $checkoutSession,
+        array $data = []
+    ) {
+        parent::__construct($context, $paymentConfig, $data);
+        $this->checkoutSession = $checkoutSession;
+    }
+
+    /**
+     * {inheritdoc}
+     */
+    protected function _toHtml()
+    {
+        if ($this->shouldRender()) {
+            return $this->processHtml();
+        }
+
+        return '';
+    }
+
+    /**
+     * Checks whether block should be rendered
+     * basing on TransparentInterface presence in checkout session
+     *
+     * @return bool
+     */
+    protected function shouldRender()
+    {
+        $quote = $this->checkoutSession->getQuote();
+        if ($quote) {
+            $payment = $quote->getPayment();
+            return $payment && $payment->getMethodInstance() instanceof TransparentInterface;
+        }
+
+        return false;
+    }
+
+    /**
+     * Initializes method
+     *
+     * @return void
+     */
+    protected function initializeMethod()
+    {
+        $this->setData(
+            'method',
+            $this->checkoutSession
+                ->getQuote()
+                ->getPayment()
+                ->getMethodInstance()
+        );
+    }
+
+    /**
+     * Parent rendering wrapper
+     *
+     * @return string
+     */
+    protected function processHtml()
+    {
+        $this->initializeMethod();
+        return parent::_toHtml();
+    }
+
+    /**
+     * Get type of request
+     *
+     * @return bool
+     */
+    public function isAjaxRequest()
+    {
+        return $this->getRequest()->getParam('isAjax');
+    }
+
+    /**
+     * Get delimiter for date
+     *
+     * @return string
+     */
+    public function getDateDelim()
+    {
+        return $this->getMethodConfigData('date_delim');
+    }
+
+    /**
+     * Get map of cc_code, cc_num, cc_expdate for gateway
+     * Returns json formatted string
+     *
+     * @return string
+     */
+    public function getCardFieldsMap()
+    {
+        $keys = ['cccvv', 'ccexpdate', 'ccnum'];
+        $ccfields = array_combine($keys, explode(',', $this->getMethodConfigData('ccfields')));
+        return json_encode($ccfields);
+    }
+
+    /**
+     * Retrieve place order url on front
+     *
+     * @return string
+     */
+    public function getOrderUrl()
+    {
+        return $this->_urlBuilder->getUrl(
+            $this->getMethodConfigData('place_order_url'),
+            [
+                '_secure' => $this->getRequest()->isSecure()
+            ]
+        );
+    }
+
+    /**
+     * Retrieve gateway url
+     *
+     * @return string
+     */
+    public function getCgiUrl()
+    {
+        return (bool)$this->getMethodConfigData('sandbox_flag')
+            ? $this->getMethodConfigData('cgi_url_test_mode')
+            : $this->getMethodConfigData('cgi_url');
+    }
+
+    /**
+     * Retrieve config data value by field name
+     *
+     * @param string $fieldName
+     * @return mixed
+     */
+    public function getMethodConfigData($fieldName)
+    {
+        return $this->getMethod()->getConfigInterface()->getConfigValue($fieldName);
+    }
+
+    /**
+     * Returns transparent method service
+     *
+     * @return TransparentInterface
+     * @throws LocalizedException
+     */
+    public function getMethod()
+    {
+        $method = parent::getMethod();
+
+        if (!$method instanceof TransparentInterface) {
+            throw new LocalizedException(
+                __('We cannot retrieve the transparent payment method model object.')
+            );
+        }
+        return $method;
+    }
+}
diff --git a/app/code/Magento/Payment/Block/Transparent/Iframe.php b/app/code/Magento/Payment/Block/Transparent/Iframe.php
new file mode 100644
index 0000000000000000000000000000000000000000..3070173f92b36c0bae20d66aadce8981b7c322af
--- /dev/null
+++ b/app/code/Magento/Payment/Block/Transparent/Iframe.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Payment\Block\Transparent;
+
+/**
+ * Iframe block for register specific params in layout
+ *
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Iframe extends \Magento\Framework\View\Element\Template
+{
+    /**
+     * Core registry
+     *
+     * @var \Magento\Framework\Registry
+     */
+    protected $coreRegistry;
+
+    /**
+     * Constructor
+     *
+     * @param \Magento\Framework\View\Element\Template\Context $context
+     * @param \Magento\Framework\Registry $registry
+     * @param array $data
+     */
+    public function __construct(
+        \Magento\Framework\View\Element\Template\Context $context,
+        \Magento\Framework\Registry $registry,
+        array $data = []
+    ) {
+        $this->coreRegistry = $registry;
+        parent::__construct($context, $data);
+    }
+
+    /**
+     * Preparing layout
+     *
+     * @return $this
+     */
+    protected function _prepareLayout()
+    {
+        if ($this->hasRegistryKey()) {
+            $params = $this->coreRegistry->registry($this->getRegistryKey());
+            $this->setParams($params);
+        }
+        return parent::_prepareLayout();
+    }
+}
diff --git a/app/code/Magento/Payment/Block/Transparent/Info.php b/app/code/Magento/Payment/Block/Transparent/Info.php
new file mode 100644
index 0000000000000000000000000000000000000000..af21b0e1758a59f2a7c3e9adb1b5905de346cd89
--- /dev/null
+++ b/app/code/Magento/Payment/Block/Transparent/Info.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Payment\Block\Transparent;
+
+/**
+ * Class Info. Payment Information block used for transparent redirect feature
+ * @package Magento\Payment\Block\Transparent
+ */
+class Info extends \Magento\Framework\View\Element\Template
+{
+    /**
+     * @var string
+     */
+    protected $_template = 'Magento_Payment::transparent/info.phtml';
+}
diff --git a/app/code/Magento/Payment/Model/Method/AbstractMethod.php b/app/code/Magento/Payment/Model/Method/AbstractMethod.php
index e316982a1be7081f470bc8cb2493d19ea0debfea..5a3a5a8b46262889fcd8a574a8b2fffb2a26f61c 100644
--- a/app/code/Magento/Payment/Model/Method/AbstractMethod.php
+++ b/app/code/Magento/Payment/Model/Method/AbstractMethod.php
@@ -254,6 +254,20 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
         $this->_scopeConfig = $scopeConfig;
         $this->_eventManager = $context->getEventDispatcher();
         $this->logger = $context->getLogger();
+        $this->initializeData($data);
+    }
+
+    /**
+     * Initializes injected data
+     *
+     * @param array $data
+     * @return void
+     */
+    protected function initializeData($data = [])
+    {
+        if (!empty($data['formBlockType'])) {
+            $this->_formBlockType = $data['formBlockType'];
+        }
     }
 
     /**
diff --git a/app/code/Magento/Payment/Model/Method/ConfigInterface.php b/app/code/Magento/Payment/Model/Method/ConfigInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..600f4fdb53a8c0eada317308eeda14a9a26907ee
--- /dev/null
+++ b/app/code/Magento/Payment/Model/Method/ConfigInterface.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Payment\Model\Method;
+
+/**
+ * Interface for payment methods config
+ *
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+interface ConfigInterface
+{
+    /**
+     * Config field getter
+     * The specified key can be either in camelCase or under_score format
+     *
+     * @param string $key
+     * @return mixed
+     */
+    public function getConfigValue($key);
+}
diff --git a/app/code/Magento/Payment/Model/Method/Logger.php b/app/code/Magento/Payment/Model/Method/Logger.php
new file mode 100644
index 0000000000000000000000000000000000000000..9c9e54e5e23636527f64eaff58997e6bb0de70c7
--- /dev/null
+++ b/app/code/Magento/Payment/Model/Method/Logger.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Payment\Model\Method;
+
+use Psr\Log\LoggerInterface;
+
+/**
+ * Class Logger for payment related information (request, response, etc.) which is used for debug
+ *
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Logger
+{
+    /**
+     * @var LoggerInterface
+     */
+    protected $logger;
+
+    /**
+     * @param LoggerInterface $logger
+     */
+    public function __construct(LoggerInterface $logger)
+    {
+        $this->logger = $logger;
+    }
+
+    /**
+     * Logs payment related information used for debug
+     *
+     * @param mixed $logData
+     * @param ConfigInterface $config
+     *
+     * @return void
+     */
+    public function debug($logData, ConfigInterface $config)
+    {
+        if ($config->getConfigValue('debug')) {
+            $this->logger->debug(var_export($logData, true));
+        }
+    }
+}
diff --git a/app/code/Magento/Payment/Model/Method/Online/GatewayInterface.php b/app/code/Magento/Payment/Model/Method/Online/GatewayInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..4a99a7e8308758e368ad364463673f4828e2ca0e
--- /dev/null
+++ b/app/code/Magento/Payment/Model/Method/Online/GatewayInterface.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Payment\Model\Method\Online;
+
+use Magento\Framework\Object;
+use Magento\Payment\Model\Method\ConfigInterface;
+
+/**
+ * Gateway interface for online payment methods
+ *
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+interface GatewayInterface
+{
+    /**
+     * Post request to gateway and return response
+     *
+     * @param Object $request
+     * @param ConfigInterface $config
+     *
+     * @return Object
+     *
+     * @throws \Exception
+     */
+    public function postRequest(Object $request, ConfigInterface $config);
+}
diff --git a/app/code/Magento/Payment/Model/Method/TransparentInterface.php b/app/code/Magento/Payment/Model/Method/TransparentInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..eebb8594cc2ea9a0259edd508aef77bd6fa1c9b2
--- /dev/null
+++ b/app/code/Magento/Payment/Model/Method/TransparentInterface.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Payment\Model\Method;
+
+use Magento\Payment\Model\MethodInterface;
+
+/**
+ * Interface TransparentInterface need to be implemented by Payment Method service
+ * which supports transparent redirect feature
+ * @package Magento\Payment\Model\Method
+ */
+interface TransparentInterface extends MethodInterface
+{
+    /**
+     * Returns payment method configured config
+     *
+     * @return ConfigInterface
+     */
+    public function getConfigInterface();
+}
diff --git a/app/code/Magento/Payment/Test/Unit/Block/Adminhtml/Transparent/FormTest.php b/app/code/Magento/Payment/Test/Unit/Block/Adminhtml/Transparent/FormTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..3281e616a649bd16ce9293069d052a965e380c5d
--- /dev/null
+++ b/app/code/Magento/Payment/Test/Unit/Block/Adminhtml/Transparent/FormTest.php
@@ -0,0 +1,86 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Payment\Test\Unit\Block\Adminhtml\Transparent;
+
+use Magento\Framework\App\RequestInterface;
+use Magento\Framework\Object;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+use Magento\Framework\UrlInterface;
+use Magento\Payment\Model\Method\TransparentInterface;
+
+class FormTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var FormTesting | \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $form;
+
+    /**
+     * @var TransparentInterface | \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $methodMock;
+
+    /**
+     * @var \Magento\Checkout\Model\Session | \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $checkoutSessionMock;
+
+    protected function setUp()
+    {
+        $objectManagerHelper = new ObjectManager($this);
+
+        $this->requestMock = $this->getMockBuilder('\Magento\Framework\App\RequestInterface')
+            ->setMethods(['getParam'])
+            ->getMockForAbstractClass();
+
+        $this->urlBuilderMock = $this->getMockBuilder('\Magento\Framework\UrlInterface')
+            ->setMethods(['getUrl'])
+            ->getMockForAbstractClass();
+
+        $context = $objectManagerHelper->getObject('Magento\Framework\View\Element\Template\Context');
+
+        $this->methodMock = $this->getMockBuilder('Magento\Payment\Model\Method\TransparentInterface')
+            ->getMock();
+
+        $this->checkoutSessionMock = $this->getMockBuilder('Magento\Checkout\Model\Session')
+            ->setMethods([])
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $paymentConfigMock = $this->getMockBuilder('Magento\Payment\Model\Config')
+            ->setMethods([])
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->form = new FormTesting(
+            $context,
+            $paymentConfigMock,
+            $this->checkoutSessionMock
+        );
+    }
+
+    public function testToHtmlShouldRender()
+    {
+        $quoteMock = $this->getMockBuilder('Magento\Quote\Model\Quote')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $paymentMock = $this->getMockBuilder('Magento\Quote\Model\Quote\Payment')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->checkoutSessionMock->expects($this->never())
+            ->method('getQuote')
+            ->willReturn($quoteMock);
+        $quoteMock->expects($this->never())
+            ->method('getPayment')
+            ->willReturn($paymentMock);
+        $paymentMock->expects($this->never())
+            ->method('getMethodInstance')
+            ->willReturn($this->methodMock);
+
+        $this->form->toHtml();
+    }
+}
diff --git a/app/code/Magento/Payment/Test/Unit/Block/Adminhtml/Transparent/FormTesting.php b/app/code/Magento/Payment/Test/Unit/Block/Adminhtml/Transparent/FormTesting.php
new file mode 100644
index 0000000000000000000000000000000000000000..e48bf8f6a57e7cea7576db24e565c4b1e2a2b0bf
--- /dev/null
+++ b/app/code/Magento/Payment/Test/Unit/Block/Adminhtml/Transparent/FormTesting.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Payment\Test\Unit\Block\Adminhtml\Transparent;
+
+use Magento\Payment\Block\Adminhtml\Transparent\Form;
+
+/**
+ * Class FormTesting extended test class, used to substitute calls to parent methods
+ * @package Magento\Payment\Test\Unit\Block\Adminhtml\Transparent
+ */
+class FormTesting extends Form
+{
+    /**
+     * Return values for processHtml() method
+     */
+    const PROCESS_HTML_RESULT = 'parent_result';
+
+    /**
+     * {inheritdoc}
+     */
+    protected function processHtml()
+    {
+        return self::PROCESS_HTML_RESULT;
+    }
+}
diff --git a/app/code/Magento/Payment/Test/Unit/Block/FormTest.php b/app/code/Magento/Payment/Test/Unit/Block/FormTest.php
index 2db84edbdfd599c017242715d510240ce944a5f7..9f01df530fa1520c38e79312f2f309de3b4df336 100644
--- a/app/code/Magento/Payment/Test/Unit/Block/FormTest.php
+++ b/app/code/Magento/Payment/Test/Unit/Block/FormTest.php
@@ -119,4 +119,12 @@ class FormTest extends \PHPUnit_Framework_TestCase
             ]
         ];
     }
+
+    public function testSetMethod()
+    {
+        $methodInterfaceMock = $this->getMockBuilder('\Magento\Payment\Model\MethodInterface')
+            ->getMockForAbstractClass();
+
+        $this->assertSame($this->_object, $this->_object->setMethod($methodInterfaceMock));
+    }
 }
diff --git a/app/code/Magento/Payment/Test/Unit/Block/Transparent/FormTest.php b/app/code/Magento/Payment/Test/Unit/Block/Transparent/FormTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..b361cc1881eec8ae1c463dbf7b2ead8d1ce39a19
--- /dev/null
+++ b/app/code/Magento/Payment/Test/Unit/Block/Transparent/FormTest.php
@@ -0,0 +1,301 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Payment\Test\Unit\Block\Transparent;
+
+use Magento\Checkout\Model\Session;
+use Magento\Framework\App\RequestInterface;
+use Magento\Framework\Object;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+use Magento\Framework\UrlInterface;
+use Magento\Payment\Model\Method\TransparentInterface;
+
+class FormTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var FormTesting | \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $form;
+
+    /**
+     * @var RequestInterface | \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $requestMock;
+
+    /**
+     * @var UrlInterface | \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $urlBuilderMock;
+
+    /**
+     * @var TransparentInterface | \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $methodMock;
+
+    /**
+     * @var Session | \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $checkoutSessionMock;
+
+    protected function setUp()
+    {
+        $objectManagerHelper = new ObjectManager($this);
+
+        $this->requestMock = $this->getMockBuilder('\Magento\Framework\App\RequestInterface')
+            ->setMethods(['getParam'])
+            ->getMockForAbstractClass();
+
+        $this->urlBuilderMock = $this->getMockBuilder('\Magento\Framework\UrlInterface')
+            ->setMethods(['getUrl'])
+            ->getMockForAbstractClass();
+
+        $context = $objectManagerHelper->getObject(
+            'Magento\Framework\View\Element\Template\Context',
+            [
+                'request' => $this->requestMock,
+                'urlBuilder' => $this->urlBuilderMock
+            ]
+        );
+
+        $this->methodMock = $this->getMockBuilder('Magento\Payment\Model\Method\TransparentInterface')
+            ->getMock();
+
+        $this->checkoutSessionMock = $this->getMockBuilder('Magento\Checkout\Model\Session')
+            ->setMethods([])
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $paymentConfigMock = $this->getMockBuilder('Magento\Payment\Model\Config')
+            ->setMethods([])
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->form = new FormTesting(
+            $context,
+            $paymentConfigMock,
+            $this->checkoutSessionMock
+        );
+    }
+
+    public function testIsAjaxRequest()
+    {
+        $this->requestMock->expects($this->exactly(2))
+            ->method('getParam')
+            ->with('isAjax')
+            ->willReturnOnConsecutiveCalls(true, false);
+
+        $this->assertTrue($this->form->isAjaxRequest());
+        $this->assertFalse($this->form->isAjaxRequest());
+    }
+
+    /**
+     * @param string $fieldName
+     * @param mixed $fieldValue
+     * @param mixed $expected
+     *
+     * @dataProvider getMethodConfigDataDataProvider
+     */
+    public function testGetMethodConfigData($fieldName, $fieldValue, $expected)
+    {
+        $this->initializeMethodWithConfigMock([[$fieldName, $fieldValue]]);
+
+        $this->form->setMethod($this->methodMock);
+
+        $this->assertEquals($expected, $this->form->getMethodConfigData($fieldName));
+    }
+
+    /**
+     * Initializes method mock with config mock
+     *
+     * @param array $configMap
+     */
+    private function initializeMethodWithConfigMock(array $configMap = [])
+    {
+        $configInterface = $this->getMockBuilder('Magento\Payment\Model\Method\ConfigInterface')
+            ->getMock();
+
+        $configInterface->expects($this->any())
+            ->method('getConfigValue')
+            ->willReturnMap($configMap);
+
+        $this->methodMock->expects($this->any())
+            ->method('getConfigInterface')
+            ->willReturn($configInterface);
+    }
+
+    /**
+     * Data provider for testGetMethodConfigData
+     *
+     * @see testGetMethodConfigData
+     *
+     * @case #1 Set string value
+     * @case #2 Set boolean value
+     *
+     * @return array
+     */
+    public function getMethodConfigDataDataProvider()
+    {
+        return [
+            ['gateway_name', 'payment_gateway', 'payment_gateway'],
+            ['sandbox_flag', true, true],
+        ];
+    }
+
+    /**
+     * @dataProvider getCgiUrlDataProvider
+     *
+     * @param $sandboxFlag
+     * @param $cgiUrlTestMode
+     * @param $cgiUrl
+     * @param $expectedUrl
+     */
+    public function testGetCgiUrl($sandboxFlag, $cgiUrlTestMode, $cgiUrl, $expectedUrl)
+    {
+        $this->initializeMethodWithConfigMock(
+            [
+                ['sandbox_flag', $sandboxFlag],
+                ['cgi_url_test_mode', $cgiUrlTestMode],
+                ['cgi_url', $cgiUrl]
+            ]
+        );
+
+        $this->form->setMethod($this->methodMock);
+
+        $this->assertEquals($expectedUrl, $this->form->getCgiUrl());
+    }
+
+    /**
+     * Data provider for testGetCgiUrl
+     *
+     * @see testGetCgiUrl
+     *
+     * @case #1 The sandboxFlag is 1 we expected cgi_url_test_mode_value
+     * @case #2 The sandboxFlag is 0 we expected cgi_url_value
+     *
+     * @return array
+     */
+    public function getCgiUrlDataProvider()
+    {
+        return [
+            [
+                1,
+                'cgi_url_test_mode_value',
+                'cgi_url_value',
+                'cgi_url_test_mode_value'
+            ],
+            [
+                0,
+                'cgi_url_test_mode_value',
+                'cgi_url_value',
+                'cgi_url_value'
+            ],
+        ];
+    }
+
+    public function testGetOrderUrl()
+    {
+        $orderUrlPattern = 'order_url';
+        $builtOrderUrl = 'built_url';
+        $this->initializeMethodWithConfigMock([['place_order_url', $orderUrlPattern]]);
+
+        $this->urlBuilderMock->expects($this->once())
+            ->method('getUrl')
+            ->with($orderUrlPattern)
+            ->willReturn($builtOrderUrl);
+
+        $this->form->setMethod($this->methodMock);
+
+        $this->assertEquals($builtOrderUrl, $this->form->getOrderUrl());
+    }
+
+    public function testGetDateDelim()
+    {
+        $dateDelimiter = '/';
+        $this->initializeMethodWithConfigMock([['date_delim', $dateDelimiter]]);
+
+        $this->form->setMethod($this->methodMock);
+
+        $this->assertEquals($dateDelimiter, $this->form->getDateDelim());
+    }
+
+    public function testGetCardFieldsMap()
+    {
+        $ccfields = 'x_card_code,x_exp_date,x_card_num';
+        $this->initializeMethodWithConfigMock([['ccfields', $ccfields]]);
+
+        $this->form->setMethod($this->methodMock);
+
+        $expected = json_encode(['cccvv' => 'x_card_code', 'ccexpdate' => 'x_exp_date', 'ccnum' => 'x_card_num']);
+
+        $this->assertEquals($expected, $this->form->getCardFieldsMap());
+    }
+
+    public function testToHtmlShouldRender()
+    {
+        $quoteMock = $this->getMockBuilder('Magento\Quote\Model\Quote')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $paymentMock = $this->getMockBuilder('Magento\Quote\Model\Quote\Payment')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->checkoutSessionMock->expects($this->once())
+            ->method('getQuote')
+            ->willReturn($quoteMock);
+        $quoteMock->expects($this->once())
+            ->method('getPayment')
+            ->willReturn($paymentMock);
+        $paymentMock->expects($this->once())
+            ->method('getMethodInstance')
+            ->willReturn($this->methodMock);
+
+        $this->form->toHtml();
+    }
+
+    public function testToHtmlShouldNotRenderEmptyQuote()
+    {
+        $this->checkoutSessionMock->expects($this->once())
+            ->method('getQuote')
+            ->willReturn(null);
+
+        $this->assertEmpty($this->form->toHtml());
+    }
+
+    public function testToHtmlShouldNotRenderEmptyPayment()
+    {
+        $quoteMock = $this->getMockBuilder('Magento\Quote\Model\Quote')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->checkoutSessionMock->expects($this->once())
+            ->method('getQuote')
+            ->willReturn($quoteMock);
+        $quoteMock->expects($this->once())
+            ->method('getPayment')
+            ->willReturn(null);
+
+        $this->assertEmpty($this->form->toHtml());
+    }
+
+    public function testGetMethodSuccess()
+    {
+        $this->form->setMethod($this->methodMock);
+        $this->assertSame($this->methodMock, $this->form->getMethod());
+    }
+
+    public function testGetMethodNotTransparentInterface()
+    {
+        $this->setExpectedException(
+            'Magento\Framework\Exception\LocalizedException',
+            __('We cannot retrieve the transparent payment method model object.')
+        );
+
+        $methodMock = $this->getMockBuilder('Magento\Payment\Model\MethodInterface')
+            ->getMockForAbstractClass();
+
+        $this->form->setMethod($methodMock);
+        $this->form->getMethod();
+    }
+}
diff --git a/app/code/Magento/Payment/Test/Unit/Block/Transparent/FormTesting.php b/app/code/Magento/Payment/Test/Unit/Block/Transparent/FormTesting.php
new file mode 100644
index 0000000000000000000000000000000000000000..cdeb6a8b5fc76d2fe77e824c3b1b9b56f6582274
--- /dev/null
+++ b/app/code/Magento/Payment/Test/Unit/Block/Transparent/FormTesting.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Payment\Test\Unit\Block\Transparent;
+
+use Magento\Payment\Block\Transparent\Form;
+
+/**
+ * Class FormTesting extended test class, used to substitute calls to parent methods
+ * @package Magento\Payment\Test\Unit\Block\Transparent
+ */
+class FormTesting extends Form
+{
+    /**
+     * Return values for processHtml() method
+     */
+    const PROCESS_HTML_RESULT = 'parent_result';
+
+    /**
+     * {inheritdoc}
+     */
+    protected function processHtml()
+    {
+        return self::PROCESS_HTML_RESULT;
+    }
+}
diff --git a/app/code/Magento/Payment/Test/Unit/Model/Method/LoggerTest.php b/app/code/Magento/Payment/Test/Unit/Model/Method/LoggerTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..75efef237b33a53a318e56ca50920d21f644418f
--- /dev/null
+++ b/app/code/Magento/Payment/Test/Unit/Model/Method/LoggerTest.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Payment\Test\Unit\Model\Method;
+
+use Magento\Payment\Model\Method\ConfigInterface;
+use Magento\Payment\Model\Method\Logger;
+use Psr\Log\LoggerInterface;
+
+class LoggerTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var Logger | \PHPUnit_Framework_MockObject_MockObject */
+    private $logger;
+
+    /** @var LoggerInterface | \PHPUnit_Framework_MockObject_MockObject */
+    private $loggerMock;
+
+    /** @var ConfigInterface | \PHPUnit_Framework_MockObject_MockObject */
+    private $configMock;
+
+    protected function setUp()
+    {
+        $this->loggerMock = $this->getMockForAbstractClass('Psr\Log\LoggerInterface');
+        $this->configMock = $this->getMockForAbstractClass('Magento\Payment\Model\Method\ConfigInterface');
+
+        $this->logger = new Logger($this->loggerMock);
+    }
+
+    public function testDebugOn()
+    {
+        $this->configMock->expects($this->once())
+            ->method('getConfigValue')
+            ->with('debug')
+            ->willReturn(true);
+        $this->loggerMock->expects($this->once())
+            ->method('debug')
+            ->with("'test_value'");
+
+        $this->logger->debug('test_value', $this->configMock);
+    }
+
+    public function testDebugOff()
+    {
+        $this->configMock->expects($this->once())
+            ->method('getConfigValue')
+            ->with('debug')
+            ->willReturn(false);
+        $this->loggerMock->expects($this->never())
+            ->method('debug');
+
+        $this->logger->debug('', $this->configMock);
+    }
+}
diff --git a/app/code/Magento/Payment/composer.json b/app/code/Magento/Payment/composer.json
index b4e88d864a2b2c0868d6bd2cb685f0b81bcb0d4d..f765253fd15845aba891a6d80232c3d0599a3b6d 100644
--- a/app/code/Magento/Payment/composer.json
+++ b/app/code/Magento/Payment/composer.json
@@ -3,17 +3,17 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-config": "0.74.0-beta6",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-sales": "0.74.0-beta6",
-        "magento/module-centinel": "0.74.0-beta6",
-        "magento/module-checkout": "0.74.0-beta6",
-        "magento/module-quote": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-config": "0.74.0-beta7",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-sales": "0.74.0-beta7",
+        "magento/module-centinel": "0.74.0-beta7",
+        "magento/module-checkout": "0.74.0-beta7",
+        "magento/module-quote": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Payment/view/adminhtml/templates/transparent/form.phtml b/app/code/Magento/Payment/view/adminhtml/templates/transparent/form.phtml
new file mode 100644
index 0000000000000000000000000000000000000000..e9632aa0f89155238a8a659b660687a2bc4ce743
--- /dev/null
+++ b/app/code/Magento/Payment/view/adminhtml/templates/transparent/form.phtml
@@ -0,0 +1,94 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+?>
+<?php
+// @codingStandardsIgnoreFile
+
+/** @var \Magento\Payment\Block\Transparent\Form $block*/
+$code = $block->getMethodCode();
+?>
+
+<!-- IFRAME for request to Payment Gateway -->
+<iframe id="<?php echo $code ?>-transparent-iframe" data-container="<?php echo $code ?>-transparent-iframe" allowtransparency="true" frameborder="0"  name="iframeTransparent" style="display:none;width:100%;background-color:transparent" src="<?php echo $block->getViewFileUrl('blank.html') ?>"></iframe>
+<div id="payment_form_<?php echo $code ?>"
+     data-mage-init='{
+     "transparent":{
+        "controller":"<?php echo $block->getRequest()->getControllerName() ?>",
+        "gateway":"<?php echo $block->getMethodCode() ?>",
+        "dateDelim":"<?php echo $block->getDateDelim() ?>",
+        "cardFieldsMap":<?php echo $block->getCardFieldsMap() ?>,
+        "orderSaveUrl":"<?php echo $block->getOrderUrl() ?>",
+        "cgiUrl":"<?php echo $block->getCgiUrl() ?>",
+        "nativeAction":"<?php echo $block->getUrl('*/*/save', ['_secure' => $block->getRequest()->isSecure()]) ?>"
+      }, "validation":[]}'
+     style="display:none;">
+
+        <div class="field required type">
+            <label for="<?php echo $code ?>_cc_type" class="label"><span><?php echo __('Credit Card Type') ?></span></label>
+            <div class="control">
+                <select id="<?php echo $code ?>_cc_type" data-container="<?php echo $code ?>-cc-type" name="payment[cc_type]" data-validate='{required:true, "validate-cc-type-select":"#<?php echo $code ?>_cc_number"}'>
+                    <option value=""><?php echo __('--Please Select--')?></option>
+                    <?php $_ccType = $block->getInfoData('cc_type') ?>
+                    <?php foreach ($block->getCcAvailableTypes() as $_typeCode => $_typeName): ?>
+                        <option value="<?php echo $_typeCode ?>"<?php if ($_typeCode == $_ccType): ?> selected="selected"<?php endif ?>><?php echo $_typeName ?></option>
+                    <?php endforeach ?>
+                </select>
+            </div>
+        </div>
+
+        <div class="field required number">
+            <label for="<?php echo $code ?>_cc_number" class="label"><span><?php echo __('Credit Card Number') ?></span></label>
+            <div class="control">
+                <input type="number" id="<?php echo $code ?>_cc_number" data-container="<?php echo $code ?>-cc-number" name="payment[cc_number]" title="<?php echo __('Credit Card Number') ?>" class="input-text" value="" data-validate='{"required-number":true, "validate-cc-number":"#<?php echo $code ?>_cc_type", "validate-cc-type":"#<?php echo $code ?>_cc_type"}' autocomplete="off"/>
+            </div>
+        </div>
+
+        <div class="field required date" id="<?php echo $code ?>_cc_type_exp_div">
+            <label for="<?php echo $code ?>_expiration" class="label"><span><?php echo __('Expiration Date') ?></span></label>
+            <div class="control">
+                <div class="fields group group-2">
+                    <div class="field no-label month">
+                        <div class="control">
+                            <select id="<?php echo $code ?>_expiration" name="payment[cc_exp_month]" data-container="<?php echo $code ?>-cc-month" class="month" data-validate='{required:true, "validate-cc-exp":"#<?php echo $code ?>_expiration_yr"}'>
+                                <?php $_ccExpMonth = $block->getInfoData('cc_exp_month') ?>
+                                <?php foreach ($block->getCcMonths() as $k => $v): ?>
+                                    <option value="<?php echo $k ? $k : '' ?>"<?php if ($k == $_ccExpMonth): ?> selected="selected"<?php endif ?>><?php echo $v ?></option>
+                                <?php endforeach ?>
+                            </select>
+                        </div>
+                    </div>
+                    <div class="field no-label year">
+                        <div class="control">
+                            <?php $_ccExpYear = $block->getInfoData('cc_exp_year') ?>
+                            <select id="<?php echo $code ?>_expiration_yr" name="payment[cc_exp_year]" class="year" data-container="<?php echo $code ?>-cc-year" data-validate='{required:true}'>
+                                <?php foreach ($block->getCcYears() as $k => $v): ?>
+                                    <option value="<?php echo $k ? $k : '' ?>"<?php if ($k == $_ccExpYear): ?> selected="selected"<?php endif ?>><?php echo $v ?></option>
+                                <?php endforeach ?>
+                            </select>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <?php if ($block->hasVerification()): ?>
+            <div class="field required cvv" id="<?php echo $code ?>_cc_type_cvv_div">
+                <label for="<?php echo $code ?>_cc_cid" class="label"><span><?php echo __('Card Verification Number') ?></span></label>
+                <div class="control">
+                    <input type="number" title="<?php echo __('Card Verification Number') ?>" data-container="<?php echo $code ?>-cc-cvv" class="input-text cvv" id="<?php echo $code ?>_cc_cid" name="payment[cc_cid]" value="" data-validate='{"required-number":true, "validate-cc-cvn":"#<?php echo $code ?>_cc_type"}' autocomplete="off"/>
+                </div>
+            </div>
+        <?php endif; ?>
+        <?php echo $block->getChildHtml() ?>
+</div>
+
+<script>
+    /**
+     * Disable card server validation in admin
+     */
+    require(["Magento_Sales/order/create/form"], function(){
+        order.addExcludedPaymentMethod('<?php echo $code ?>');
+    });
+</script>
diff --git a/app/code/Magento/Payment/view/adminhtml/templates/transparent/iframe.phtml b/app/code/Magento/Payment/view/adminhtml/templates/transparent/iframe.phtml
new file mode 100644
index 0000000000000000000000000000000000000000..943767e9b80556510bc3d2aa637da38fa9a5ea44
--- /dev/null
+++ b/app/code/Magento/Payment/view/adminhtml/templates/transparent/iframe.phtml
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+// @codingStandardsIgnoreFile
+
+$params = $block->getParams();
+
+?>
+<html>
+<head>
+<script>
+<?php if (isset($params['redirect'])): ?>
+    window.location="<?php echo $block->escapeUrl($params['redirect']) ?>";
+<?php elseif (isset($params['redirect_parent'])): ?>
+    window.top.location="<?php echo $block->escapeUrl($params['redirect_parent']) ?>";
+<?php elseif (isset($params['error_msg'])): ?>
+    window.top.alert(<?php echo $block->helper('Magento\Framework\Json\Helper\Data')->jsonEncode($params['error_msg']) ?>);
+<?php elseif (isset($params['order_success'])): ?>
+    window.top.location = "<?php echo $params['order_success'] ?>";
+<?php else: ?>
+    var require = window.top.require;
+    require(['jquery'], function($) {
+        $('#edit_form').trigger('processStop');
+
+        $("input[name='payment[cc_number]']").prop('disabled', true);
+        $("select[name='payment[cc_type]']").prop('disabled', true);
+        $("select[name='payment[cc_exp_month]']").prop('disabled', true);
+        $("select[name='payment[cc_exp_year]']").prop('disabled', true);
+        $("input[name='payment[cc_cid]']").prop('disabled', true);
+
+        $('#edit_form').trigger('realOrder');
+    });
+<?php endif; ?>
+</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/app/code/Magento/Payment/view/adminhtml/templates/transparent/info.phtml b/app/code/Magento/Payment/view/adminhtml/templates/transparent/info.phtml
new file mode 100644
index 0000000000000000000000000000000000000000..badfd92d13a478cb0c409eccb4f9f3af9210e150
--- /dev/null
+++ b/app/code/Magento/Payment/view/adminhtml/templates/transparent/info.phtml
@@ -0,0 +1,13 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+/**
+ * @see \Magento\Payment\Block\Transparent\Info
+ */
+?>
+<fieldset id="payment_form_<?php echo $block->getMethodCode() ?>" style="display:none" class="fieldset items redirect">
+    <div><?php echo __('You\'ll be asked for your payment details before placing an order.') ?></div>
+</fieldset>
diff --git a/app/code/Magento/Payment/view/adminhtml/web/transparent.js b/app/code/Magento/Payment/view/adminhtml/web/transparent.js
new file mode 100644
index 0000000000000000000000000000000000000000..1317880d7f062c08ebe1c1fee96be951796b1a53
--- /dev/null
+++ b/app/code/Magento/Payment/view/adminhtml/web/transparent.js
@@ -0,0 +1,165 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+define([
+    "jquery",
+    "mage/template",
+    "jquery/ui"
+], function($, mageTemplate){
+    "use strict";
+
+    $.widget('mage.transparent', {
+        options: {
+            hiddenFormTmpl:
+                '<form target="<%= data.target %>" action="<%= data.action %>" method="POST" hidden enctype="application/x-www-form-urlencoded" class="no-display">' +
+                    '<% _.each(data.inputs, function(val, key){ %>' +
+                    '<input value="<%= val %>" name="<%= key %>" type="hidden">' +
+                    '<% }); %>' +
+                '</form>',
+            cgiUrl: null,
+            orderSaveUrl: null,
+            controller: null,
+            gateway: null,
+            dateDelim: null,
+            cardFieldsMap: null
+        },
+
+        _create: function() {
+            var prepare = function (event, method) {
+                if (method === this.options.gateway) {
+                    $('#edit_form')
+                        .off('submitOrder')
+                        .on('submitOrder', this._orderSave.bind(this))
+                }
+            };
+            this.hiddenFormTmpl = mageTemplate(this.options.hiddenFormTmpl);
+            jQuery('#edit_form').on('changePaymentMethod', prepare.bind(this));
+
+            jQuery('#edit_form').trigger(
+                'changePaymentMethod',
+                [
+                    jQuery('#edit_form').find(':radio[name="payment[method]"]:checked').val()
+                ]
+            );
+        },
+
+        /**
+         * handler for Place Order button to call gateway for credit card validation
+         * Save order and generate post data for gateway call
+         * @private
+         */
+        _orderSave: function() {
+            var postData = "form_key="+FORM_KEY;
+            $.ajax({
+                url: this.options.orderSaveUrl,
+                type: 'post',
+                context: this,
+                data: postData,
+                dataType: 'json',
+                success: function(response) {
+                    if (response.success && response[this.options.gateway]) {
+                        this._postPaymentToGateway(response);
+                    } else {
+                        this._processErrors(response);
+                    }
+                }
+            });
+        },
+
+        /**
+         * Post data to gateway for credit card validation
+         * @param response
+         * @private
+         */
+        _postPaymentToGateway: function(response) {
+            var data,
+                tmpl,
+                iframe;
+
+            data = this._preparePaymentData(response);
+            var iframeSelector = '[data-container="' + this.options.gateway + '-transparent-iframe"]';
+
+            tmpl = this.hiddenFormTmpl({
+                data: {
+                    target: $(iframeSelector).attr('name'),
+                    action: this.options.cgiUrl,
+                    inputs: data
+                }
+            });
+
+            iframe = $(iframeSelector)
+                .on('submit', function(event){
+                    event.stopPropagation();
+                });
+            $(tmpl).appendTo(iframe).submit();
+            iframe.html('');
+        },
+
+        /**
+         * Add credit card fields to post data for gateway
+         *
+         * @param response
+         * @private
+         */
+        _preparePaymentData: function(response) {
+            var ccfields,
+                data,
+                preparedata;
+
+            data = response[this.options.gateway].fields;
+            ccfields = this.options.cardFieldsMap;
+
+            if (this.element.find('[data-container="' + this.options.gateway + '-cc-cvv"]').length) {
+                data[ccfields.cccvv] = this.element.find(
+                    '[data-container="' + this.options.gateway + '-cc-cvv"]'
+                ).val();
+            }
+            preparedata = this._prepareExpDate();
+            data[ccfields.ccexpdate] = preparedata.month + this.options.dateDelim + preparedata.year;
+            data[ccfields.ccnum] = this.element.find(
+                '[data-container="' + this.options.gateway + '-cc-number"]'
+            ).val();
+            return data;
+        },
+
+        /**
+         * Grab Month and Year into one
+         * @returns {object}
+         * @private
+         */
+        _prepareExpDate: function() {
+            var year = this.element.find('[data-container="' + this.options.gateway + '-cc-year"]').val(),
+                month = parseInt(
+                    this.element.find('[data-container="' + this.options.gateway + '-cc-month"]').val()
+                    , 10
+                );
+            if (year.length > 2) {
+                year = year.substring(2);
+            }
+            if (month < 10) {
+                month = '0' + month;
+            }
+            return {month: month, year: year};
+        },
+
+        /**
+         * Processing errors
+         *
+         * @param response
+         * @private
+         */
+        _processErrors: function (response) {
+            var msg = response.error_messages;
+            if (typeof (msg) === 'object') {
+                alert(msg.join("\n"));
+            }
+            if (msg) {
+                alert(msg);
+            }
+        }
+    });
+
+    return $.mage.transparent;
+});
diff --git a/app/code/Magento/Ui/view/base/layout/default.xml b/app/code/Magento/Payment/view/frontend/layout/checkout_onepage_review.xml
similarity index 52%
rename from app/code/Magento/Ui/view/base/layout/default.xml
rename to app/code/Magento/Payment/view/frontend/layout/checkout_onepage_review.xml
index 289b9006c48b5014637cea71d5f054d2ba733e70..8bdab785e571d24a7092c52b5ac420fe697dc1d5 100644
--- a/app/code/Magento/Ui/view/base/layout/default.xml
+++ b/app/code/Magento/Payment/view/frontend/layout/checkout_onepage_review.xml
@@ -7,11 +7,11 @@
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
     <body>
-        <referenceContainer name="footer">
-            <block class="Magento\Ui\Context\DataProvider" name="ui.global.config" after="-">
-                <arguments>
-                    <argument name="content_template" xsi:type="string">Magento_Ui::context/default.phtml</argument>
-                </arguments>
+        <referenceContainer name="checkout.onepage.review.info.items.after">
+            <block class="Magento\Payment\Block\Transparent\Form" name="payment.form.transparent">
+                <action method="setTemplate">
+                    <argument name="template" xsi:type="string">Magento_Payment::transparent/form.phtml</argument>
+                </action>
             </block>
         </referenceContainer>
     </body>
diff --git a/app/code/Magento/Payment/view/frontend/templates/transparent/form.phtml b/app/code/Magento/Payment/view/frontend/templates/transparent/form.phtml
new file mode 100644
index 0000000000000000000000000000000000000000..5a4e8c63822a4ba2097d266cfd99232c67378ba6
--- /dev/null
+++ b/app/code/Magento/Payment/view/frontend/templates/transparent/form.phtml
@@ -0,0 +1,86 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+// @codingStandardsIgnoreFile
+
+/** @var \Magento\Payment\Block\Transparent\Form $block */
+$code = $block->getMethodCode();
+?>
+
+<!-- IFRAME for request to Payment Gateway -->
+<iframe width="0" height="0" id="<?php echo $code ?>-transparent-iframe" data-container="<?php echo $code ?>-transparent-iframe" allowtransparency="true" frameborder="0"  name="iframeTransparent" style="display:none;width:100%;background-color:transparent" src="<?php echo $block->getViewFileUrl('blank.html') ?>"></iframe>
+<form class="form" id="co-transparent-form" action="#" method="post" data-mage-init='{
+    "transparent":{
+        "controller":"<?php echo $block->getRequest()->getControllerName() ?>",
+        "gateway":"<?php echo $code ?>",
+        "orderSaveUrl":"<?php echo $block->getOrderUrl() ?>",
+        "cgiUrl":"<?php echo $block->getCgiUrl() ?>",
+        "dateDelim":"<?php echo $block->getDateDelim() ?>",
+        "cardFieldsMap":<?php echo $block->getCardFieldsMap() ?>,
+        "nativeAction":"<?php echo $block->getUrl('checkout/onepage/saveOrder', ['_secure' => $block->getRequest()->isSecure()]) ?>"
+    }, "validation":[]}'>
+    <fieldset class="fieldset ccard <?php echo $code ?>" id="payment_form_<?php echo $code ?>">
+        <legend class="legend"><span><?php echo __('Credit Card Information') ?></span></legend><br />
+        <div class="field required type">
+            <label for="<?php echo $code ?>_cc_type" class="label"><span><?php echo __('Credit Card Type') ?></span></label>
+            <div class="control">
+                <select id="<?php echo $code ?>_cc_type" data-container="<?php echo $code ?>-cc-type" name="payment[cc_type]" data-validate='{required:true, "validate-cc-type-select":"#<?php echo $code ?>_cc_number"}'>
+                    <option value=""><?php echo __('--Please Select--')?></option>
+                <?php $_ccType = $block->getInfoData('cc_type') ?>
+                <?php foreach ($block->getCcAvailableTypes() as $_typeCode => $_typeName): ?>
+                    <option value="<?php echo $_typeCode ?>"<?php if ($_typeCode == $_ccType): ?> selected="selected"<?php endif ?>><?php echo $_typeName ?></option>
+                <?php endforeach ?>
+                </select>
+            </div>
+        </div>
+        <div class="field required number">
+            <label for="<?php echo $code ?>_cc_number" class="label"><span><?php echo __('Credit Card Number') ?></span></label>
+            <div class="control">
+                <input type="number" id="<?php echo $code ?>_cc_number" data-container="<?php echo $code ?>-cc-number" name="payment[cc_number]" title="<?php echo __('Credit Card Number') ?>" class="input-text" value="" data-validate='{"required-number":true, "validate-cc-number":"#<?php echo $code ?>_cc_type", "validate-cc-type":"#<?php echo $code ?>_cc_type"}' autocomplete="off"/>
+            </div>
+        </div>
+        <div class="field required date" id="<?php echo $code ?>_cc_type_exp_div">
+            <label for="<?php echo $code ?>_expiration" class="label"><span><?php echo __('Expiration Date') ?></span></label>
+            <div class="control">
+                <div class="fields group group-2">
+                    <div class="field no-label month">
+                        <div class="control">
+                            <select id="<?php echo $code ?>_expiration" name="payment[cc_exp_month]" data-container="<?php echo $code ?>-cc-month" class="month" data-validate='{required:true, "validate-cc-exp":"#<?php echo $code ?>_expiration_yr"}'>
+                            <?php $ccExpMonth = $block->getInfoData('cc_exp_month') ?>
+                            <?php foreach ($block->getCcMonths() as $k => $v): ?>
+                                <option value="<?php echo $k ? $k : '' ?>"<?php if ($k == $ccExpMonth): ?> selected="selected"<?php endif ?>><?php echo $v ?></option>
+                            <?php endforeach ?>
+                            </select>
+                        </div>
+                    </div>
+                    <div class="field no-label year">
+                        <div class="control">
+                            <select id="<?php echo $code ?>_expiration_yr" name="payment[cc_exp_year]" class="year" data-container="<?php echo $code ?>-cc-year" data-validate='{required:true}'>
+                            <?php $ccExpYear = $block->getInfoData('cc_exp_year') ?>
+                            <?php foreach ($block->getCcYears() as $k => $v): ?>
+                                <option value="<?php echo $k ? $k : '' ?>"<?php if ($k == $ccExpYear): ?> selected="selected"<?php endif ?>><?php echo $v ?></option>
+                            <?php endforeach ?>
+                            </select>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <?php if ($block->hasVerification()): ?>
+        <div class="field required cvv" id="<?php echo $code ?>_cc_type_cvv_div">
+            <label for="<?php echo $code ?>_cc_cid" class="label"><span><?php echo __('Card Verification Number') ?></span></label>
+            <div class="control">
+                <input type="number" title="<?php echo __('Card Verification Number') ?>" data-container="<?php echo $code ?>-cc-cvv" class="input-text cvv" id="<?php echo $code ?>_cc_cid" name="payment[cc_cid]" value="" data-validate='{"required-number":true, "validate-cc-cvn":"#<?php echo $code ?>_cc_type"}' autocomplete="off"/>
+                <?php $_content = '<img src=\"' . $block->getViewFileUrl('Magento_Checkout::cvv.png') . '\" alt=\"' . __('Card Verification Number Visual Reference') . '\" title=\"' . __('Card Verification Number Visual Reference') . '\" />'; ?>
+                <div class="note">
+                    <a href="#" id="<?php echo $code ?>-cvv-what-is-this" class="action cvv" title="<?php echo $block->escapeHtml(__('What is this?'));?>" data-mage-init='{"tooltip": {"content": "<?php echo $_content ?>"}}'><span><?php echo __('What is this?') ?></span></a>
+                </div>
+            </div>
+        </div>
+        <?php endif; ?>
+    <?php echo $block->getChildHtml() ?>
+</fieldset>
+</form>
diff --git a/app/code/Magento/Payment/view/frontend/templates/transparent/iframe.phtml b/app/code/Magento/Payment/view/frontend/templates/transparent/iframe.phtml
new file mode 100644
index 0000000000000000000000000000000000000000..d090920cb02945f4d00f34b66d6c65355e084007
--- /dev/null
+++ b/app/code/Magento/Payment/view/frontend/templates/transparent/iframe.phtml
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+// @codingStandardsIgnoreFile
+
+/** @var \Magento\Payment\Block\Transparent\Iframe $block */
+$params = $block->getParams();
+?>
+<html>
+    <head>
+        <script>
+        <?php if (isset($params['redirect'])): ?>
+            window.location="<?php echo $block->escapeUrl($params['redirect']) ?>";
+        <?php elseif (isset($params['redirect_parent'])): ?>
+            window.top.location="<?php echo $block->escapeUrl($params['redirect_parent']) ?>";
+        <?php elseif (isset($params['error_msg'])): ?>
+            window.top.alert(<?php echo $this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode($params['error_msg']) ?>);
+        <?php elseif (isset($params['order_success'])): ?>
+            window.top.location = "<?php echo $params['order_success'] ?>";
+        <?php else: ?>
+            var require = window.top.require;
+            require(['jquery'], function($) {
+                $('#opc-review').trigger('hideAjaxLoader');
+                $('#opc-review').trigger('saveOrder');
+            });
+        <?php endif; ?>
+        </script>
+    </head>
+    <body></body>
+</html>
diff --git a/app/code/Magento/Payment/view/frontend/templates/transparent/info.phtml b/app/code/Magento/Payment/view/frontend/templates/transparent/info.phtml
new file mode 100644
index 0000000000000000000000000000000000000000..badfd92d13a478cb0c409eccb4f9f3af9210e150
--- /dev/null
+++ b/app/code/Magento/Payment/view/frontend/templates/transparent/info.phtml
@@ -0,0 +1,13 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+/**
+ * @see \Magento\Payment\Block\Transparent\Info
+ */
+?>
+<fieldset id="payment_form_<?php echo $block->getMethodCode() ?>" style="display:none" class="fieldset items redirect">
+    <div><?php echo __('You\'ll be asked for your payment details before placing an order.') ?></div>
+</fieldset>
diff --git a/app/code/Magento/Payment/view/frontend/web/transparent.js b/app/code/Magento/Payment/view/frontend/web/transparent.js
new file mode 100644
index 0000000000000000000000000000000000000000..570772d6d430c67d6dcd4ea10325fade6d3407b0
--- /dev/null
+++ b/app/code/Magento/Payment/view/frontend/web/transparent.js
@@ -0,0 +1,154 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+define([
+    "jquery",
+    "mage/template",
+    "jquery/ui"
+], function($, mageTemplate){
+    "use strict";
+
+    $.widget('mage.transparent', {
+        options: {
+            placeOrderSelector: '[data-role="review-save"]',
+            paymentFormSelector: '#co-payment-form',
+            updateSelectorPrefix: '#checkout-',
+            updateSelectorSuffix: '-load',
+            hiddenFormTmpl:
+                '<form target="<%= data.target %>" action="<%= data.action %>" method="POST" hidden enctype="application/x-www-form-urlencoded" class="no-display">' +
+                    '<% _.each(data.inputs, function(val, key){ %>' +
+                    '<input value="<%= val %>" name="<%= key %>" type="hidden">' +
+                    '<% }); %>' +
+                '</form>',
+            reviewAgreementForm: '#checkout-agreements',
+            cgiUrl: null,
+            orderSaveUrl: null,
+            controller: null,
+            gateway: null,
+            dateDelim: null,
+            cardFieldsMap: null
+        },
+
+        _create: function() {
+            this.hiddenFormTmpl = mageTemplate(this.options.hiddenFormTmpl);
+            $(this.options.placeOrderSelector)
+                .off('click')
+                .on('click', $.proxy(this._placeOrderHandler, this));
+        },
+
+        /**
+         * handler for Place Order button to call gateway for credit card validation
+         * @return {Boolean}
+         * @private
+         */
+        _placeOrderHandler: function() {
+            if (this.element.validation && this.element.validation('isValid')) {
+                this._orderSave();
+            }
+            return false;
+        },
+
+        /**
+         * Save order and generate post data for gateway call
+         * @private
+         */
+        _orderSave: function() {
+            var postData = $(this.options.paymentFormSelector).serialize();
+            if ($(this.options.reviewAgreementForm).length) {
+                postData += '&' + $(this.options.reviewAgreementForm).serialize();
+            }
+            postData += '&controller=' + this.options.controller;
+            $.ajax({
+                url: this.options.orderSaveUrl,
+                type: 'post',
+                context: this,
+                data: postData,
+                dataType: 'json',
+                beforeSend: function() {this.element.trigger('showAjaxLoader');},
+                success: function(response) {
+                    var preparedData,
+                        msg;
+                    if (response.success && response[this.options.gateway]) {
+                        preparedData = this._preparePaymentData(
+                            response[this.options.gateway].fields,
+                            this.options.cardFieldsMap
+                        );
+                        this._postPaymentToGateway(preparedData);
+                    } else {
+                        msg = response.error_messages;
+                        if (typeof (msg) === 'object') {
+                            alert(msg.join("\n"));
+                        }
+                        if (msg) {
+                            alert(msg);
+                        }
+                    }
+                }
+            });
+        },
+
+        /**
+         * Post data to gateway for credit card validation
+         * @param data
+         * @private
+         */
+        _postPaymentToGateway: function(data) {
+            var tmpl;
+            var iframeSelector = '[data-container="' + this.options.gateway + '-transparent-iframe"]';
+
+            tmpl = this.hiddenFormTmpl({
+                data: {
+                    target: $(iframeSelector).attr('name'),
+                    action: this.options.cgiUrl,
+                    inputs: data
+                }
+            });
+
+            $(tmpl).appendTo($(iframeSelector)).submit();
+        },
+
+        /**
+         * Add credit card fields to post data for gateway
+         * @param data
+         * @param ccfields
+         * @private
+         */
+        _preparePaymentData: function(data, ccfields) {
+            if (this.element.find('[data-container="' + this.options.gateway + '-cc-cvv"]').length) {
+                data[ccfields.cccvv] = this.element.find(
+                    '[data-container="' + this.options.gateway + '-cc-cvv"]'
+                ).val();
+            }
+            var preparedata = this._prepareExpDate();
+            data[ccfields.ccexpdate] = preparedata.month + this.options.dateDelim + preparedata.year;
+            data[ccfields.ccnum] = this.element.find(
+                '[data-container="' + this.options.gateway + '-cc-number"]'
+            ).val();
+            return data;
+        },
+
+        /**
+         * Grab Month and Year into one
+         * @returns {object}
+         * @private
+         */
+        _prepareExpDate: function() {
+            var year = this.element.find('[data-container="' + this.options.gateway + '-cc-year"]').val(),
+                month = parseInt(
+                    this.element.find('[data-container="' + this.options.gateway + '-cc-month"]').val(),
+                    10
+                );
+            if (year.length > 2) {
+                year = year.substring(2);
+            }
+            if (month < 10) {
+                month = '0' + month;
+            }
+            return {month: month, year: year};
+        }
+    });
+
+    return $.mage.transparent;
+});
diff --git a/app/code/Magento/Persistent/Controller/Index.php b/app/code/Magento/Persistent/Controller/Index.php
index 0232cecb0bc7aa8f35766424f9872f8a037dc4b9..69e283a403112f93401ab4fa6f0a81c5bad6f522 100644
--- a/app/code/Magento/Persistent/Controller/Index.php
+++ b/app/code/Magento/Persistent/Controller/Index.php
@@ -5,54 +5,69 @@
  */
 namespace Magento\Persistent\Controller;
 
+use Magento\Framework\App\Action\Action;
+use Magento\Framework\App\Action\Context;
+use Magento\Persistent\Model\QuoteManager;
+use Magento\Checkout\Model\Session as CheckoutSession;
+use Magento\Customer\Model\Session as CustomerSession;
+use Magento\Persistent\Helper\Session as SessionHelper;
+
 /**
  * Persistent front controller
  */
-class Index extends \Magento\Framework\App\Action\Action
+class Index extends Action
 {
     /**
-     * Whether clear checkout session when logout
+     * Persistent observer
      *
-     * @var bool
+     * @var \Magento\Persistent\Model\Observer
      */
-    protected $_clearCheckoutSession = true;
+    protected $quoteManager;
+
+    /**
+     * Checkout session
+     *
+     * @var \Magento\Checkout\Model\Session
+     */
+    protected $checkoutSession;
 
     /**
      * Customer session
      *
      * @var \Magento\Customer\Model\Session
      */
-    protected $_customerSession;
+    protected $customerSession;
 
     /**
-     * Checkout session
-     *
-     * @var \Magento\Checkout\Model\Session
+     * @var \Magento\Persistent\Helper\Session
      */
-    protected $_checkoutSession;
+    protected $sessionHelper;
 
     /**
-     * Persistent observer
+     * Whether clear checkout session when logout
      *
-     * @var \Magento\Persistent\Model\Observer
+     * @var bool
      */
-    protected $quoteManager;
+    protected $clearCheckoutSession = true;
 
     /**
      * @param \Magento\Framework\App\Action\Context $context
      * @param \Magento\Persistent\Model\QuoteManager $quoteManager
      * @param \Magento\Checkout\Model\Session $checkoutSession
      * @param \Magento\Customer\Model\Session $customerSession
+     * @param \Magento\Persistent\Helper\Session $sessionHelper
      */
     public function __construct(
-        \Magento\Framework\App\Action\Context $context,
-        \Magento\Persistent\Model\QuoteManager $quoteManager,
-        \Magento\Checkout\Model\Session $checkoutSession,
-        \Magento\Customer\Model\Session $customerSession
+        Context $context,
+        QuoteManager $quoteManager,
+        CheckoutSession $checkoutSession,
+        CustomerSession $customerSession,
+        SessionHelper $sessionHelper
     ) {
         $this->quoteManager = $quoteManager;
-        $this->_checkoutSession = $checkoutSession;
-        $this->_customerSession = $customerSession;
+        $this->checkoutSession = $checkoutSession;
+        $this->customerSession = $customerSession;
+        $this->sessionHelper = $sessionHelper;
         parent::__construct($context);
     }
 
@@ -64,17 +79,7 @@ class Index extends \Magento\Framework\App\Action\Action
      */
     public function setClearCheckoutSession($clear = true)
     {
-        $this->_clearCheckoutSession = $clear;
+        $this->clearCheckoutSession = $clear;
         return $this;
     }
-
-    /**
-     * Retrieve 'persistent session' helper instance
-     *
-     * @return \Magento\Persistent\Helper\Session
-     */
-    protected function _getHelper()
-    {
-        return $this->_objectManager->get('Magento\Persistent\Helper\Session');
-    }
 }
diff --git a/app/code/Magento/Persistent/Controller/Index/ExpressCheckout.php b/app/code/Magento/Persistent/Controller/Index/ExpressCheckout.php
index cf0a4884841bf1d38405b47b019e63d3f1ee9795..4a53814bbccb1cae33124197c448fd30b7214a30 100644
--- a/app/code/Magento/Persistent/Controller/Index/ExpressCheckout.php
+++ b/app/code/Magento/Persistent/Controller/Index/ExpressCheckout.php
@@ -1,21 +1,26 @@
 <?php
 /**
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
 namespace Magento\Persistent\Controller\Index;
 
-class ExpressCheckout extends \Magento\Persistent\Controller\Index
+use Magento\Persistent\Controller\Index;
+use Magento\Framework\Controller\ResultFactory;
+
+class ExpressCheckout extends Index
 {
     /**
      * Add appropriate session message and redirect to shopping cart
      *
-     * @return void
+     * @return \Magento\Framework\Controller\Result\Redirect
      */
     public function execute()
     {
         $this->messageManager->addNotice(__('Your shopping cart has been updated with new prices.'));
-        $this->_redirect('checkout/cart');
+        /** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */
+        $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
+        $resultRedirect->setPath('checkout/cart');
+        return $resultRedirect;
     }
 }
diff --git a/app/code/Magento/Persistent/Controller/Index/SaveMethod.php b/app/code/Magento/Persistent/Controller/Index/SaveMethod.php
index d64059a510e3ae66ec5f16348bbe0f0ba49c76c1..64e32cb94724642e429b84d55d61c742e6f0e619 100644
--- a/app/code/Magento/Persistent/Controller/Index/SaveMethod.php
+++ b/app/code/Magento/Persistent/Controller/Index/SaveMethod.php
@@ -1,35 +1,33 @@
 <?php
 /**
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
 namespace Magento\Persistent\Controller\Index;
 
-class SaveMethod extends \Magento\Persistent\Controller\Index
-{
-    /**
-     * @var \Magento\Persistent\Model\QuoteManager
-     */
-    protected $quoteManager;
+use Magento\Persistent\Controller\Index;
+use Magento\Framework\Controller\ResultFactory;
 
+class SaveMethod extends Index
+{
     /**
      * Save onepage checkout method to be register
      *
-     * @return void
+     * @return \Magento\Framework\Controller\Result\Redirect
      */
     public function execute()
     {
-        if ($this->_getHelper()->isPersistent()) {
-            $this->_getHelper()->getSession()->removePersistentCookie();
-            if (!$this->_customerSession->isLoggedIn()) {
-                $this->_customerSession->setCustomerId(null)->setCustomerGroupId(null);
+        if ($this->sessionHelper->isPersistent()) {
+            $this->sessionHelper->getSession()->removePersistentCookie();
+            if (!$this->customerSession->isLoggedIn()) {
+                $this->customerSession->setCustomerId(null)->setCustomerGroupId(null);
             }
-
             $this->quoteManager->setGuest();
         }
-
         $checkoutUrl = $this->_redirect->getRefererUrl();
-        $this->getResponse()->setRedirect($checkoutUrl . (strpos($checkoutUrl, '?') ? '&' : '?') . 'register');
+        /** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */
+        $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
+        $resultRedirect->setUrl($checkoutUrl . (strpos($checkoutUrl, '?') ? '&' : '?') . 'register');
+        return $resultRedirect;
     }
 }
diff --git a/app/code/Magento/Persistent/Controller/Index/UnsetCookie.php b/app/code/Magento/Persistent/Controller/Index/UnsetCookie.php
index 8f358bc672a0edff0b6857a99b18eb2adfef0b0f..369c63f7de88093d062f2625bab0558d86f4ad15 100644
--- a/app/code/Magento/Persistent/Controller/Index/UnsetCookie.php
+++ b/app/code/Magento/Persistent/Controller/Index/UnsetCookie.php
@@ -1,40 +1,44 @@
 <?php
 /**
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
 namespace Magento\Persistent\Controller\Index;
 
-class UnsetCookie extends \Magento\Persistent\Controller\Index
+use Magento\Persistent\Controller\Index;
+use Magento\Framework\Controller\ResultFactory;
+
+class UnsetCookie extends Index
 {
     /**
-     * Revert all persistent data
+     * Unset persistent cookie action
      *
-     * @return $this
+     * @return \Magento\Framework\Controller\Result\Redirect
      */
-    protected function _cleanup()
+    public function execute()
     {
-        $this->_eventManager->dispatch('persistent_session_expired');
-        $this->_customerSession->setCustomerId(null)->setCustomerGroupId(null);
-        if ($this->_clearCheckoutSession) {
-            $this->_checkoutSession->clearStorage();
+        if ($this->sessionHelper->isPersistent()) {
+            $this->cleanup();
         }
-        $this->_getHelper()->getSession()->removePersistentCookie();
-        return $this;
+        /** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */
+        $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
+        $resultRedirect->setPath('customer/account/login');
+        return $resultRedirect;
     }
 
     /**
-     * Unset persistent cookie action
+     * Revert all persistent data
      *
-     * @return void
+     * @return $this
      */
-    public function execute()
+    protected function cleanup()
     {
-        if ($this->_getHelper()->isPersistent()) {
-            $this->_cleanup();
+        $this->_eventManager->dispatch('persistent_session_expired');
+        $this->customerSession->setCustomerId(null)->setCustomerGroupId(null);
+        if ($this->clearCheckoutSession) {
+            $this->checkoutSession->clearStorage();
         }
-        $this->_redirect('customer/account/login');
-        return;
+        $this->sessionHelper->getSession()->removePersistentCookie();
+        return $this;
     }
 }
diff --git a/app/code/Magento/Persistent/composer.json b/app/code/Magento/Persistent/composer.json
index 6b71977bb0d02f8105c6b0fc6ab5b57c6345fd7b..820efe841ed01b4dac02fff0edadcc44590e78b1 100644
--- a/app/code/Magento/Persistent/composer.json
+++ b/app/code/Magento/Persistent/composer.json
@@ -3,17 +3,17 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-checkout": "0.74.0-beta6",
-        "magento/module-customer": "0.74.0-beta6",
-        "magento/module-cron": "0.74.0-beta6",
-        "magento/module-page-cache": "0.74.0-beta6",
-        "magento/module-quote": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-checkout": "0.74.0-beta7",
+        "magento/module-customer": "0.74.0-beta7",
+        "magento/module-cron": "0.74.0-beta7",
+        "magento/module-page-cache": "0.74.0-beta7",
+        "magento/module-quote": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/ProductAlert/composer.json b/app/code/Magento/ProductAlert/composer.json
index f6482671da0a929b537d916d2d9960bcf2b24161..662db83f95e273020c4aa550da04fdf71bf8bb06 100644
--- a/app/code/Magento/ProductAlert/composer.json
+++ b/app/code/Magento/ProductAlert/composer.json
@@ -3,14 +3,14 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/module-customer": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/module-customer": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Quote/Model/PaymentMethodManagement.php b/app/code/Magento/Quote/Model/PaymentMethodManagement.php
index fa4add6be7b7ec66b9872c55d1f1f1983ea1c475..b3a512ae1b9330585b778670e4bd647a556e4210 100644
--- a/app/code/Magento/Quote/Model/PaymentMethodManagement.php
+++ b/app/code/Magento/Quote/Model/PaymentMethodManagement.php
@@ -7,10 +7,13 @@ namespace Magento\Quote\Model;
 
 use Magento\Framework\Exception\State\InvalidTransitionException;
 
+/**
+ * Class PaymentMethodManagement
+ */
 class PaymentMethodManagement implements \Magento\Quote\Api\PaymentMethodManagementInterface
 {
     /**
-     * @var \Magento\Quote\Model\QuoteRepository
+     * @var \Magento\Quote\Api\CartRepositoryInterface
      */
     protected $quoteRepository;
 
@@ -25,12 +28,14 @@ class PaymentMethodManagement implements \Magento\Quote\Api\PaymentMethodManagem
     protected $methodList;
 
     /**
-     * @param QuoteRepository $quoteRepository
+     * Constructor
+     *
+     * @param \Magento\Quote\Api\CartRepositoryInterface $quoteRepository
      * @param \Magento\Payment\Model\Checks\ZeroTotal $zeroTotalValidator
      * @param \Magento\Payment\Model\MethodList $methodList
      */
     public function __construct(
-        \Magento\Quote\Model\QuoteRepository $quoteRepository,
+        \Magento\Quote\Api\CartRepositoryInterface $quoteRepository,
         \Magento\Payment\Model\Checks\ZeroTotal $zeroTotalValidator,
         \Magento\Payment\Model\MethodList $methodList
     ) {
@@ -45,7 +50,7 @@ class PaymentMethodManagement implements \Magento\Quote\Api\PaymentMethodManagem
     public function set($cartId, \Magento\Quote\Api\Data\PaymentInterface $method)
     {
         /** @var \Magento\Quote\Model\Quote $quote */
-        $quote = $this->quoteRepository->getActive($cartId);
+        $quote = $this->quoteRepository->get($cartId);
 
         $method->setChecks([
             \Magento\Payment\Model\Method\AbstractMethod::CHECK_USE_CHECKOUT,
@@ -87,7 +92,7 @@ class PaymentMethodManagement implements \Magento\Quote\Api\PaymentMethodManagem
     public function get($cartId)
     {
         /** @var \Magento\Quote\Model\Quote $quote */
-        $quote = $this->quoteRepository->getActive($cartId);
+        $quote = $this->quoteRepository->get($cartId);
         $payment = $quote->getPayment();
         if (!$payment->getId()) {
             return null;
@@ -101,7 +106,7 @@ class PaymentMethodManagement implements \Magento\Quote\Api\PaymentMethodManagem
     public function getList($cartId)
     {
         /** @var \Magento\Quote\Model\Quote $quote */
-        $quote = $this->quoteRepository->getActive($cartId);
+        $quote = $this->quoteRepository->get($cartId);
         return $this->methodList->getAvailableMethods($quote);
     }
 }
diff --git a/app/code/Magento/Quote/Model/Quote.php b/app/code/Magento/Quote/Model/Quote.php
index 88010642002f69ba6d36ff56c882fd2f96076ccd..377ba1d34f937857dc446288129b6cb389284e1d 100644
--- a/app/code/Magento/Quote/Model/Quote.php
+++ b/app/code/Magento/Quote/Model/Quote.php
@@ -11,6 +11,7 @@ namespace Magento\Quote\Model;
 use Magento\Customer\Api\Data\CustomerInterface;
 use Magento\Customer\Api\Data\GroupInterface;
 use Magento\Framework\Model\AbstractExtensibleModel;
+use Magento\Quote\Api\Data\PaymentInterface;
 use Magento\Quote\Model\Quote\Address;
 use Magento\Sales\Model\Resource;
 use Magento\Sales\Model\Status;
@@ -1857,10 +1858,12 @@ class Quote extends AbstractExtensibleModel implements \Magento\Quote\Api\Data\C
     }
 
     /**
-     * @param \Magento\Quote\Model\Quote\Payment $payment
+     * Adds a payment to quote
+     *
+     * @param PaymentInterface $payment
      * @return $this
      */
-    public function addPayment(\Magento\Quote\Model\Quote\Payment $payment)
+    public function addPayment(PaymentInterface $payment)
     {
         $payment->setQuote($this);
         if (!$payment->getId()) {
@@ -1870,10 +1873,12 @@ class Quote extends AbstractExtensibleModel implements \Magento\Quote\Api\Data\C
     }
 
     /**
-     * @param \Magento\Quote\Model\Quote\Payment $payment
-     * @return \Magento\Quote\Model\Quote\Payment
+     * Sets payment to current quote
+     *
+     * @param PaymentInterface $payment
+     * @return PaymentInterface
      */
-    public function setPayment(\Magento\Quote\Model\Quote\Payment $payment)
+    public function setPayment(PaymentInterface $payment)
     {
         if (!$this->getIsMultiPayment() && ($old = $this->getPayment())) {
             $payment->setId($old->getId());
diff --git a/app/code/Magento/Quote/Model/Quote/Payment/ToOrderPayment.php b/app/code/Magento/Quote/Model/Quote/Payment/ToOrderPayment.php
index 9e34d40fdb342ab5ede3cd784d687250c89c41fe..a65e71d224697d8d38abad335a3ba3354482a6c4 100644
--- a/app/code/Magento/Quote/Model/Quote/Payment/ToOrderPayment.php
+++ b/app/code/Magento/Quote/Model/Quote/Payment/ToOrderPayment.php
@@ -67,11 +67,9 @@ class ToOrderPayment
             '\Magento\Sales\Api\Data\OrderPaymentInterface'
         );
         $orderPayment->setAdditionalInformation(
-            serialize(
-                array_merge(
-                    $object->getAdditionalInformation(),
-                    [Substitution::INFO_KEY_TITLE => $object->getMethodInstance()->getTitle()]
-                )
+            array_merge(
+                $object->getAdditionalInformation(),
+                [Substitution::INFO_KEY_TITLE => $object->getMethodInstance()->getTitle()]
             )
         );
         // set directly on the model
diff --git a/app/code/Magento/Quote/Test/Unit/Model/PaymentMethodManagementTest.php b/app/code/Magento/Quote/Test/Unit/Model/PaymentMethodManagementTest.php
index 70dd9e5238ad2e7427574c95c5f39ed533dea5a4..78751a96441cc1cf17f18f01eb3d41fe2fc2f252 100644
--- a/app/code/Magento/Quote/Test/Unit/Model/PaymentMethodManagementTest.php
+++ b/app/code/Magento/Quote/Test/Unit/Model/PaymentMethodManagementTest.php
@@ -34,12 +34,20 @@ class PaymentMethodManagementTest extends \PHPUnit_Framework_TestCase
     protected function setUp()
     {
         $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
-        $this->quoteRepositoryMock = $this->getMock('\Magento\Quote\Model\QuoteRepository', [], [], '', false);
-        $this->methodListMock = $this->getMock('\Magento\Payment\Model\MethodList', [], [], '', false);
-        $this->zeroTotalMock = $this->getMock('\Magento\Payment\Model\Checks\ZeroTotal', [], [], '', false);
+        $this->quoteRepositoryMock = $this->getMockForAbstractClass(
+            'Magento\Quote\Api\CartRepositoryInterface',
+            [],
+            '',
+            false,
+            true,
+            true,
+            []
+        );
+        $this->methodListMock = $this->getMock('Magento\Payment\Model\MethodList', [], [], '', false);
+        $this->zeroTotalMock = $this->getMock('Magento\Payment\Model\Checks\ZeroTotal', [], [], '', false);
 
         $this->model = $this->objectManager->getObject(
-            '\Magento\Quote\Model\PaymentMethodManagement',
+            'Magento\Quote\Model\PaymentMethodManagement',
             [
                 'quoteRepository' => $this->quoteRepositoryMock,
                 'methodList' => $this->methodListMock,
@@ -51,13 +59,13 @@ class PaymentMethodManagementTest extends \PHPUnit_Framework_TestCase
     public function testGetPaymentIfPaymentMethodNotSet()
     {
         $cartId = 11;
-        $quoteMock = $this->getMock('\Magento\Quote\Model\Quote', [], [], '', false);
-        $paymentMock = $this->getMock('\Magento\Quote\Model\Quote\Payment', [], [], '', false);
+        $quoteMock = $this->getMock('Magento\Quote\Model\Quote', [], [], '', false);
+        $paymentMock = $this->getMock('Magento\Quote\Model\Quote\Payment', [], [], '', false);
         $quoteMock->expects($this->once())->method('getPayment')->will($this->returnValue($paymentMock));
         $paymentMock->expects($this->once())->method('getId')->will($this->returnValue(null));
 
         $this->quoteRepositoryMock->expects($this->once())
-            ->method('getActive')
+            ->method('get')
             ->with($cartId)
             ->will($this->returnValue($quoteMock));
 
@@ -68,14 +76,14 @@ class PaymentMethodManagementTest extends \PHPUnit_Framework_TestCase
     {
         $cartId = 11;
 
-        $paymentMock = $this->getMock('\Magento\Quote\Model\Quote\Payment', [], [], '', false);
+        $paymentMock = $this->getMock('Magento\Quote\Model\Quote\Payment', [], [], '', false);
         $paymentMock->expects($this->once())->method('getId')->will($this->returnValue(1));
 
-        $quoteMock = $this->getMock('\Magento\Quote\Model\Quote', [], [], '', false);
+        $quoteMock = $this->getMock('Magento\Quote\Model\Quote', [], [], '', false);
         $quoteMock->expects($this->once())->method('getPayment')->will($this->returnValue($paymentMock));
 
         $this->quoteRepositoryMock->expects($this->once())
-            ->method('getActive')
+            ->method('get')
             ->with($cartId)
             ->will($this->returnValue($quoteMock));
         $this->assertEquals($paymentMock, $this->model->get($cartId));
@@ -84,13 +92,13 @@ class PaymentMethodManagementTest extends \PHPUnit_Framework_TestCase
     public function testGetList()
     {
         $cartId = 10;
-        $quoteMock = $this->getMock('\Magento\Quote\Model\Quote', [], [], '', false);
+        $quoteMock = $this->getMock('Magento\Quote\Model\Quote', [], [], '', false);
         $this->quoteRepositoryMock->expects($this->once())
-            ->method('getActive')
+            ->method('get')
             ->with($cartId)
             ->will($this->returnValue($quoteMock));
 
-        $paymentMethod = $this->getMock('\Magento\Quote\Api\Data\PaymentMethodInterface');
+        $paymentMethod = $this->getMock('Magento\Quote\Api\Data\PaymentMethodInterface');
         $this->methodListMock->expects($this->once())
             ->method('getAvailableMethods')
             ->with($quoteMock)
@@ -106,15 +114,15 @@ class PaymentMethodManagementTest extends \PHPUnit_Framework_TestCase
         $paymentMethod = 'checkmo';
 
         $quoteMock = $this->getMock(
-            '\Magento\Quote\Model\Quote',
+            'Magento\Quote\Model\Quote',
             ['setTotalsCollectedFlag', 'getPayment', 'isVirtual', 'getBillingAddress', 'collectTotals', 'save'],
             [],
             '',
             false
         );
-        $this->quoteRepositoryMock->expects($this->once())->method('getActive')->with($cartId)->willReturn($quoteMock);
+        $this->quoteRepositoryMock->expects($this->once())->method('get')->with($cartId)->willReturn($quoteMock);
 
-        $methodMock = $this->getMock('\Magento\Quote\Model\Quote\Payment', ['setChecks', 'getData'], [], '', false);
+        $methodMock = $this->getMock('Magento\Quote\Model\Quote\Payment', ['setChecks', 'getData'], [], '', false);
         $methodMock->expects($this->once())
             ->method('setChecks')
             ->with([
@@ -127,7 +135,7 @@ class PaymentMethodManagementTest extends \PHPUnit_Framework_TestCase
         $methodMock->expects($this->once())->method('getData')->willReturn($methodData);
 
         $paymentMock = $this->getMock(
-            '\Magento\Quote\Model\Quote\Payment',
+            'Magento\Quote\Model\Quote\Payment',
             ['importData', 'getMethod', 'getMethodInstance', 'getId'],
             [],
             '',
@@ -137,7 +145,7 @@ class PaymentMethodManagementTest extends \PHPUnit_Framework_TestCase
         $paymentMock->expects($this->once())->method('getMethod')->willReturn($paymentMethod);
 
         $billingAddressMock = $this->getMock(
-            '\Magento\Quote\Model\Quote\Address',
+            'Magento\Quote\Model\Quote\Address',
             ['getCountryId', 'setPaymentMethod'],
             [],
             '',
@@ -153,7 +161,7 @@ class PaymentMethodManagementTest extends \PHPUnit_Framework_TestCase
         $quoteMock->expects($this->exactly(2))->method('isVirtual')->willReturn(true);
         $quoteMock->expects($this->exactly(2))->method('getBillingAddress')->willReturn($billingAddressMock);
 
-        $methodInstance = $this->getMock('\Magento\Payment\Model\Checks\PaymentMethodChecksInterface');
+        $methodInstance = $this->getMock('Magento\Payment\Model\Checks\PaymentMethodChecksInterface');
         $paymentMock->expects($this->once())->method('getMethodInstance')->willReturn($methodInstance);
 
         $this->zeroTotalMock->expects($this->once())
@@ -179,15 +187,15 @@ class PaymentMethodManagementTest extends \PHPUnit_Framework_TestCase
         $methodData = ['method' => 'data'];
 
         $quoteMock = $this->getMock(
-            '\Magento\Quote\Model\Quote',
+            'Magento\Quote\Model\Quote',
             ['getPayment', 'isVirtual', 'getBillingAddress'],
             [],
             '',
             false
         );
-        $this->quoteRepositoryMock->expects($this->once())->method('getActive')->with($cartId)->willReturn($quoteMock);
+        $this->quoteRepositoryMock->expects($this->once())->method('get')->with($cartId)->willReturn($quoteMock);
 
-        $methodMock = $this->getMock('\Magento\Quote\Model\Quote\Payment', ['setChecks', 'getData'], [], '', false);
+        $methodMock = $this->getMock('Magento\Quote\Model\Quote\Payment', ['setChecks', 'getData'], [], '', false);
         $methodMock->expects($this->once())
             ->method('setChecks')
             ->with([
@@ -199,10 +207,10 @@ class PaymentMethodManagementTest extends \PHPUnit_Framework_TestCase
             ->willReturnSelf();
         $methodMock->expects($this->once())->method('getData')->willReturn($methodData);
 
-        $paymentMock = $this->getMock('\Magento\Quote\Model\Quote\Payment', ['importData', 'getMethod'], [], '', false);
+        $paymentMock = $this->getMock('Magento\Quote\Model\Quote\Payment', ['importData', 'getMethod'], [], '', false);
         $paymentMock->expects($this->once())->method('importData')->with($methodData)->willReturnSelf();
 
-        $billingAddressMock = $this->getMock('\Magento\Quote\Model\Quote\Address', ['getCountryId'], [], '', false);
+        $billingAddressMock = $this->getMock('Magento\Quote\Model\Quote\Address', ['getCountryId'], [], '', false);
         $billingAddressMock->expects($this->once())->method('getCountryId')->willReturn(null);
 
         $quoteMock->expects($this->once())->method('getPayment')->willReturn($paymentMock);
@@ -223,15 +231,15 @@ class PaymentMethodManagementTest extends \PHPUnit_Framework_TestCase
         $paymentMethod = 'checkmo';
 
         $quoteMock = $this->getMock(
-            '\Magento\Quote\Model\Quote',
+            'Magento\Quote\Model\Quote',
             ['getPayment', 'isVirtual', 'getBillingAddress'],
             [],
             '',
             false
         );
-        $this->quoteRepositoryMock->expects($this->once())->method('getActive')->with($cartId)->willReturn($quoteMock);
+        $this->quoteRepositoryMock->expects($this->once())->method('get')->with($cartId)->willReturn($quoteMock);
 
-        $methodMock = $this->getMock('\Magento\Quote\Model\Quote\Payment', ['setChecks', 'getData'], [], '', false);
+        $methodMock = $this->getMock('Magento\Quote\Model\Quote\Payment', ['setChecks', 'getData'], [], '', false);
         $methodMock->expects($this->once())
             ->method('setChecks')
             ->with([
@@ -244,7 +252,7 @@ class PaymentMethodManagementTest extends \PHPUnit_Framework_TestCase
         $methodMock->expects($this->once())->method('getData')->willReturn($methodData);
 
         $paymentMock = $this->getMock(
-            '\Magento\Quote\Model\Quote\Payment',
+            'Magento\Quote\Model\Quote\Payment',
             ['importData', 'getMethod', 'getMethodInstance'],
             [],
             '',
@@ -254,7 +262,7 @@ class PaymentMethodManagementTest extends \PHPUnit_Framework_TestCase
         $paymentMock->expects($this->once())->method('getMethod')->willReturn($paymentMethod);
 
         $billingAddressMock = $this->getMock(
-            '\Magento\Quote\Model\Quote\Address',
+            'Magento\Quote\Model\Quote\Address',
             ['getCountryId', 'setPaymentMethod'],
             [],
             '',
@@ -270,7 +278,7 @@ class PaymentMethodManagementTest extends \PHPUnit_Framework_TestCase
         $quoteMock->expects($this->exactly(2))->method('isVirtual')->willReturn(true);
         $quoteMock->expects($this->exactly(2))->method('getBillingAddress')->willReturn($billingAddressMock);
 
-        $methodInstance = $this->getMock('\Magento\Payment\Model\Checks\PaymentMethodChecksInterface');
+        $methodInstance = $this->getMock('Magento\Payment\Model\Checks\PaymentMethodChecksInterface');
         $paymentMock->expects($this->once())->method('getMethodInstance')->willReturn($methodInstance);
 
         $this->zeroTotalMock->expects($this->once())
@@ -288,15 +296,15 @@ class PaymentMethodManagementTest extends \PHPUnit_Framework_TestCase
         $paymentMethod = 'checkmo';
 
         $quoteMock = $this->getMock(
-            '\Magento\Quote\Model\Quote',
+            'Magento\Quote\Model\Quote',
             ['getPayment', 'isVirtual', 'getShippingAddress', 'setTotalsCollectedFlag', 'collectTotals', 'save'],
             [],
             '',
             false
         );
-        $this->quoteRepositoryMock->expects($this->once())->method('getActive')->with($cartId)->willReturn($quoteMock);
+        $this->quoteRepositoryMock->expects($this->once())->method('get')->with($cartId)->willReturn($quoteMock);
 
-        $methodMock = $this->getMock('\Magento\Quote\Model\Quote\Payment', ['setChecks', 'getData'], [], '', false);
+        $methodMock = $this->getMock('Magento\Quote\Model\Quote\Payment', ['setChecks', 'getData'], [], '', false);
         $methodMock->expects($this->once())
             ->method('setChecks')
             ->with([
@@ -309,7 +317,7 @@ class PaymentMethodManagementTest extends \PHPUnit_Framework_TestCase
         $methodMock->expects($this->once())->method('getData')->willReturn($methodData);
 
         $paymentMock = $this->getMock(
-            '\Magento\Quote\Model\Quote\Payment',
+            'Magento\Quote\Model\Quote\Payment',
             ['importData', 'getMethod', 'getMethodInstance', 'getId'],
             [],
             '',
@@ -319,7 +327,7 @@ class PaymentMethodManagementTest extends \PHPUnit_Framework_TestCase
         $paymentMock->expects($this->once())->method('getMethod')->willReturn($paymentMethod);
 
         $shippingAddressMock = $this->getMock(
-            '\Magento\Quote\Model\Quote\Address',
+            'Magento\Quote\Model\Quote\Address',
             ['getCountryId', 'setPaymentMethod'],
             [],
             '',
@@ -335,7 +343,7 @@ class PaymentMethodManagementTest extends \PHPUnit_Framework_TestCase
         $quoteMock->expects($this->exactly(2))->method('isVirtual')->willReturn(false);
         $quoteMock->expects($this->exactly(4))->method('getShippingAddress')->willReturn($shippingAddressMock);
 
-        $methodInstance = $this->getMock('\Magento\Payment\Model\Checks\PaymentMethodChecksInterface');
+        $methodInstance = $this->getMock('Magento\Payment\Model\Checks\PaymentMethodChecksInterface');
         $paymentMock->expects($this->once())->method('getMethodInstance')->willReturn($methodInstance);
 
         $this->zeroTotalMock->expects($this->once())
@@ -361,15 +369,15 @@ class PaymentMethodManagementTest extends \PHPUnit_Framework_TestCase
         $methodData = ['method' => 'data'];
 
         $quoteMock = $this->getMock(
-            '\Magento\Quote\Model\Quote',
+            'Magento\Quote\Model\Quote',
             ['getPayment', 'isVirtual', 'getShippingAddress'],
             [],
             '',
             false
         );
-        $this->quoteRepositoryMock->expects($this->once())->method('getActive')->with($cartId)->willReturn($quoteMock);
+        $this->quoteRepositoryMock->expects($this->once())->method('get')->with($cartId)->willReturn($quoteMock);
 
-        $methodMock = $this->getMock('\Magento\Quote\Model\Quote\Payment', ['setChecks', 'getData'], [], '', false);
+        $methodMock = $this->getMock('Magento\Quote\Model\Quote\Payment', ['setChecks', 'getData'], [], '', false);
         $methodMock->expects($this->once())
             ->method('setChecks')
             ->with([
@@ -381,10 +389,10 @@ class PaymentMethodManagementTest extends \PHPUnit_Framework_TestCase
             ->willReturnSelf();
         $methodMock->expects($this->once())->method('getData')->willReturn($methodData);
 
-        $paymentMock = $this->getMock('\Magento\Quote\Model\Quote\Payment', ['importData'], [], '', false);
+        $paymentMock = $this->getMock('Magento\Quote\Model\Quote\Payment', ['importData'], [], '', false);
         $paymentMock->expects($this->once())->method('importData')->with($methodData)->willReturnSelf();
 
-        $shippingAddressMock = $this->getMock('\Magento\Quote\Model\Quote\Address', ['getCountryId'], [], '', false);
+        $shippingAddressMock = $this->getMock('Magento\Quote\Model\Quote\Address', ['getCountryId'], [], '', false);
         $shippingAddressMock->expects($this->once())->method('getCountryId')->willReturn(null);
 
         $quoteMock->expects($this->once())->method('getPayment')->willReturn($paymentMock);
diff --git a/app/code/Magento/Quote/Test/Unit/Model/Quote/Payment/ToOrderPaymentTest.php b/app/code/Magento/Quote/Test/Unit/Model/Quote/Payment/ToOrderPaymentTest.php
index b68aeb602acb6cfd7d7d8af9cf45b60595dcd6c6..aa6099192147fe2557b93e465f822f1b30753d57 100644
--- a/app/code/Magento/Quote/Test/Unit/Model/Quote/Payment/ToOrderPaymentTest.php
+++ b/app/code/Magento/Quote/Test/Unit/Model/Quote/Payment/ToOrderPaymentTest.php
@@ -113,7 +113,7 @@ class ToOrderPaymentTest extends \PHPUnit_Framework_TestCase
         );
         $orderPayment->expects($this->once())
             ->method('setAdditionalInformation')
-            ->with(serialize(array_merge($additionalInfo, [Substitution::INFO_KEY_TITLE => $paymentMethodTitle])))
+            ->with(array_merge($additionalInfo, [Substitution::INFO_KEY_TITLE => $paymentMethodTitle]))
             ->willReturnSelf();
         $orderPayment->expects($this->once())
             ->method('setCcNumber')
diff --git a/app/code/Magento/Quote/composer.json b/app/code/Magento/Quote/composer.json
index c4bf2a50e6d26dbf3884fd47edee836d756ea200..1e9c6075223d256f7c0446991c4c26096cff6261 100644
--- a/app/code/Magento/Quote/composer.json
+++ b/app/code/Magento/Quote/composer.json
@@ -3,25 +3,25 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/module-catalog-rule": "0.74.0-beta6",
-        "magento/module-customer": "0.74.0-beta6",
-        "magento/module-authorization": "0.74.0-beta6",
-        "magento/module-payment": "0.74.0-beta6",
-        "magento/module-sales": "0.74.0-beta6",
-        "magento/module-shipping": "0.74.0-beta6",
-        "magento/module-sales-sequence": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-directory": "0.74.0-beta6",
-        "magento/module-eav": "0.74.0-beta6",
-        "magento/module-tax": "0.74.0-beta6",
-        "magento/module-catalog-inventory": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/module-catalog-rule": "0.74.0-beta7",
+        "magento/module-customer": "0.74.0-beta7",
+        "magento/module-authorization": "0.74.0-beta7",
+        "magento/module-payment": "0.74.0-beta7",
+        "magento/module-sales": "0.74.0-beta7",
+        "magento/module-shipping": "0.74.0-beta7",
+        "magento/module-sales-sequence": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-directory": "0.74.0-beta7",
+        "magento/module-eav": "0.74.0-beta7",
+        "magento/module-tax": "0.74.0-beta7",
+        "magento/module-catalog-inventory": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Quote/etc/di.xml b/app/code/Magento/Quote/etc/di.xml
index 4eeb1ff2b61a7e865d24c28af7411c599b7c3f05..0b46fc59fb7dcbead0e93d40563787ce7f6af5b7 100644
--- a/app/code/Magento/Quote/etc/di.xml
+++ b/app/code/Magento/Quote/etc/di.xml
@@ -25,7 +25,6 @@
     <preference for="Magento\Quote\Api\Data\TotalsInterface" type="\Magento\Quote\Model\Cart\Totals" />
     <preference for="Magento\Quote\Api\Data\TotalsItemInterface" type="\Magento\Quote\Model\Quote\Cart\Totals\Item" />
     <preference for="Magento\Quote\Api\Data\CurrencyInterface" type="\Magento\Quote\Model\Cart\Currency" />
-
     <preference for="Magento\Quote\Api\GuestCartManagementInterface" type="Magento\Quote\Model\GuestCart\GuestCartManagement" />
     <preference for="Magento\Quote\Api\GuestCartRepositoryInterface" type="Magento\Quote\Model\GuestCart\GuestCartRepository" />
     <preference for="Magento\Quote\Api\GuestCartItemRepositoryInterface" type="Magento\Quote\Model\GuestCart\GuestCartItemRepository" />
@@ -35,7 +34,6 @@
     <preference for="Magento\Quote\Api\GuestShippingAddressManagementInterface" type="Magento\Quote\Model\GuestCart\GuestShippingAddressManagement" />
     <preference for="Magento\Quote\Api\GuestShippingMethodManagementInterface" type="Magento\Quote\Model\GuestCart\GuestShippingMethodManagement" />
     <preference for="Magento\Quote\Api\GuestBillingAddressManagementInterface" type="Magento\Quote\Model\GuestCart\GuestBillingAddressManagement" />
-
     <type name="Magento\Webapi\Controller\Rest\ParamsOverrider">
         <arguments>
             <argument name="paramOverriders" xsi:type="array">
@@ -43,4 +41,14 @@
             </argument>
         </arguments>
     </type>
+    <type name="Magento\Quote\Model\QuoteRepository">
+        <arguments>
+            <argument name="quoteCollection" xsi:type="object">Magento\Quote\Model\Resource\Quote\Collection\Proxy</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Quote\Model\Quote\Address">
+        <arguments>
+            <argument name="addressConfig" xsi:type="object">Magento\Customer\Model\Address\Config\Proxy</argument>
+        </arguments>
+    </type>
 </config>
diff --git a/app/code/Magento/Reports/composer.json b/app/code/Magento/Reports/composer.json
index 575834f57dafa4f07f7bb71ab6935fde724e4731..da54b6503db78f7a07f41f55682f196bc169e91a 100644
--- a/app/code/Magento/Reports/composer.json
+++ b/app/code/Magento/Reports/composer.json
@@ -3,28 +3,28 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-config": "0.74.0-beta6",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-eav": "0.74.0-beta6",
-        "magento/module-customer": "0.74.0-beta6",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/module-sales": "0.74.0-beta6",
-        "magento/module-cms": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-widget": "0.74.0-beta6",
-        "magento/module-log": "0.74.0-beta6",
-        "magento/module-wishlist": "0.74.0-beta6",
-        "magento/module-review": "0.74.0-beta6",
-        "magento/module-catalog-inventory": "0.74.0-beta6",
-        "magento/module-tax": "0.74.0-beta6",
-        "magento/module-downloadable": "0.74.0-beta6",
-        "magento/module-sales-rule": "0.74.0-beta6",
-        "magento/module-quote": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-config": "0.74.0-beta7",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-eav": "0.74.0-beta7",
+        "magento/module-customer": "0.74.0-beta7",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/module-sales": "0.74.0-beta7",
+        "magento/module-cms": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-widget": "0.74.0-beta7",
+        "magento/module-log": "0.74.0-beta7",
+        "magento/module-wishlist": "0.74.0-beta7",
+        "magento/module-review": "0.74.0-beta7",
+        "magento/module-catalog-inventory": "0.74.0-beta7",
+        "magento/module-tax": "0.74.0-beta7",
+        "magento/module-downloadable": "0.74.0-beta7",
+        "magento/module-sales-rule": "0.74.0-beta7",
+        "magento/module-quote": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/RequireJs/composer.json b/app/code/Magento/RequireJs/composer.json
index 968f8b00f4780f6abfd675c4d73350b3d1b10f95..09b0a38dcb6ef123f32e19d05b29590d0a1679c1 100644
--- a/app/code/Magento/RequireJs/composer.json
+++ b/app/code/Magento/RequireJs/composer.json
@@ -3,11 +3,11 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/framework": "0.74.0-beta6",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Review/Block/Form.php b/app/code/Magento/Review/Block/Form.php
index 9682f444c4100126155f6daa0ecde88b656ce156..cf506a09857d50ca75e60af14307933802b9678b 100644
--- a/app/code/Magento/Review/Block/Form.php
+++ b/app/code/Magento/Review/Block/Form.php
@@ -163,7 +163,11 @@ class Form extends \Magento\Framework\View\Element\Template
      */
     public function getProductInfo()
     {
-        return $this->productRepository->getById($this->getProductId());
+        return $this->productRepository->getById(
+            $this->getProductId(),
+            false,
+            $this->_storeManager->getStore()->getId()
+        );
     }
 
     /**
diff --git a/app/code/Magento/Review/Model/Resource/Review/Collection.php b/app/code/Magento/Review/Model/Resource/Review/Collection.php
index 7bd2de244b7adb3bdff739d5782cb681e832c41b..d32a6b04ac03043b9fc8a2c596ece7d84af58eaf 100644
--- a/app/code/Magento/Review/Model/Resource/Review/Collection.php
+++ b/app/code/Magento/Review/Model/Resource/Review/Collection.php
@@ -17,35 +17,35 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
      *
      * @var string
      */
-    protected $_reviewTable;
+    protected $_reviewTable = null;
 
     /**
      * Review detail table
      *
      * @var string
      */
-    protected $_reviewDetailTable;
+    protected $_reviewDetailTable = null;
 
     /**
      * Review status table
      *
      * @var string
      */
-    protected $_reviewStatusTable;
+    protected $_reviewStatusTable = null;
 
     /**
      * Review entity table
      *
      * @var string
      */
-    protected $_reviewEntityTable;
+    protected $_reviewEntityTable = null;
 
     /**
      * Review store table
      *
      * @var string
      */
-    protected $_reviewStoreTable;
+    protected $_reviewStoreTable = null;
 
     /**
      * Add store data flag
@@ -111,11 +111,6 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
     protected function _construct()
     {
         $this->_init('Magento\Review\Model\Review', 'Magento\Review\Model\Resource\Review');
-        $this->_reviewTable = $this->getTable('review');
-        $this->_reviewDetailTable = $this->getTable('review_detail');
-        $this->_reviewStatusTable = $this->getTable('review_status');
-        $this->_reviewEntityTable = $this->getTable('review_entity');
-        $this->_reviewStoreTable = $this->getTable('review_store');
     }
 
     /**
@@ -127,7 +122,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
     {
         parent::_initSelect();
         $this->getSelect()->join(
-            ['detail' => $this->_reviewDetailTable],
+            ['detail' => $this->getReviewDetailTable()],
             'main_table.review_id = detail.review_id',
             ['detail_id', 'title', 'detail', 'nickname', 'customer_id']
         );
@@ -156,7 +151,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
     {
         $inCond = $this->getConnection()->prepareSqlCondition('store.store_id', ['in' => $storeId]);
         $this->getSelect()->join(
-            ['store' => $this->_reviewStoreTable],
+            ['store' => $this->getReviewStoreTable()],
             'main_table.review_id=store.review_id',
             []
         );
@@ -184,18 +179,19 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
      */
     public function addEntityFilter($entity, $pkValue)
     {
+        $reviewEntityTable = $this->getReviewEntityTable();
         if (is_numeric($entity)) {
             $this->addFilter('entity', $this->getConnection()->quoteInto('main_table.entity_id=?', $entity), 'string');
         } elseif (is_string($entity)) {
             $this->_select->join(
-                $this->_reviewEntityTable,
-                'main_table.entity_id=' . $this->_reviewEntityTable . '.entity_id',
+                $reviewEntityTable,
+                'main_table.entity_id=' . $reviewEntityTable . '.entity_id',
                 ['entity_code']
             );
 
             $this->addFilter(
                 'entity',
-                $this->getConnection()->quoteInto($this->_reviewEntityTable . '.entity_code=?', $entity),
+                $this->getConnection()->quoteInto($reviewEntityTable . '.entity_code=?', $entity),
                 'string'
             );
         }
@@ -268,7 +264,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
     public function addReviewsTotalCount()
     {
         $this->_select->joinLeft(
-            ['r' => $this->_reviewTable],
+            ['r' => $this->getReviewTable()],
             'main_table.entity_pk_value = r.entity_pk_value',
             ['total_reviews' => new \Zend_Db_Expr('COUNT(r.review_id)')]
         )->group(
@@ -311,7 +307,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
         $storesToReviews = [];
         if (count($reviewsIds) > 0) {
             $inCond = $adapter->prepareSqlCondition('review_id', ['in' => $reviewsIds]);
-            $select = $adapter->select()->from($this->_reviewStoreTable)->where($inCond);
+            $select = $adapter->select()->from($this->getReviewStoreTable())->where($inCond);
             $result = $adapter->fetchAll($select);
             foreach ($result as $row) {
                 if (!isset($storesToReviews[$row['review_id']])) {
@@ -329,4 +325,69 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
             }
         }
     }
+
+    /**
+     * Get review table
+     *
+     * @return string
+     */
+    protected function getReviewTable()
+    {
+        if ($this->_reviewTable === null) {
+            $this->_reviewTable = $this->getTable('review');
+        }
+        return $this->_reviewTable;
+    }
+
+    /**
+     * Get review detail table
+     *
+     * @return string
+     */
+    protected function getReviewDetailTable()
+    {
+        if ($this->_reviewDetailTable === null) {
+            $this->_reviewDetailTable = $this->getTable('review_detail');
+        }
+        return $this->_reviewDetailTable;
+    }
+
+    /**
+     * Get review status table
+     *
+     * @return string
+     */
+    protected function getReviewStatusTable()
+    {
+        if ($this->_reviewStatusTable === null) {
+            $this->_reviewStatusTable = $this->getTable('review_status');
+        }
+        return $this->_reviewStatusTable;
+    }
+
+    /**
+     * Get review entity table
+     *
+     * @return string
+     */
+    protected function getReviewEntityTable()
+    {
+        if ($this->_reviewEntityTable === null) {
+            $this->_reviewEntityTable = $this->getTable('review_entity');
+        }
+        return $this->_reviewEntityTable;
+    }
+
+    /**
+     * Get review store table
+     *
+     * @return string
+     */
+    protected function getReviewStoreTable()
+    {
+        if ($this->_reviewStoreTable === null) {
+            $this->_reviewStoreTable = $this->getTable('review_store');
+        }
+        return $this->_reviewStoreTable;
+    }
 }
diff --git a/app/code/Magento/Review/Test/Unit/Block/FormTest.php b/app/code/Magento/Review/Test/Unit/Block/FormTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..32a59cf8334c59766d49955916821c587a1bb32f
--- /dev/null
+++ b/app/code/Magento/Review/Test/Unit/Block/FormTest.php
@@ -0,0 +1,99 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Review\Test\Unit\Block;
+
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
+
+class FormTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\Review\Block\Form */
+    protected $object;
+
+    /** @var ObjectManagerHelper */
+    protected $objectManagerHelper;
+
+    /**
+     * @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $requestMock;
+
+    /** @var \Magento\Framework\View\Element\Template\Context|\PHPUnit_Framework_MockObject_MockObject */
+    protected $context;
+
+    /**
+     * @var \Magento\Review\Helper\Data|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $reviewDataMock;
+
+    /** @var \Magento\Catalog\Api\ProductRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $productRepository;
+
+    /** @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $storeManager;
+
+    protected function setUp()
+    {
+        $this->storeManager = $this->getMock('\Magento\Store\Model\StoreManagerInterface');
+        $this->requestMock = $this->getMock('\Magento\Framework\App\RequestInterface');
+        $this->reviewDataMock = $this->getMockBuilder('\Magento\Review\Helper\Data')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->reviewDataMock->expects($this->once())
+            ->method('getIsGuestAllowToWrite')
+            ->willReturn(true);
+
+        $this->context = $this->getMock('Magento\Framework\View\Element\Template\Context', [], [], '', false);
+        $this->context->expects(
+            $this->any()
+        )->method(
+            'getStoreManager'
+        )->will(
+            $this->returnValue($this->storeManager)
+        );
+        $this->context->expects($this->any())
+            ->method('getRequest')
+            ->willReturn($this->requestMock);
+        $this->productRepository = $this->getMock('\Magento\Catalog\Api\ProductRepositoryInterface');
+
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+        $this->object = $this->objectManagerHelper->getObject(
+            'Magento\Review\Block\Form',
+            [
+                'context' => $this->context,
+                'reviewData' => $this->reviewDataMock,
+                'productRepository' => $this->productRepository,
+            ]
+        );
+    }
+
+    public function testGetProductInfo()
+    {
+        $productId = 3;
+        $storeId = 1;
+
+        $this->storeManager->expects(
+            $this->any()
+        )->method(
+            'getStore'
+        )->will(
+            $this->returnValue(new \Magento\Framework\Object(['id' => $storeId]))
+        );
+
+        $this->requestMock->expects($this->once())
+            ->method('getParam')
+            ->with('id', false)
+            ->willReturn($productId);
+
+        $productMock = $this->getMock('Magento\Catalog\Api\Data\ProductInterface');
+        $this->productRepository->expects($this->once())
+            ->method('getById')
+            ->with($productId, false, $storeId)
+            ->willReturn($productMock);
+
+        $this->assertSame($productMock, $this->object->getProductInfo());
+    }
+}
diff --git a/app/code/Magento/Review/Test/Unit/Model/Resource/Review/CollectionTest.php b/app/code/Magento/Review/Test/Unit/Model/Resource/Review/CollectionTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..67e67cdf8381745aa356f7b85129945f2d563d33
--- /dev/null
+++ b/app/code/Magento/Review/Test/Unit/Model/Resource/Review/CollectionTest.php
@@ -0,0 +1,188 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Review\Test\Unit\Model\Resource\Review;
+
+class CollectionTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Review\Model\Resource\Review\Collection
+     */
+    protected $model;
+
+    /**
+     * @var \Zend_Db_Select | \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $selectMock;
+
+    /**
+     * @var \Magento\Store\Model\StoreManagerInterface | \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $storeManagerMock;
+
+    /**
+     * @var \Magento\Framework\Model\Resource\Db\AbstractDb | \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $resourceMock;
+
+    /**
+     * @var \Zend_Db_Adapter_Abstract | \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $readerAdapterMock;
+
+    /**
+     * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager
+     */
+    protected $objectManager;
+
+    public function setUp()
+    {
+        $store = $this->getMock('\Magento\Store\Model\Store', ['getId'], [], '', false);
+        $store->expects($this->any())->method('getId')->will($this->returnValue(1));
+        $this->storeManagerMock = $this->getMock('Magento\Store\Model\StoreManagerInterface');
+        $this->storeManagerMock->expects($this->any())->method('getStore')->will($this->returnValue($store));
+        $this->objectManager = (new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this));
+        $this->resourceMock = $this->getMockBuilder('Magento\Framework\Model\Resource\Db\AbstractDb')
+            ->disableOriginalConstructor()
+            ->setMethods(['getReadConnection', 'getMainTable', 'getTable'])
+            ->getMockForAbstractClass();
+        $this->readerAdapterMock = $this->getMockBuilder('\Zend_Db_Adapter_Abstract')
+            ->disableOriginalConstructor()
+            ->setMethods(['select', 'prepareSqlCondition', 'quoteInto'])
+            ->getMockForAbstractClass();
+        $this->selectMock = $this->getMockBuilder('\Zend_Db_Select')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->readerAdapterMock->expects($this->any())
+            ->method('select')
+            ->willReturn($this->selectMock);
+        $this->resourceMock->expects($this->any())
+            ->method('getReadConnection')
+            ->willReturn($this->readerAdapterMock);
+        $this->resourceMock->expects($this->any())
+            ->method('getMainTable')
+            ->willReturn('maintable');
+        $this->resourceMock->expects($this->any())
+            ->method('getTable')
+            ->willReturnCallback(function ($table) {
+                return $table;
+            });
+        $this->model = $this->objectManager->getObject(
+            '\Magento\Review\Model\Resource\Review\Collection',
+            [
+                'storeManager' => $this->storeManagerMock,
+                'resource' => $this->resourceMock,
+            ]
+        );
+
+    }
+
+    public function testInitSelect()
+    {
+        $this->selectMock->expects($this->once())
+            ->method('join')
+            ->with(
+                ['detail' => 'review_detail'],
+                'main_table.review_id = detail.review_id',
+                ['detail_id', 'title', 'detail', 'nickname', 'customer_id']
+            );
+        $this->objectManager->getObject(
+            '\Magento\Review\Model\Resource\Review\Collection',
+            [
+                'storeManager' => $this->storeManagerMock,
+                'resource' => $this->resourceMock,
+            ]
+        );
+    }
+
+    public function testAddStoreFilter()
+    {
+        $this->readerAdapterMock->expects($this->once())
+            ->method('prepareSqlCondition');
+        $this->selectMock->expects($this->once())
+            ->method('join')
+            ->with(
+                ['store' => 'review_store'],
+                'main_table.review_id=store.review_id',
+                []
+            );
+        $this->model->addStoreFilter(1);
+    }
+
+    /**
+     * @param int|string $entity
+     * @param int $pkValue
+     * @param string $quoteIntoArguments1
+     * @param string $quoteIntoArguments2
+     * @param string $quoteIntoReturn1
+     * @param string $quoteIntoReturn2
+     * @param int $callNum
+     * @dataProvider addEntityFilterDataProvider
+     */
+    public function testAddEntityFilter(
+        $entity,
+        $pkValue,
+        $quoteIntoArguments1,
+        $quoteIntoArguments2,
+        $quoteIntoReturn1,
+        $quoteIntoReturn2,
+        $callNum
+    ) {
+        $this->readerAdapterMock->expects($this->at(0))
+            ->method('quoteInto')
+            ->with($quoteIntoArguments1[0], $quoteIntoArguments1[1])
+            ->willReturn($quoteIntoReturn1);
+        $this->readerAdapterMock->expects($this->at(1))
+            ->method('quoteInto')
+            ->with($quoteIntoArguments2[0], $quoteIntoArguments2[1])
+            ->willReturn($quoteIntoReturn2);
+        $this->selectMock->expects($this->exactly($callNum))
+            ->method('join')
+            ->with(
+                'review_entity',
+                'main_table.entity_id=' . 'review_entity' . '.entity_id',
+                ['entity_code']
+            );
+        $this->model->addEntityFilter($entity, $pkValue);
+    }
+
+    public function addEntityFilterDataProvider()
+    {
+        return [
+            [
+                1,
+                2,
+                ['main_table.entity_id=?', 1],
+                ['main_table.entity_pk_value=?', 2],
+                'quoteIntoReturn1',
+                'quoteIntoReturn2',
+                0
+            ],
+            [
+                'entity',
+                2,
+                ['review_entity.entity_code=?', 'entity'],
+                ['main_table.entity_pk_value=?', 2],
+                'quoteIntoReturn1',
+                'quoteIntoReturn2',
+                1
+            ]
+        ];
+    }
+
+    public function testAddReviewsTotalCount()
+    {
+        $this->selectMock->expects($this->once())
+            ->method('joinLeft')
+            ->with(
+                ['r' => 'review'],
+                'main_table.entity_pk_value = r.entity_pk_value',
+                ['total_reviews' => new \Zend_Db_Expr('COUNT(r.review_id)')]
+            )->willReturnSelf();
+        $this->selectMock->expects($this->once())
+            ->method('group');
+        $this->model->addReviewsTotalCount();
+    }
+}
diff --git a/app/code/Magento/Review/composer.json b/app/code/Magento/Review/composer.json
index 35197e270227acf8a04a3e0915411c076af46e0d..10b89c9f5b04bff6ba97ad1d1c720a0970314673 100644
--- a/app/code/Magento/Review/composer.json
+++ b/app/code/Magento/Review/composer.json
@@ -3,22 +3,22 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/module-customer": "0.74.0-beta6",
-        "magento/module-eav": "0.74.0-beta6",
-        "magento/module-theme": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-newsletter": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
-        "magento/module-ui": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/module-customer": "0.74.0-beta7",
+        "magento/module-eav": "0.74.0-beta7",
+        "magento/module-theme": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-newsletter": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
+        "magento/module-ui": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "suggest": {
-        "magento/module-cookie": "0.74.0-beta6"
+        "magento/module-cookie": "0.74.0-beta7"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Review/view/adminhtml/layout/customer_form.xml b/app/code/Magento/Review/view/adminhtml/layout/customer_index_edit.xml
similarity index 91%
rename from app/code/Magento/Review/view/adminhtml/layout/customer_form.xml
rename to app/code/Magento/Review/view/adminhtml/layout/customer_index_edit.xml
index 09fe7121ca4f6407351238f0802a4fd999dd1e35..a6fe4a094eb0f1425af6a7dcf876f619ce58d1c1 100644
--- a/app/code/Magento/Review/view/adminhtml/layout/customer_form.xml
+++ b/app/code/Magento/Review/view/adminhtml/layout/customer_index_edit.xml
@@ -7,7 +7,7 @@
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
     <body>
-        <referenceBlock name="form">
+        <referenceBlock name="customer_form">
             <block acl="Magento_Review::reviews_all" class="Magento\Review\Block\Adminhtml\ReviewTab" name="reviews" />
         </referenceBlock>
     </body>
diff --git a/app/code/Magento/Rss/composer.json b/app/code/Magento/Rss/composer.json
index cb02900c44ef080abe82adcc3879c5394cf4640c..2e3f52bd9644d567c605deb87d855e01c32f6e8c 100644
--- a/app/code/Magento/Rss/composer.json
+++ b/app/code/Magento/Rss/composer.json
@@ -3,14 +3,14 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
-        "magento/module-customer": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
+        "magento/module-customer": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Rule/composer.json b/app/code/Magento/Rule/composer.json
index 4e9e4fd3965676ec789fcae5df2f3fc27a1601ca..f03b63cba961c0adf432192ca5b2809a5a134c6e 100644
--- a/app/code/Magento/Rule/composer.json
+++ b/app/code/Magento/Rule/composer.json
@@ -3,16 +3,16 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-eav": "0.74.0-beta6",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-eav": "0.74.0-beta7",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "lib-libxml": "*",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Sales/Api/Data/CreditmemoCommentInterface.php b/app/code/Magento/Sales/Api/Data/CreditmemoCommentInterface.php
index 28afae3c0f9528343770c22dfe283b82324a7c5a..3a4a5c23033f48a2b2fcc41eb519330cb3e955fd 100644
--- a/app/code/Magento/Sales/Api/Data/CreditmemoCommentInterface.php
+++ b/app/code/Magento/Sales/Api/Data/CreditmemoCommentInterface.php
@@ -57,6 +57,14 @@ interface CreditmemoCommentInterface extends \Magento\Framework\Api\ExtensibleDa
      */
     public function getCreatedAt();
 
+    /**
+     * Sets the credit memo created-at timestamp.
+     *
+     * @param string $createdAt timestamp
+     * @return $this
+     */
+    public function setCreatedAt($createdAt);
+
     /**
      * Gets the credit memo ID.
      *
diff --git a/app/code/Magento/Sales/Api/Data/CreditmemoInterface.php b/app/code/Magento/Sales/Api/Data/CreditmemoInterface.php
index 205d5c37b3f1033132c9679a240e036223a2e5e8..ce5a46b9838b447159bcf96b87bbd8753e46ed5e 100644
--- a/app/code/Magento/Sales/Api/Data/CreditmemoInterface.php
+++ b/app/code/Magento/Sales/Api/Data/CreditmemoInterface.php
@@ -383,6 +383,15 @@ interface CreditmemoInterface extends \Magento\Framework\Api\ExtensibleDataInter
      * @return string Credit memo created-at timestamp.
      */
     public function getCreatedAt();
+
+    /**
+     * Sets the credit memo created-at timestamp.
+     *
+     * @param string $createdAt timestamp
+     * @return $this
+     */
+    public function setCreatedAt($createdAt);
+
     /**
      * Gets the credit memo status.
      *
diff --git a/app/code/Magento/Sales/Api/Data/InvoiceCommentInterface.php b/app/code/Magento/Sales/Api/Data/InvoiceCommentInterface.php
index 10c86a870231cd4cd0c24a165c1cc5cf022bcdaf..ec6fce4016f6a0d397858b3ebf5848cacdc3e047 100644
--- a/app/code/Magento/Sales/Api/Data/InvoiceCommentInterface.php
+++ b/app/code/Magento/Sales/Api/Data/InvoiceCommentInterface.php
@@ -55,6 +55,14 @@ interface InvoiceCommentInterface extends \Magento\Framework\Api\ExtensibleDataI
      */
     public function getCreatedAt();
 
+    /**
+     * Sets the created-at timestamp for the invoice.
+     *
+     * @param string $createdAt timestamp
+     * @return $this
+     */
+    public function setCreatedAt($createdAt);
+
     /**
      * Gets the ID for the invoice.
      *
diff --git a/app/code/Magento/Sales/Api/Data/InvoiceInterface.php b/app/code/Magento/Sales/Api/Data/InvoiceInterface.php
index e17decc98e0bbd364313f43a2d7373cbfd7990cc..fcbe20b83f28c96b939277d524a04dec9f923b7d 100644
--- a/app/code/Magento/Sales/Api/Data/InvoiceInterface.php
+++ b/app/code/Magento/Sales/Api/Data/InvoiceInterface.php
@@ -319,6 +319,14 @@ interface InvoiceInterface extends \Magento\Framework\Api\ExtensibleDataInterfac
      */
     public function getCreatedAt();
 
+    /**
+     * Sets the created-at timestamp for the invoice.
+     *
+     * @param string $createdAt timestamp
+     * @return $this
+     */
+    public function setCreatedAt($createdAt);
+
     /**
      * Gets the discount amount for the invoice.
      *
diff --git a/app/code/Magento/Sales/Api/Data/OrderInterface.php b/app/code/Magento/Sales/Api/Data/OrderInterface.php
index 7bd62fbe1c3228b2241690b981a7f0ab8c2f84eb..42ccf6aee23c151088f27b7d6e714237a75ce845 100644
--- a/app/code/Magento/Sales/Api/Data/OrderInterface.php
+++ b/app/code/Magento/Sales/Api/Data/OrderInterface.php
@@ -914,6 +914,14 @@ interface OrderInterface extends \Magento\Framework\Api\ExtensibleDataInterface
      */
     public function getCreatedAt();
 
+    /**
+     * Sets the created-at timestamp for the order.
+     *
+     * @param string $createdAt timestamp
+     * @return $this
+     */
+    public function setCreatedAt($createdAt);
+
     /**
      * Gets the customer date-of-birth (DOB) for the order.
      *
diff --git a/app/code/Magento/Sales/Api/Data/OrderItemInterface.php b/app/code/Magento/Sales/Api/Data/OrderItemInterface.php
index 6e59b03a98370feb88a6d6522c9fb84560e12bf3..e10e196380670f54fd11963a281738c50226d20c 100644
--- a/app/code/Magento/Sales/Api/Data/OrderItemInterface.php
+++ b/app/code/Magento/Sales/Api/Data/OrderItemInterface.php
@@ -578,6 +578,14 @@ interface OrderItemInterface extends \Magento\Framework\Api\ExtensibleDataInterf
      */
     public function getCreatedAt();
 
+    /**
+     * Sets the created-at timestamp for the order item.
+     *
+     * @param string $createdAt timestamp
+     * @return $this
+     */
+    public function setCreatedAt($createdAt);
+
     /**
      * Gets the description for the order item.
      *
diff --git a/app/code/Magento/Sales/Api/Data/OrderStatusHistoryInterface.php b/app/code/Magento/Sales/Api/Data/OrderStatusHistoryInterface.php
index 4ef7daf322d37f0ca1b26f0ab7501e7ad5a79fcf..3a27e326c3b88866c1cb03ec4c84227391e46416 100644
--- a/app/code/Magento/Sales/Api/Data/OrderStatusHistoryInterface.php
+++ b/app/code/Magento/Sales/Api/Data/OrderStatusHistoryInterface.php
@@ -64,6 +64,14 @@ interface OrderStatusHistoryInterface extends \Magento\Framework\Api\ExtensibleD
      */
     public function getCreatedAt();
 
+    /**
+     * Sets the created-at timestamp for the order status history.
+     *
+     * @param string $createdAt timestamp
+     * @return $this
+     */
+    public function setCreatedAt($createdAt);
+
     /**
      * Gets the ID for the order status history.
      *
diff --git a/app/code/Magento/Sales/Api/Data/ShipmentCommentInterface.php b/app/code/Magento/Sales/Api/Data/ShipmentCommentInterface.php
index 213b7c2e5e4931bd9f9295aee3b537f817891a68..e6bcd71928463f0bd09446f60bc303a1a31f4864 100644
--- a/app/code/Magento/Sales/Api/Data/ShipmentCommentInterface.php
+++ b/app/code/Magento/Sales/Api/Data/ShipmentCommentInterface.php
@@ -55,6 +55,14 @@ interface ShipmentCommentInterface extends \Magento\Framework\Api\ExtensibleData
      */
     public function getCreatedAt();
 
+    /**
+     * Sets the created-at timestamp for the shipment comment.
+     *
+     * @param string $createdAt timestamp
+     * @return $this
+     */
+    public function setCreatedAt($createdAt);
+
     /**
      * Gets the ID for the shipment comment.
      *
diff --git a/app/code/Magento/Sales/Api/Data/ShipmentInterface.php b/app/code/Magento/Sales/Api/Data/ShipmentInterface.php
index 41c676ea2081219e35d7e7d6561206f4f5bf5c24..67b3b60b05266ef8febff35e6df0952414ebdea1 100644
--- a/app/code/Magento/Sales/Api/Data/ShipmentInterface.php
+++ b/app/code/Magento/Sales/Api/Data/ShipmentInterface.php
@@ -103,6 +103,14 @@ interface ShipmentInterface extends \Magento\Framework\Api\ExtensibleDataInterfa
      */
     public function getCreatedAt();
 
+    /**
+     * Sets the created-at timestamp for the shipment.
+     *
+     * @param string $createdAt timestamp
+     * @return $this
+     */
+    public function setCreatedAt($createdAt);
+
     /**
      * Gets the customer ID for the shipment.
      *
diff --git a/app/code/Magento/Sales/Api/Data/ShipmentTrackInterface.php b/app/code/Magento/Sales/Api/Data/ShipmentTrackInterface.php
index 7ace1ead4114db6c8c81c9a3921d56f1e9195727..e9bfa3915c4074096f9d5023e5a5c13514a92267 100644
--- a/app/code/Magento/Sales/Api/Data/ShipmentTrackInterface.php
+++ b/app/code/Magento/Sales/Api/Data/ShipmentTrackInterface.php
@@ -76,6 +76,14 @@ interface ShipmentTrackInterface extends \Magento\Framework\Api\ExtensibleDataIn
      */
     public function getCreatedAt();
 
+    /**
+     * Sets the created-at timestamp for the shipment package.
+     *
+     * @param string $createdAt timestamp
+     * @return $this
+     */
+    public function setCreatedAt($createdAt);
+
     /**
      * Gets the description for the shipment package.
      *
diff --git a/app/code/Magento/Sales/Api/Data/TransactionInterface.php b/app/code/Magento/Sales/Api/Data/TransactionInterface.php
index 224d9765582f0e3381846f159814103e72111351..92d431c6e0b5754ed8222c5deb9f8fb02f28ce05 100644
--- a/app/code/Magento/Sales/Api/Data/TransactionInterface.php
+++ b/app/code/Magento/Sales/Api/Data/TransactionInterface.php
@@ -75,6 +75,14 @@ interface TransactionInterface extends \Magento\Framework\Api\ExtensibleDataInte
      */
     public function getTransactionId();
 
+    /**
+     * Sets the transaction ID for the transaction.
+     *
+     * @param int $id
+     * @return $this
+     */
+    public function setTransactionId($id);
+
     /**
      * Gets the parent ID for the transaction.
      *
@@ -138,6 +146,14 @@ interface TransactionInterface extends \Magento\Framework\Api\ExtensibleDataInte
      */
     public function getCreatedAt();
 
+    /**
+     * Sets the created-at timestamp for the transaction.
+     *
+     * @param string $createdAt timestamp
+     * @return $this
+     */
+    public function setCreatedAt($createdAt);
+
     /**
      * Gets an array of child transactions for the transaction.
      *
diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Comments/View.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Comments/View.php
index 6dd4434c6e0ef0fc6c47735fa50d84c312ee3230..ea065d8eea7a6dc695f3c1d2c023e39af251f1a6 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Order/Comments/View.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Comments/View.php
@@ -60,7 +60,7 @@ class View extends \Magento\Backend\Block\Template
         $this->addChild(
             'submit_button',
             'Magento\Backend\Block\Widget\Button',
-            ['id' => 'submit_comment_button', 'label' => __('Submit Comment'), 'class' => 'save']
+            ['id' => 'submit_comment_button', 'label' => __('Submit Comment'), 'class' => 'action-secondary save']
         );
         return parent::_prepareLayout();
     }
diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Store.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Store.php
index 908dabf48c15cc5f7e4cdaec3eec7c08431fd7a3..cf83b3bc125c7ffd8cb391fd3ea55b687629ab5a 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Store.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Store.php
@@ -30,6 +30,6 @@ class Store extends \Magento\Sales\Block\Adminhtml\Order\Create\AbstractCreate
      */
     public function getHeaderText()
     {
-        return __('Please select a store.');
+        return __('Please select a store');
     }
 }
diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/View/History.php b/app/code/Magento/Sales/Block/Adminhtml/Order/View/History.php
index ad82046b66ed50ea6914ed6775cb90e8b482661e..d0284f3175fdc79c07fd9938f5634fa76cab7ef9 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Order/View/History.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Order/View/History.php
@@ -54,7 +54,7 @@ class History extends \Magento\Backend\Block\Template
         $button = $this->getLayout()->createBlock(
             'Magento\Backend\Block\Widget\Button'
         )->setData(
-            ['label' => __('Submit Comment'), 'class' => 'save', 'onclick' => $onclick]
+            ['label' => __('Submit Comment'), 'class' => 'action-save action-secondary', 'onclick' => $onclick]
         );
         $this->setChild('submit_button', $button);
         return parent::_prepareLayout();
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/EditInterface.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/EditInterface.php
deleted file mode 100644
index 79fefe2a18515d4f143f561aba1c9a2f9e3f4cde..0000000000000000000000000000000000000000
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/EditInterface.php
+++ /dev/null
@@ -1,11 +0,0 @@
-<?php
-/**
- *
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Sales\Controller\Adminhtml\Order;
-
-interface EditInterface extends \Magento\Framework\App\ActionInterface
-{
-}
diff --git a/app/code/Magento/Sales/Model/Order.php b/app/code/Magento/Sales/Model/Order.php
index 94847e91dbe200c9ea34764d4981d08ac986db98..43f4b95497720ed8df3e7f74a4cc03e31255b980 100644
--- a/app/code/Magento/Sales/Model/Order.php
+++ b/app/code/Magento/Sales/Model/Order.php
@@ -35,7 +35,6 @@ use Magento\Sales\Model\Resource\Order\Status\History\Collection as HistoryColle
  * @method \Magento\Sales\Model\Resource\Order getResource()
  * @method int getGiftMessageId()
  * @method \Magento\Sales\Model\Order setGiftMessageId(int $value)
- * @method \Magento\Sales\Model\Order setCreatedAt(string $value)
  * @method bool hasBillingAddressId()
  * @method \Magento\Sales\Model\Order unsBillingAddressId()
  * @method bool hasShippingAddressId()
@@ -920,6 +919,8 @@ class Order extends AbstractModel implements EntityInterface, OrderInterface
      * Order state setter.
      * If status is specified, will add order status history with specified comment
      * the setData() cannot be overridden because of compatibility issues with resource model
+     * By default allows to set any state. Can also update status to default or specified value
+     * Complete and closed states are encapsulated intentionally
      *
      * @param string $state
      * @param string|bool $status
@@ -927,6 +928,7 @@ class Order extends AbstractModel implements EntityInterface, OrderInterface
      * @param bool $isCustomerNotified
      * @param bool $shouldProtectState
      * @return \Magento\Sales\Model\Order
+     * @throws \Magento\Framework\Exception\LocalizedException
      */
     public function setState(
         $state,
@@ -935,29 +937,7 @@ class Order extends AbstractModel implements EntityInterface, OrderInterface
         $isCustomerNotified = null,
         $shouldProtectState = true
     ) {
-        return $this->_setState($state, $status, $comment, $isCustomerNotified, $shouldProtectState);
-    }
 
-    /**
-     * Order state protected setter.
-     * By default allows to set any state. Can also update status to default or specified value
-     * Complete and closed states are encapsulated intentionally, see the _checkState()
-     *
-     * @param string $state
-     * @param string|bool $status
-     * @param string $comment
-     * @param bool $isCustomerNotified
-     * @param bool $shouldProtectState
-     * @return $this
-     * @throws \Magento\Framework\Exception\LocalizedException
-     */
-    protected function _setState(
-        $state,
-        $status = false,
-        $comment = '',
-        $isCustomerNotified = null,
-        $shouldProtectState = false
-    ) {
         // attempt to set the specified state
         if ($shouldProtectState) {
             if ($this->isStateProtected($state)) {
@@ -966,17 +946,32 @@ class Order extends AbstractModel implements EntityInterface, OrderInterface
                 );
             }
         }
-        $this->setData('state', $state);
+
+        $transport = new \Magento\Framework\Object(
+            [
+                'state'     => $state,
+                'status'    => $status,
+                'comment'   => $comment,
+                'is_customer_notified'    => $isCustomerNotified
+            ]
+        );
+
+        $this->_eventManager->dispatch(
+            'sales_order_state_change_before',
+            ['order' => $this, 'transport' => $transport]
+        );
+        $status = $transport->getStatus();
+        $this->setData('state', $transport->getState());
 
         // add status history
         if ($status) {
             if ($status === true) {
-                $status = $this->getConfig()->getStateDefaultStatus($state);
+                $status = $this->getConfig()->getStateDefaultStatus($transport->getState());
             }
             $this->setStatus($status);
-            $history = $this->addStatusHistoryComment($comment, false);
+            $history = $this->addStatusHistoryComment($transport->getComment(), false);
             // no sense to set $status again
-            $history->setIsCustomerNotified($isCustomerNotified);
+            $history->setIsCustomerNotified($transport->getIsCustomerNotified());
         }
         return $this;
     }
@@ -1167,7 +1162,7 @@ class Order extends AbstractModel implements EntityInterface, OrderInterface
             $this->setTotalCanceled($this->getGrandTotal() - $this->getTotalPaid());
             $this->setBaseTotalCanceled($this->getBaseGrandTotal() - $this->getBaseTotalPaid());
 
-            $this->_setState($cancelState, true, $comment);
+            $this->setState($cancelState, true, $comment, null, false);
         } elseif (!$graceful) {
             throw new \Magento\Framework\Exception\LocalizedException(__('We cannot cancel this order.'));
         }
@@ -2485,6 +2480,14 @@ class Order extends AbstractModel implements EntityInterface, OrderInterface
         return $this->getData(OrderInterface::CREATED_AT);
     }
 
+    /**
+     * {@inheritdoc}
+     */
+    public function setCreatedAt($createdAt)
+    {
+        return $this->setData(OrderInterface::CREATED_AT, $createdAt);
+    }
+
     /**
      * Returns customer_dob
      *
diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo.php b/app/code/Magento/Sales/Model/Order/Creditmemo.php
index 9e77f5afd8635e1b6421a1915684a4c0a858cbd0..7fbc58d77171b57ccf708e81a9a4ad77a827293b 100644
--- a/app/code/Magento/Sales/Model/Order/Creditmemo.php
+++ b/app/code/Magento/Sales/Model/Order/Creditmemo.php
@@ -20,7 +20,6 @@ use Magento\Sales\Model\EntityInterface;
  *
  * @method \Magento\Sales\Model\Resource\Order\Creditmemo _getResource()
  * @method \Magento\Sales\Model\Resource\Order\Creditmemo getResource()
- * @method \Magento\Sales\Model\Order\Creditmemo setCreatedAt(string $value)
  * @method \Magento\Sales\Model\Order\Invoice setSendEmail(bool $value)
  * @method \Magento\Sales\Model\Order\Invoice setCustomerNote(string $value)
  * @method string getCustomerNote()
@@ -1034,6 +1033,14 @@ class Creditmemo extends AbstractModel implements EntityInterface, CreditmemoInt
         return $this->getData(CreditmemoInterface::CREATED_AT);
     }
 
+    /**
+     * {@inheritdoc}
+     */
+    public function setCreatedAt($createdAt)
+    {
+        return $this->setData(CreditmemoInterface::CREATED_AT, $createdAt);
+    }
+
     /**
      * Returns creditmemo_status
      *
diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo/Comment.php b/app/code/Magento/Sales/Model/Order/Creditmemo/Comment.php
index a488162c322611e892d33bc90cd60be5dac7cc6f..2dac94c26b818bc2eab23acc83aea3079166a9d5 100644
--- a/app/code/Magento/Sales/Model/Order/Creditmemo/Comment.php
+++ b/app/code/Magento/Sales/Model/Order/Creditmemo/Comment.php
@@ -12,7 +12,6 @@ use Magento\Sales\Model\AbstractModel;
 /**
  * @method \Magento\Sales\Model\Resource\Order\Creditmemo\Comment _getResource()
  * @method \Magento\Sales\Model\Resource\Order\Creditmemo\Comment getResource()
- * @method \Magento\Sales\Model\Order\Creditmemo\Comment setCreatedAt(string $value)
  */
 class Comment extends AbstractModel implements CreditmemoCommentInterface
 {
@@ -126,6 +125,14 @@ class Comment extends AbstractModel implements CreditmemoCommentInterface
         return $this->getData(CreditmemoCommentInterface::CREATED_AT);
     }
 
+    /**
+     * {@inheritdoc}
+     */
+    public function setCreatedAt($createdAt)
+    {
+        return $this->setData(CreditmemoCommentInterface::CREATED_AT, $createdAt);
+    }
+
     /**
      * Returns is_customer_notified
      *
diff --git a/app/code/Magento/Sales/Model/Order/Email/Sender/CreditmemoCommentSender.php b/app/code/Magento/Sales/Model/Order/Email/Sender/CreditmemoCommentSender.php
index 2d6598ec9a830a7f0ca18a53e3291ce1446bb368..09d01d2e0a55cdf874ba8cbe9add9567998a5c5c 100644
--- a/app/code/Magento/Sales/Model/Order/Email/Sender/CreditmemoCommentSender.php
+++ b/app/code/Magento/Sales/Model/Order/Email/Sender/CreditmemoCommentSender.php
@@ -11,6 +11,7 @@ use Magento\Sales\Model\Order\Email\Container\CreditmemoCommentIdentity;
 use Magento\Sales\Model\Order\Email\Container\Template;
 use Magento\Sales\Model\Order\Email\NotifySender;
 use Magento\Sales\Model\Order\Address\Renderer;
+use Magento\Framework\Event\ManagerInterface;
 
 /**
  * Class CreditmemoCommentSender
@@ -22,22 +23,32 @@ class CreditmemoCommentSender extends NotifySender
      */
     protected $addressRenderer;
 
+    /**
+     * Application Event Dispatcher
+     *
+     * @var ManagerInterface
+     */
+    protected $eventManager;
+
     /**
      * @param Template $templateContainer
      * @param CreditmemoCommentIdentity $identityContainer
      * @param Order\Email\SenderBuilderFactory $senderBuilderFactory
      * @param \Psr\Log\LoggerInterface $logger
      * @param Renderer $addressRenderer
+     * @param ManagerInterface $eventManager
      */
     public function __construct(
         Template $templateContainer,
         CreditmemoCommentIdentity $identityContainer,
         \Magento\Sales\Model\Order\Email\SenderBuilderFactory $senderBuilderFactory,
         \Psr\Log\LoggerInterface $logger,
-        Renderer $addressRenderer
+        Renderer $addressRenderer,
+        ManagerInterface $eventManager
     ) {
         parent::__construct($templateContainer, $identityContainer, $senderBuilderFactory, $logger);
         $this->addressRenderer = $addressRenderer;
+        $this->eventManager = $eventManager;
     }
 
     /**
@@ -57,18 +68,28 @@ class CreditmemoCommentSender extends NotifySender
             $formattedShippingAddress = '';
         }
         $formattedBillingAddress = $this->addressRenderer->format($order->getBillingAddress(), 'html');
-        $this->templateContainer->setTemplateVars(
-            [
-                'order' => $order,
-                'creditmemo' => $creditmemo,
-                'comment' => $comment,
-                'billing' => $order->getBillingAddress(),
-                'store' => $order->getStore(),
-                'formattedShippingAddress' => $formattedShippingAddress,
-                'formattedBillingAddress' => $formattedBillingAddress,
+
+        $transport = new \Magento\Framework\Object(
+            ['template_vars' =>
+                 [
+                     'order'                    => $order,
+                     'creditmemo'               => $creditmemo,
+                     'comment'                  => $comment,
+                     'billing'                  => $order->getBillingAddress(),
+                     'store'                    => $order->getStore(),
+                     'formattedShippingAddress' => $formattedShippingAddress,
+                     'formattedBillingAddress'  => $formattedBillingAddress,
+                 ]
             ]
         );
 
+        $this->eventManager->dispatch(
+            'email_creditmemo_comment_set_template_vars_before',
+            ['sender' => $this, 'transport' => $transport]
+        );
+
+        $this->templateContainer->setTemplateVars($transport->getTemplateVars());
+
         return $this->checkAndSend($order, $notify);
     }
 }
diff --git a/app/code/Magento/Sales/Model/Order/Email/Sender/CreditmemoSender.php b/app/code/Magento/Sales/Model/Order/Email/Sender/CreditmemoSender.php
index e476e5ec8b544272154e907ce04cf46be2dd08ba..8bcd58fafd941a3dc185de14ac7f33b932ed2d7b 100644
--- a/app/code/Magento/Sales/Model/Order/Email/Sender/CreditmemoSender.php
+++ b/app/code/Magento/Sales/Model/Order/Email/Sender/CreditmemoSender.php
@@ -13,6 +13,7 @@ use Magento\Sales\Model\Order\Email\Container\Template;
 use Magento\Sales\Model\Order\Email\Sender;
 use Magento\Sales\Model\Resource\Order\Creditmemo as CreditmemoResource;
 use Magento\Sales\Model\Order\Address\Renderer;
+use Magento\Framework\Event\ManagerInterface;
 
 /**
  * Class CreditmemoSender
@@ -43,6 +44,13 @@ class CreditmemoSender extends Sender
      */
     protected $addressRenderer;
 
+    /**
+     * Application Event Dispatcher
+     *
+     * @var ManagerInterface
+     */
+    protected $eventManager;
+
     /**
      * @param Template $templateContainer
      * @param CreditmemoIdentity $identityContainer
@@ -52,6 +60,7 @@ class CreditmemoSender extends Sender
      * @param CreditmemoResource $creditmemoResource
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig
      * @param Renderer $addressRenderer
+     * @param ManagerInterface $eventManager
      */
     public function __construct(
         Template $templateContainer,
@@ -61,13 +70,15 @@ class CreditmemoSender extends Sender
         PaymentHelper $paymentHelper,
         CreditmemoResource $creditmemoResource,
         \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig,
-        Renderer $addressRenderer
+        Renderer $addressRenderer,
+        ManagerInterface $eventManager
     ) {
         parent::__construct($templateContainer, $identityContainer, $senderBuilderFactory, $logger);
         $this->paymentHelper = $paymentHelper;
         $this->creditmemoResource = $creditmemoResource;
         $this->globalConfig = $globalConfig;
         $this->addressRenderer = $addressRenderer;
+        $this->eventManager = $eventManager;
     }
 
     /**
@@ -100,24 +111,32 @@ class CreditmemoSender extends Sender
 
             $formattedBillingAddress = $this->addressRenderer->format($order->getBillingAddress(), 'html');
 
-            $this->templateContainer->setTemplateVars(
-                [
-                    'order' => $order,
-                    'creditmemo' => $creditmemo,
-                    'comment' => $creditmemo->getCustomerNoteNotify() ? $creditmemo->getCustomerNote() : '',
-                    'billing' => $order->getBillingAddress(),
-                    'payment_html' => $this->getPaymentHtml($order),
-                    'store' => $order->getStore(),
-                    'formattedShippingAddress' => $formattedShippingAddress,
-                    'formattedBillingAddress' => $formattedBillingAddress,
+            $transport = new \Magento\Framework\Object(
+                ['template_vars' =>
+                     [
+                         'order'                    => $order,
+                         'creditmemo'               => $creditmemo,
+                         'comment'                  => $creditmemo->getCustomerNoteNotify()
+                             ? $creditmemo->getCustomerNote() : '',
+                         'billing'                  => $order->getBillingAddress(),
+                         'payment_html'             => $this->getPaymentHtml($order),
+                         'store'                    => $order->getStore(),
+                         'formattedShippingAddress' => $formattedShippingAddress,
+                         'formattedBillingAddress'  => $formattedBillingAddress
+                     ]
                 ]
             );
 
+            $this->eventManager->dispatch(
+                'email_creditmemo_set_template_vars_before',
+                ['sender' => $this, 'transport' => $transport]
+            );
+
+            $this->templateContainer->setTemplateVars($transport->getTemplateVars());
+
             if ($this->checkAndSend($order)) {
                 $creditmemo->setEmailSent(true);
-
                 $this->creditmemoResource->saveAttribute($creditmemo, ['send_email', 'email_sent']);
-
                 return true;
             }
         }
diff --git a/app/code/Magento/Sales/Model/Order/Email/Sender/InvoiceCommentSender.php b/app/code/Magento/Sales/Model/Order/Email/Sender/InvoiceCommentSender.php
index 75529455b3f5baa8b0e5e089465de1b48e6fc2eb..b994034cf480a12c17738832e1bb44e9920be569 100644
--- a/app/code/Magento/Sales/Model/Order/Email/Sender/InvoiceCommentSender.php
+++ b/app/code/Magento/Sales/Model/Order/Email/Sender/InvoiceCommentSender.php
@@ -11,6 +11,7 @@ use Magento\Sales\Model\Order\Email\Container\Template;
 use Magento\Sales\Model\Order\Email\NotifySender;
 use Magento\Sales\Model\Order\Invoice;
 use Magento\Sales\Model\Order\Address\Renderer;
+use Magento\Framework\Event\ManagerInterface;
 
 /**
  * Class InvoiceCommentSender
@@ -22,22 +23,32 @@ class InvoiceCommentSender extends NotifySender
      */
     protected $addressRenderer;
 
+    /**
+     * Application Event Dispatcher
+     *
+     * @var ManagerInterface
+     */
+    protected $eventManager;
+
     /**
      * @param Template $templateContainer
      * @param InvoiceCommentIdentity $identityContainer
      * @param Order\Email\SenderBuilderFactory $senderBuilderFactory
      * @param \Psr\Log\LoggerInterface $logger
      * @param Renderer $addressRenderer
+     * @param ManagerInterface $eventManager
      */
     public function __construct(
         Template $templateContainer,
         InvoiceCommentIdentity $identityContainer,
         \Magento\Sales\Model\Order\Email\SenderBuilderFactory $senderBuilderFactory,
         \Psr\Log\LoggerInterface $logger,
-        Renderer $addressRenderer
+        Renderer $addressRenderer,
+        ManagerInterface $eventManager
     ) {
         parent::__construct($templateContainer, $identityContainer, $senderBuilderFactory, $logger);
         $this->addressRenderer = $addressRenderer;
+        $this->eventManager = $eventManager;
     }
 
     /**
@@ -57,17 +68,28 @@ class InvoiceCommentSender extends NotifySender
             $formattedShippingAddress = '';
         }
         $formattedBillingAddress = $this->addressRenderer->format($order->getBillingAddress(), 'html');
-        $this->templateContainer->setTemplateVars(
-            [
-                'order' => $order,
-                'invoice' => $invoice,
-                'comment' => $comment,
-                'billing' => $order->getBillingAddress(),
-                'store' => $order->getStore(),
-                'formattedShippingAddress' => $formattedShippingAddress,
-                'formattedBillingAddress' => $formattedBillingAddress,
+
+        $transport = new \Magento\Framework\Object(
+            ['template_vars' =>
+                 [
+                     'order'                    => $order,
+                     'invoice'                  => $invoice,
+                     'comment'                  => $comment,
+                     'billing'                  => $order->getBillingAddress(),
+                     'store'                    => $order->getStore(),
+                     'formattedShippingAddress' => $formattedShippingAddress,
+                     'formattedBillingAddress'  => $formattedBillingAddress,
+                 ]
             ]
         );
+
+        $this->eventManager->dispatch(
+            'email_invoice_comment_set_template_vars_before',
+            ['sender' => $this, 'transport' => $transport]
+        );
+
+        $this->templateContainer->setTemplateVars($transport->getTemplateVars());
+
         return $this->checkAndSend($order, $notify);
     }
 }
diff --git a/app/code/Magento/Sales/Model/Order/Email/Sender/InvoiceSender.php b/app/code/Magento/Sales/Model/Order/Email/Sender/InvoiceSender.php
index 0796ff0443b198be2f4f2533e825fb8eca25c2f9..d879b0f529aab42479a89acc597f14867f4268a4 100644
--- a/app/code/Magento/Sales/Model/Order/Email/Sender/InvoiceSender.php
+++ b/app/code/Magento/Sales/Model/Order/Email/Sender/InvoiceSender.php
@@ -13,6 +13,7 @@ use Magento\Sales\Model\Order\Email\Sender;
 use Magento\Sales\Model\Order\Invoice;
 use Magento\Sales\Model\Resource\Order\Invoice as InvoiceResource;
 use Magento\Sales\Model\Order\Address\Renderer;
+use Magento\Framework\Event\ManagerInterface;
 
 /**
  * Class InvoiceSender
@@ -43,6 +44,13 @@ class InvoiceSender extends Sender
      */
     protected $addressRenderer;
 
+    /**
+     * Application Event Dispatcher
+     *
+     * @var ManagerInterface
+     */
+    protected $eventManager;
+
     /**
      * @param Template $templateContainer
      * @param InvoiceIdentity $identityContainer
@@ -52,6 +60,7 @@ class InvoiceSender extends Sender
      * @param InvoiceResource $invoiceResource
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig
      * @param Renderer $addressRenderer
+     * @param ManagerInterface $eventManager
      */
     public function __construct(
         Template $templateContainer,
@@ -61,13 +70,15 @@ class InvoiceSender extends Sender
         PaymentHelper $paymentHelper,
         InvoiceResource $invoiceResource,
         \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig,
-        Renderer $addressRenderer
+        Renderer $addressRenderer,
+        ManagerInterface $eventManager
     ) {
         parent::__construct($templateContainer, $identityContainer, $senderBuilderFactory, $logger);
         $this->paymentHelper = $paymentHelper;
         $this->invoiceResource = $invoiceResource;
         $this->globalConfig = $globalConfig;
         $this->addressRenderer = $addressRenderer;
+        $this->eventManager = $eventManager;
     }
 
     /**
@@ -98,25 +109,33 @@ class InvoiceSender extends Sender
                 $formattedShippingAddress = '';
             }
             $formattedBillingAddress = $this->addressRenderer->format($order->getBillingAddress(), 'html');
-            
-            $this->templateContainer->setTemplateVars(
-                [
-                    'order' => $order,
-                    'invoice' => $invoice,
-                    'comment' => $invoice->getCustomerNoteNotify() ? $invoice->getCustomerNote() : '',
-                    'billing' => $order->getBillingAddress(),
-                    'payment_html' => $this->getPaymentHtml($order),
-                    'store' => $order->getStore(),
-                    'formattedShippingAddress' => $formattedShippingAddress,
-                    'formattedBillingAddress' => $formattedBillingAddress
+
+            $transport = new \Magento\Framework\Object(
+                ['template_vars' =>
+                     [
+                         'order'                    => $order,
+                         'invoice'                  => $invoice,
+                         'comment'                  => $invoice->getCustomerNoteNotify() ? $invoice->getCustomerNote()
+                             : '',
+                         'billing'                  => $order->getBillingAddress(),
+                         'payment_html'             => $this->getPaymentHtml($order),
+                         'store'                    => $order->getStore(),
+                         'formattedShippingAddress' => $formattedShippingAddress,
+                         'formattedBillingAddress'  => $formattedBillingAddress
+                     ]
                 ]
             );
 
+            $this->eventManager->dispatch(
+                'email_invoice_set_template_vars_before',
+                ['sender' => $this, 'transport' => $transport]
+            );
+
+            $this->templateContainer->setTemplateVars($transport->getTemplateVars());
+
             if ($this->checkAndSend($order)) {
                 $invoice->setEmailSent(true);
-
                 $this->invoiceResource->saveAttribute($invoice, ['send_email', 'email_sent']);
-
                 return true;
             }
         }
diff --git a/app/code/Magento/Sales/Model/Order/Email/Sender/OrderCommentSender.php b/app/code/Magento/Sales/Model/Order/Email/Sender/OrderCommentSender.php
index 10abfd138dcc392e9e953ef613214bf28949bdb5..64f67cb80ce8f98b8fc07de60fc5a48efeae534e 100644
--- a/app/code/Magento/Sales/Model/Order/Email/Sender/OrderCommentSender.php
+++ b/app/code/Magento/Sales/Model/Order/Email/Sender/OrderCommentSender.php
@@ -10,6 +10,7 @@ use Magento\Sales\Model\Order\Email\Container\OrderCommentIdentity;
 use Magento\Sales\Model\Order\Email\Container\Template;
 use Magento\Sales\Model\Order\Email\NotifySender;
 use Magento\Sales\Model\Order\Address\Renderer;
+use Magento\Framework\Event\ManagerInterface;
 
 /**
  * Class OrderCommentSender
@@ -21,22 +22,32 @@ class OrderCommentSender extends NotifySender
      */
     protected $addressRenderer;
 
+    /**
+     * Application Event Dispatcher
+     *
+     * @var ManagerInterface
+     */
+    protected $eventManager;
+
     /**
      * @param Template $templateContainer
      * @param OrderCommentIdentity $identityContainer
      * @param Order\Email\SenderBuilderFactory $senderBuilderFactory
      * @param \Psr\Log\LoggerInterface $logger
      * @param Renderer $addressRenderer
+     * @param ManagerInterface $eventManager
      */
     public function __construct(
         Template $templateContainer,
         OrderCommentIdentity $identityContainer,
         \Magento\Sales\Model\Order\Email\SenderBuilderFactory $senderBuilderFactory,
         \Psr\Log\LoggerInterface $logger,
-        Renderer $addressRenderer
+        Renderer $addressRenderer,
+        ManagerInterface $eventManager
     ) {
         parent::__construct($templateContainer, $identityContainer, $senderBuilderFactory, $logger);
         $this->addressRenderer = $addressRenderer;
+        $this->eventManager = $eventManager;
     }
 
     /**
@@ -55,16 +66,27 @@ class OrderCommentSender extends NotifySender
             $formattedShippingAddress = '';
         }
         $formattedBillingAddress = $this->addressRenderer->format($order->getBillingAddress(), 'html');
-        $this->templateContainer->setTemplateVars(
-            [
-                'order' => $order,
-                'comment' => $comment,
-                'billing' => $order->getBillingAddress(),
-                'store' => $order->getStore(),
-                'formattedShippingAddress' => $formattedShippingAddress,
-                'formattedBillingAddress' => $formattedBillingAddress,
+
+        $transport = new \Magento\Framework\Object(
+            ['template_vars' =>
+                 [
+                     'order'                    => $order,
+                     'comment'                  => $comment,
+                     'billing'                  => $order->getBillingAddress(),
+                     'store'                    => $order->getStore(),
+                     'formattedShippingAddress' => $formattedShippingAddress,
+                     'formattedBillingAddress'  => $formattedBillingAddress,
+                 ]
             ]
         );
+
+        $this->eventManager->dispatch(
+            'email_order_comment_set_template_vars_before',
+            ['sender' => $this, 'transport' => $transport]
+        );
+
+        $this->templateContainer->setTemplateVars($transport->getTemplateVars());
+
         return $this->checkAndSend($order, $notify);
     }
 }
diff --git a/app/code/Magento/Sales/Model/Order/Email/Sender/OrderSender.php b/app/code/Magento/Sales/Model/Order/Email/Sender/OrderSender.php
index dc2d544d335bd35b9aa5c81327f272bb2c927872..59c7e404c940a55abd252ae429a572e0d8b45c66 100644
--- a/app/code/Magento/Sales/Model/Order/Email/Sender/OrderSender.php
+++ b/app/code/Magento/Sales/Model/Order/Email/Sender/OrderSender.php
@@ -12,9 +12,11 @@ use Magento\Sales\Model\Order\Email\Container\Template;
 use Magento\Sales\Model\Order\Email\Sender;
 use Magento\Sales\Model\Resource\Order as OrderResource;
 use Magento\Sales\Model\Order\Address\Renderer;
+use Magento\Framework\Event\ManagerInterface;
 
 /**
  * Class OrderSender
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
 class OrderSender extends Sender
 {
@@ -40,6 +42,13 @@ class OrderSender extends Sender
      */
     protected $addressRenderer;
 
+    /**
+     * Application Event Dispatcher
+     *
+     * @var ManagerInterface
+     */
+    protected $eventManager;
+
     /**
      * @param Template $templateContainer
      * @param OrderIdentity $identityContainer
@@ -49,6 +58,7 @@ class OrderSender extends Sender
      * @param OrderResource $orderResource
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig
      * @param Renderer $addressRenderer
+     * @param ManagerInterface $eventManager
      */
     public function __construct(
         Template $templateContainer,
@@ -58,13 +68,15 @@ class OrderSender extends Sender
         PaymentHelper $paymentHelper,
         OrderResource $orderResource,
         \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig,
-        Renderer $addressRenderer
+        Renderer $addressRenderer,
+        ManagerInterface $eventManager
     ) {
         parent::__construct($templateContainer, $identityContainer, $senderBuilderFactory, $logger);
         $this->paymentHelper = $paymentHelper;
         $this->orderResource = $orderResource;
         $this->globalConfig = $globalConfig;
         $this->addressRenderer = $addressRenderer;
+        $this->eventManager = $eventManager;
     }
 
     /**
@@ -89,9 +101,7 @@ class OrderSender extends Sender
         if (!$this->globalConfig->getValue('sales_email/general/async_sending') || $forceSyncMode) {
             if ($this->checkAndSend($order)) {
                 $order->setEmailSent(true);
-
                 $this->orderResource->saveAttribute($order, ['send_email', 'email_sent']);
-
                 return true;
             }
         }
@@ -109,16 +119,26 @@ class OrderSender extends Sender
      */
     protected function prepareTemplate(Order $order)
     {
-        $this->templateContainer->setTemplateVars(
-            [
-                'order' => $order,
-                'billing' => $order->getBillingAddress(),
-                'payment_html' => $this->getPaymentHtml($order),
-                'store' => $order->getStore(),
-                'formattedShippingAddress' => $this->addressRenderer->format($order->getShippingAddress(), 'html'),
-                'formattedBillingAddress' => $this->addressRenderer->format($order->getBillingAddress(), 'html'),
+        $transport = new \Magento\Framework\Object(
+            ['template_vars' =>
+                 [
+                     'order'                    => $order,
+                     'billing'                  => $order->getBillingAddress(),
+                     'payment_html'             => $this->getPaymentHtml($order),
+                     'store'                    => $order->getStore(),
+                     'formattedShippingAddress' => $this->addressRenderer->format($order->getShippingAddress(), 'html'),
+                     'formattedBillingAddress'  => $this->addressRenderer->format($order->getBillingAddress(), 'html'),
+                 ]
             ]
         );
+
+        $this->eventManager->dispatch(
+            'email_order_set_template_vars_before',
+            ['sender' => $this, 'transport' => $transport]
+        );
+
+        $this->templateContainer->setTemplateVars($transport->getTemplateVars());
+
         parent::prepareTemplate($order);
     }
 
diff --git a/app/code/Magento/Sales/Model/Order/Email/Sender/ShipmentCommentSender.php b/app/code/Magento/Sales/Model/Order/Email/Sender/ShipmentCommentSender.php
index 1173cc951fe6455e4ddd0829d6a31e2274b6c7ca..d3555b8240b9a27934f0bbc6144d64db0a2ba563 100644
--- a/app/code/Magento/Sales/Model/Order/Email/Sender/ShipmentCommentSender.php
+++ b/app/code/Magento/Sales/Model/Order/Email/Sender/ShipmentCommentSender.php
@@ -11,6 +11,7 @@ use Magento\Sales\Model\Order\Email\Container\Template;
 use Magento\Sales\Model\Order\Email\NotifySender;
 use Magento\Sales\Model\Order\Shipment;
 use Magento\Sales\Model\Order\Address\Renderer;
+use Magento\Framework\Event\ManagerInterface;
 
 /**
  * Class ShipmentCommentSender
@@ -22,22 +23,32 @@ class ShipmentCommentSender extends NotifySender
      */
     protected $addressRenderer;
 
+    /**
+     * Application Event Dispatcher
+     *
+     * @var ManagerInterface
+     */
+    protected $eventManager;
+
     /**
      * @param Template $templateContainer
      * @param ShipmentCommentIdentity $identityContainer
      * @param Order\Email\SenderBuilderFactory $senderBuilderFactory
      * @param \Psr\Log\LoggerInterface $logger
      * @param Renderer $addressRenderer
+     * @param ManagerInterface $eventManager
      */
     public function __construct(
         Template $templateContainer,
         ShipmentCommentIdentity $identityContainer,
         \Magento\Sales\Model\Order\Email\SenderBuilderFactory $senderBuilderFactory,
         \Psr\Log\LoggerInterface $logger,
-        Renderer $addressRenderer
+        Renderer $addressRenderer,
+        ManagerInterface $eventManager
     ) {
         parent::__construct($templateContainer, $identityContainer, $senderBuilderFactory, $logger);
         $this->addressRenderer = $addressRenderer;
+        $this->eventManager = $eventManager;
     }
 
     /**
@@ -57,17 +68,28 @@ class ShipmentCommentSender extends NotifySender
             $formattedShippingAddress = '';
         }
         $formattedBillingAddress = $this->addressRenderer->format($order->getBillingAddress(), 'html');
-        $this->templateContainer->setTemplateVars(
-            [
-                'order' => $order,
-                'shipment' => $shipment,
-                'comment' => $comment,
-                'billing' => $order->getBillingAddress(),
-                'store' => $order->getStore(),
-                'formattedShippingAddress' => $formattedShippingAddress,
-                'formattedBillingAddress' => $formattedBillingAddress,
+
+        $transport = new \Magento\Framework\Object(
+            ['template_vars' =>
+                 [
+                     'order'                    => $order,
+                     'shipment'                 => $shipment,
+                     'comment'                  => $comment,
+                     'billing'                  => $order->getBillingAddress(),
+                     'store'                    => $order->getStore(),
+                     'formattedShippingAddress' => $formattedShippingAddress,
+                     'formattedBillingAddress'  => $formattedBillingAddress,
+                 ]
             ]
         );
+
+        $this->eventManager->dispatch(
+            'email_shipment_comment_set_template_vars_before',
+            ['sender' => $this, 'transport' => $transport]
+        );
+
+        $this->templateContainer->setTemplateVars($transport->getTemplateVars());
+
         return $this->checkAndSend($order, $notify);
     }
 }
diff --git a/app/code/Magento/Sales/Model/Order/Email/Sender/ShipmentSender.php b/app/code/Magento/Sales/Model/Order/Email/Sender/ShipmentSender.php
index cedd82ae34d6426ed8fff4d60ff9a48565b8ca20..96a62f88588435d2695a8e97c1a466aa161d4986 100644
--- a/app/code/Magento/Sales/Model/Order/Email/Sender/ShipmentSender.php
+++ b/app/code/Magento/Sales/Model/Order/Email/Sender/ShipmentSender.php
@@ -13,10 +13,11 @@ use Magento\Sales\Model\Order\Email\Sender;
 use Magento\Sales\Model\Order\Shipment;
 use Magento\Sales\Model\Resource\Order\Shipment as ShipmentResource;
 use Magento\Sales\Model\Order\Address\Renderer;
+use Magento\Framework\Event\ManagerInterface;
 
 /**
  * Class ShipmentSender
- * 
+ *
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
 class ShipmentSender extends Sender
@@ -43,6 +44,13 @@ class ShipmentSender extends Sender
      */
     protected $addressRenderer;
 
+    /**
+     * Application Event Dispatcher
+     *
+     * @var ManagerInterface
+     */
+    protected $eventManager;
+
     /**
      * @param Template $templateContainer
      * @param ShipmentIdentity $identityContainer
@@ -52,6 +60,7 @@ class ShipmentSender extends Sender
      * @param ShipmentResource $shipmentResource
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig
      * @param Renderer $addressRenderer
+     * @param ManagerInterface $eventManager
      */
     public function __construct(
         Template $templateContainer,
@@ -61,13 +70,15 @@ class ShipmentSender extends Sender
         PaymentHelper $paymentHelper,
         ShipmentResource $shipmentResource,
         \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig,
-        Renderer $addressRenderer
+        Renderer $addressRenderer,
+        ManagerInterface $eventManager
     ) {
         parent::__construct($templateContainer, $identityContainer, $senderBuilderFactory, $logger);
         $this->paymentHelper = $paymentHelper;
         $this->shipmentResource = $shipmentResource;
         $this->globalConfig = $globalConfig;
         $this->addressRenderer = $addressRenderer;
+        $this->eventManager = $eventManager;
     }
 
     /**
@@ -99,24 +110,33 @@ class ShipmentSender extends Sender
             }
             $formattedBillingAddress = $this->addressRenderer->format($order->getBillingAddress(), 'html');
 
-            $this->templateContainer->setTemplateVars(
-                [
-                    'order' => $order,
-                    'shipment' => $shipment,
-                    'comment' => $shipment->getCustomerNoteNotify() ? $shipment->getCustomerNote() : '',
-                    'billing' => $order->getBillingAddress(),
-                    'payment_html' => $this->getPaymentHtml($order),
-                    'store' => $order->getStore(),
-                    'formattedShippingAddress' => $formattedShippingAddress,
-                    'formattedBillingAddress' => $formattedBillingAddress
+            $transport = new \Magento\Framework\Object(
+                ['template_vars' =>
+                     [
+                         'order'                    => $order,
+                         'shipment'                 => $shipment,
+                         'comment'                  => $shipment->getCustomerNoteNotify()
+                             ? $shipment->getCustomerNote()
+                             : '',
+                         'billing'                  => $order->getBillingAddress(),
+                         'payment_html'             => $this->getPaymentHtml($order),
+                         'store'                    => $order->getStore(),
+                         'formattedShippingAddress' => $formattedShippingAddress,
+                         'formattedBillingAddress'  => $formattedBillingAddress
+                     ]
                 ]
             );
 
+            $this->eventManager->dispatch(
+                'email_shipment_set_template_vars_before',
+                ['sender' => $this, 'transport' => $transport]
+            );
+
+            $this->templateContainer->setTemplateVars($transport->getTemplateVars());
+
             if ($this->checkAndSend($order)) {
                 $shipment->setEmailSent(true);
-
                 $this->shipmentResource->saveAttribute($shipment, ['send_email', 'email_sent']);
-
                 return true;
             }
         }
diff --git a/app/code/Magento/Sales/Model/Order/Invoice.php b/app/code/Magento/Sales/Model/Order/Invoice.php
index 8317b7041d61f3e747af2b644050854b3b55174d..036aec685121162933181a05e6c66af57af6d58c 100644
--- a/app/code/Magento/Sales/Model/Order/Invoice.php
+++ b/app/code/Magento/Sales/Model/Order/Invoice.php
@@ -11,7 +11,6 @@ use Magento\Sales\Model\AbstractModel;
 use Magento\Sales\Model\EntityInterface;
 
 /**
- * @method \Magento\Sales\Model\Order\Invoice setCreatedAt(string $value)
  * @method \Magento\Sales\Model\Order\Invoice setSendEmail(bool $value)
  * @method \Magento\Sales\Model\Order\Invoice setCustomerNote(string $value)
  * @method string getCustomerNote()
@@ -969,6 +968,14 @@ class Invoice extends AbstractModel implements EntityInterface, InvoiceInterface
         return $this->getData(InvoiceInterface::CREATED_AT);
     }
 
+    /**
+     * {@inheritdoc}
+     */
+    public function setCreatedAt($createdAt)
+    {
+        return $this->setData(InvoiceInterface::CREATED_AT, $createdAt);
+    }
+
     /**
      * Returns discount_amount
      *
diff --git a/app/code/Magento/Sales/Model/Order/Invoice/Comment.php b/app/code/Magento/Sales/Model/Order/Invoice/Comment.php
index 074e77b3638e656906f3da22e3727cea61423e98..e7b99dea1593ed699d4f76e6f745256f780e8075 100644
--- a/app/code/Magento/Sales/Model/Order/Invoice/Comment.php
+++ b/app/code/Magento/Sales/Model/Order/Invoice/Comment.php
@@ -12,7 +12,6 @@ use Magento\Sales\Model\AbstractModel;
 /**
  * @method \Magento\Sales\Model\Resource\Order\Invoice\Comment _getResource()
  * @method \Magento\Sales\Model\Resource\Order\Invoice\Comment getResource()
- * @method \Magento\Sales\Model\Order\Invoice\Comment setCreatedAt(string $value)
  */
 class Comment extends AbstractModel implements InvoiceCommentInterface
 {
@@ -126,6 +125,14 @@ class Comment extends AbstractModel implements InvoiceCommentInterface
         return $this->getData(InvoiceCommentInterface::CREATED_AT);
     }
 
+    /**
+     * {@inheritdoc}
+     */
+    public function setCreatedAt($createdAt)
+    {
+        return $this->setData(InvoiceCommentInterface::CREATED_AT, $createdAt);
+    }
+
     /**
      * Returns is_customer_notified
      *
diff --git a/app/code/Magento/Sales/Model/Order/Item.php b/app/code/Magento/Sales/Model/Order/Item.php
index b23a34296c690d5584dc2a6e314401669981bd3a..602cde0a32e3ccbbc03195aa4933e4fdb81b3079 100644
--- a/app/code/Magento/Sales/Model/Order/Item.php
+++ b/app/code/Magento/Sales/Model/Order/Item.php
@@ -14,7 +14,6 @@ use Magento\Sales\Api\Data\OrderItemInterface;
  *
  * @method \Magento\Sales\Model\Resource\Order\Item _getResource()
  * @method \Magento\Sales\Model\Resource\Order\Item getResource()
- * @method \Magento\Sales\Model\Order\Item setCreatedAt(string $value)
  * @method int getGiftMessageId()
  * @method \Magento\Sales\Model\Order\Item setGiftMessageId(int $value)
  * @method int getGiftMessageAvailable()
@@ -949,6 +948,14 @@ class Item extends AbstractModel implements OrderItemInterface
         return $this->getData(OrderItemInterface::CREATED_AT);
     }
 
+    /**
+     * {@inheritdoc}
+     */
+    public function setCreatedAt($createdAt)
+    {
+        return $this->setData(OrderItemInterface::CREATED_AT, $createdAt);
+    }
+
     /**
      * Returns description
      *
diff --git a/app/code/Magento/Sales/Model/Order/Payment/Transaction.php b/app/code/Magento/Sales/Model/Order/Payment/Transaction.php
index 3c0d281f3e27cd8630d0471e6e8f505c29f6b10c..16cc9b45365adec1da8225d0c7ef6cd27ba813f1 100644
--- a/app/code/Magento/Sales/Model/Order/Payment/Transaction.php
+++ b/app/code/Magento/Sales/Model/Order/Payment/Transaction.php
@@ -19,7 +19,6 @@ use Magento\Sales\Model\AbstractModel;
  *
  * @method \Magento\Sales\Model\Resource\Order\Payment\Transaction _getResource()
  * @method \Magento\Sales\Model\Resource\Order\Payment\Transaction getResource()
- * @method \Magento\Sales\Model\Order\Payment\Transaction setCreatedAt(string $value)
 
  * @author      Magento Core Team <core@magentocommerce.com>
  * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
@@ -922,6 +921,14 @@ class Transaction extends AbstractModel implements TransactionInterface
         return $this->getData(TransactionInterface::TRANSACTION_ID);
     }
 
+    /**
+     * {@inheritdoc}
+     */
+    public function setTransactionId($id)
+    {
+        return $this->setData(TransactionInterface::TRANSACTION_ID, $id);
+    }
+
     /**
      * Returns method
      *
@@ -1002,8 +1009,9 @@ class Transaction extends AbstractModel implements TransactionInterface
         return $this->getData(TransactionInterface::IS_CLOSED);
     }
 
+    //@codeCoverageIgnoreStart
     /**
-     * Returns created_at
+     * Gets the created-at timestamp for the transaction.
      *
      * @return string
      */
@@ -1012,7 +1020,14 @@ class Transaction extends AbstractModel implements TransactionInterface
         return $this->getData(TransactionInterface::CREATED_AT);
     }
 
-    //@codeCoverageIgnoreStart
+    /**
+     * {@inheritdoc}
+     */
+    public function setCreatedAt($createdAt)
+    {
+        return $this->setData(TransactionInterface::CREATED_AT, $createdAt);
+    }
+
     /**
      * {@inheritdoc}
      */
diff --git a/app/code/Magento/Sales/Model/Order/Shipment.php b/app/code/Magento/Sales/Model/Order/Shipment.php
index 3472e9663ad337ceb64c7399b06a60e389883708..6763a4895dfe30891530cdeb2c25a61e47047c14 100644
--- a/app/code/Magento/Sales/Model/Order/Shipment.php
+++ b/app/code/Magento/Sales/Model/Order/Shipment.php
@@ -15,7 +15,6 @@ use Magento\Sales\Model\EntityInterface;
  *
  * @method \Magento\Sales\Model\Resource\Order\Shipment _getResource()
  * @method \Magento\Sales\Model\Resource\Order\Shipment getResource()
- * @method \Magento\Sales\Model\Order\Shipment setCreatedAt(string $value)
  * @method \Magento\Sales\Model\Order\Invoice setSendEmail(bool $value)
  * @method \Magento\Sales\Model\Order\Invoice setCustomerNote(string $value)
  * @method string getCustomerNote()
@@ -626,6 +625,14 @@ class Shipment extends AbstractModel implements EntityInterface, ShipmentInterfa
         return $this->getData(ShipmentInterface::CREATED_AT);
     }
 
+    /**
+     * {@inheritdoc}
+     */
+    public function setCreatedAt($createdAt)
+    {
+        return $this->setData(ShipmentInterface::CREATED_AT, $createdAt);
+    }
+
     /**
      * Returns customer_id
      *
diff --git a/app/code/Magento/Sales/Model/Order/Shipment/Comment.php b/app/code/Magento/Sales/Model/Order/Shipment/Comment.php
index 43361d79d59c4a4b6e403a7b0c7677ba1dbc1784..d1e9a5ac880bce77a0cef548f077e6e09ce754e7 100644
--- a/app/code/Magento/Sales/Model/Order/Shipment/Comment.php
+++ b/app/code/Magento/Sales/Model/Order/Shipment/Comment.php
@@ -12,7 +12,6 @@ use Magento\Sales\Model\AbstractModel;
 /**
  * @method \Magento\Sales\Model\Resource\Order\Shipment\Comment _getResource()
  * @method \Magento\Sales\Model\Resource\Order\Shipment\Comment getResource()
- * @method \Magento\Sales\Model\Order\Shipment\Comment setCreatedAt(string $value)
  */
 class Comment extends AbstractModel implements ShipmentCommentInterface
 {
@@ -126,6 +125,14 @@ class Comment extends AbstractModel implements ShipmentCommentInterface
         return $this->getData(ShipmentCommentInterface::CREATED_AT);
     }
 
+    /**
+     * {@inheritdoc}
+     */
+    public function setCreatedAt($createdAt)
+    {
+        return $this->setData(ShipmentCommentInterface::CREATED_AT, $createdAt);
+    }
+
     /**
      * Returns is_customer_notified
      *
diff --git a/app/code/Magento/Sales/Model/Order/Shipment/Track.php b/app/code/Magento/Sales/Model/Order/Shipment/Track.php
index 325c9837bee51bc906c55afdc3d172c9da8966f3..f5b15181cb8fcb89a5ddb301b28a4290573010ec 100644
--- a/app/code/Magento/Sales/Model/Order/Shipment/Track.php
+++ b/app/code/Magento/Sales/Model/Order/Shipment/Track.php
@@ -12,7 +12,6 @@ use Magento\Sales\Model\AbstractModel;
 /**
  * @method \Magento\Sales\Model\Resource\Order\Shipment\Track _getResource()
  * @method \Magento\Sales\Model\Resource\Order\Shipment\Track getResource()
- * @method \Magento\Sales\Model\Order\Shipment\Track setCreatedAt(string $value)
  *
  * @author      Magento Core Team <core@magentocommerce.com>
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
@@ -232,6 +231,14 @@ class Track extends AbstractModel implements ShipmentTrackInterface
         return $this->getData(ShipmentTrackInterface::CREATED_AT);
     }
 
+    /**
+     * {@inheritdoc}
+     */
+    public function setCreatedAt($createdAt)
+    {
+        return $this->setData(ShipmentTrackInterface::CREATED_AT, $createdAt);
+    }
+
     /**
      * Returns description
      *
diff --git a/app/code/Magento/Sales/Model/Order/Status/History.php b/app/code/Magento/Sales/Model/Order/Status/History.php
index edd828956c8241f11fcc8d929f4618a36d75e858..b442ebba05f7df7af8691e42949e79c174b0cb74 100644
--- a/app/code/Magento/Sales/Model/Order/Status/History.php
+++ b/app/code/Magento/Sales/Model/Order/Status/History.php
@@ -14,7 +14,6 @@ use Magento\Sales\Model\AbstractModel;
  *
  * @method \Magento\Sales\Model\Resource\Order\Status\History _getResource()
  * @method \Magento\Sales\Model\Resource\Order\Status\History getResource()
- * @method \Magento\Sales\Model\Order\Status\History setCreatedAt(string $value)
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
 class History extends AbstractModel implements OrderStatusHistoryInterface
@@ -196,6 +195,14 @@ class History extends AbstractModel implements OrderStatusHistoryInterface
         return $this->getData(OrderStatusHistoryInterface::CREATED_AT);
     }
 
+    /**
+     * {@inheritdoc}
+     */
+    public function setCreatedAt($createdAt)
+    {
+        return $this->setData(OrderStatusHistoryInterface::CREATED_AT, $createdAt);
+    }
+
     /**
      * Returns entity_id
      *
diff --git a/app/code/Magento/Sales/Test/Unit/Model/Config/Backend/Email/AsyncSendingTest.php b/app/code/Magento/Sales/Test/Unit/Model/Config/Backend/Email/AsyncSendingTest.php
index 69f3f6e0df310d27dc7c7c6774ad5a62ca1e82cb..9359af03ee68dfcb020c7e7ed1a9923bd4d456ec 100644
--- a/app/code/Magento/Sales/Test/Unit/Model/Config/Backend/Email/AsyncSendingTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Model/Config/Backend/Email/AsyncSendingTest.php
@@ -63,7 +63,7 @@ class AsyncSendingTest extends \PHPUnit_Framework_TestCase
     public function testAfterSave($value, $oldValue, $eventName)
     {
         $path = 'sales_email/general/async_sending';
-        $scope = \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT;
+        $scope = \Magento\Framework\App\Config\ScopeConfigInterface::SCOPE_TYPE_DEFAULT;
 
         $this->object->setData(['value' => $value, 'path' => $path, 'scope' => $scope]);
 
diff --git a/app/code/Magento/Sales/Test/Unit/Model/Config/Backend/Grid/AsyncIndexingTest.php b/app/code/Magento/Sales/Test/Unit/Model/Config/Backend/Grid/AsyncIndexingTest.php
index 972cfae38e2ae4273235a2c7a7d1ac260b4f45a3..729c19940ccff8b5f464eeeb895bc74e5aeafa16 100644
--- a/app/code/Magento/Sales/Test/Unit/Model/Config/Backend/Grid/AsyncIndexingTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Model/Config/Backend/Grid/AsyncIndexingTest.php
@@ -63,7 +63,7 @@ class AsyncIndexingTest extends \PHPUnit_Framework_TestCase
     public function testAfterSave($value, $oldValue, $eventName)
     {
         $path = 'dev/grid/async_indexing';
-        $scope = \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT;
+        $scope = \Magento\Framework\App\Config\ScopeConfigInterface::SCOPE_TYPE_DEFAULT;
 
         $this->object->setData(['value' => $value, 'path' => $path, 'scope' => $scope]);
 
diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/AbstractSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/AbstractSenderTest.php
index cd70e51424497d16585475b55edaab6d526e7cef..63ef953d756f00967ade66140431bef520989812 100644
--- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/AbstractSenderTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/AbstractSenderTest.php
@@ -62,6 +62,11 @@ abstract class AbstractSenderTest extends \PHPUnit_Framework_TestCase
      */
     protected $addressMock;
 
+    /**
+     * @var \Magento\Framework\Event\Manager | \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $eventManagerMock;
+
     /**
      * @var \PHPUnit_Framework_MockObject_MockObject
      */
@@ -128,6 +133,7 @@ abstract class AbstractSenderTest extends \PHPUnit_Framework_TestCase
 
         $this->addressRenderer = $this->getMock('Magento\Sales\Model\Order\Address\Renderer', [], [], '', false);
         $this->addressMock = $this->getMock('Magento\Sales\Model\Order\Address', [], [], '', false);
+        $this->eventManagerMock = $this->getMock('Magento\Framework\Event\Manager', [], [], '', false);
 
         $this->paymentHelper = $this->getMock('\Magento\Payment\Helper\Data', ['getInfoBlockHtml'], [], '', false);
         $this->paymentHelper->expects($this->any())
diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/CreditmemoCommentSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/CreditmemoCommentSenderTest.php
index 977ded72038ee29f205fa6981c1f534dfdae6120..fe968f3f76438091ba4fb4d99e0901c0c1d6ebc1 100644
--- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/CreditmemoCommentSenderTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/CreditmemoCommentSenderTest.php
@@ -45,7 +45,8 @@ class CreditmemoCommentSenderTest extends AbstractSenderTest
             $this->identityContainerMock,
             $this->senderBuilderFactoryMock,
             $this->loggerMock,
-            $this->addressRenderer
+            $this->addressRenderer,
+            $this->eventManagerMock
         );
     }
 
diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/CreditmemoSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/CreditmemoSenderTest.php
index cfe7bfc22e54f51db6edc23e02859488612fd11b..c42216226dae0a6f5fe4df3b75de089ff8229532 100644
--- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/CreditmemoSenderTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/CreditmemoSenderTest.php
@@ -73,7 +73,8 @@ class CreditmemoSenderTest extends AbstractSenderTest
             $this->paymentHelper,
             $this->creditmemoResourceMock,
             $this->globalConfig,
-            $this->addressRenderer
+            $this->addressRenderer,
+            $this->eventManagerMock
         );
     }
 
diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/InvoiceCommentSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/InvoiceCommentSenderTest.php
index 30b838341b5ce16a3d733839f911ee1014c2ccfe..4670ec2824ecb03e26ba446871b1cb7e24c0c28d 100644
--- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/InvoiceCommentSenderTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/InvoiceCommentSenderTest.php
@@ -61,7 +61,8 @@ class InvoiceCommentSenderTest extends AbstractSenderTest
             $this->identityContainerMock,
             $this->senderBuilderFactoryMock,
             $this->loggerMock,
-            $this->addressRenderer
+            $this->addressRenderer,
+            $this->eventManagerMock
         );
     }
 
diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/InvoiceSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/InvoiceSenderTest.php
index 35cb0e84b6566f2e74c0f17f20d918e8a88945a9..8ca7f14f25b291edbd91de51f28540ea4a48c8db 100644
--- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/InvoiceSenderTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/InvoiceSenderTest.php
@@ -73,7 +73,8 @@ class InvoiceSenderTest extends AbstractSenderTest
             $this->paymentHelper,
             $this->invoiceResourceMock,
             $this->globalConfig,
-            $this->addressRenderer
+            $this->addressRenderer,
+            $this->eventManagerMock
         );
     }
 
diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/OrderCommentSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/OrderCommentSenderTest.php
index 9bb5745162152cf85610abaa6cd8af1564586c7d..3b7c92d55986fb7f5435f7210c25b0d412b85e5e 100644
--- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/OrderCommentSenderTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/OrderCommentSenderTest.php
@@ -24,7 +24,8 @@ class OrderCommentSenderTest extends AbstractSenderTest
             $this->identityContainerMock,
             $this->senderBuilderFactoryMock,
             $this->loggerMock,
-            $this->addressRenderer
+            $this->addressRenderer,
+            $this->eventManagerMock
         );
     }
 
diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/OrderSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/OrderSenderTest.php
index 5350c1924f023c6055e59eec341cb024acb687ca..7de676a36f9281413f0d008e44de723d0de385f5 100644
--- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/OrderSenderTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/OrderSenderTest.php
@@ -50,7 +50,8 @@ class OrderSenderTest extends AbstractSenderTest
             $this->paymentHelper,
             $this->orderResourceMock,
             $this->globalConfig,
-            $this->addressRenderer
+            $this->addressRenderer,
+            $this->eventManagerMock
         );
     }
 
diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/ShipmentCommentSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/ShipmentCommentSenderTest.php
index 0a69bb2fcf85d7eae3c0f0841ee17be8afdd1221..7351b1444b6691440f087a99ed05fdb2db6b00e8 100644
--- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/ShipmentCommentSenderTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/ShipmentCommentSenderTest.php
@@ -43,7 +43,8 @@ class ShipmentCommentSenderTest extends AbstractSenderTest
             $this->identityContainerMock,
             $this->senderBuilderFactoryMock,
             $this->loggerMock,
-            $this->addressRenderer
+            $this->addressRenderer,
+            $this->eventManagerMock
         );
     }
 
diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/ShipmentSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/ShipmentSenderTest.php
index a13619f0423eaaa9a0f0ee3636c0c999454a0a9c..89fab376003d21eb36bf6c702785584abab2a861 100644
--- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/ShipmentSenderTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/ShipmentSenderTest.php
@@ -73,7 +73,8 @@ class ShipmentSenderTest extends AbstractSenderTest
             $this->paymentHelper,
             $this->shipmentResourceMock,
             $this->globalConfig,
-            $this->addressRenderer
+            $this->addressRenderer,
+            $this->eventManagerMock
         );
     }
 
diff --git a/app/code/Magento/Sales/composer.json b/app/code/Magento/Sales/composer.json
index 482c2576832b49f12c0e42710c10efb31c419643..d975eed1fc1cf27009dcfa90d0ed6bf5603bd535 100644
--- a/app/code/Magento/Sales/composer.json
+++ b/app/code/Magento/Sales/composer.json
@@ -3,35 +3,35 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/module-customer": "0.74.0-beta6",
-        "magento/module-authorization": "0.74.0-beta6",
-        "magento/module-payment": "0.74.0-beta6",
-        "magento/module-checkout": "0.74.0-beta6",
-        "magento/module-theme": "0.74.0-beta6",
-        "magento/module-sales-rule": "0.74.0-beta6",
-        "magento/module-sales-sequence": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-widget": "0.74.0-beta6",
-        "magento/module-directory": "0.74.0-beta6",
-        "magento/module-eav": "0.74.0-beta6",
-        "magento/module-tax": "0.74.0-beta6",
-        "magento/module-gift-message": "0.74.0-beta6",
-        "magento/module-reports": "0.74.0-beta6",
-        "magento/module-catalog-inventory": "0.74.0-beta6",
-        "magento/module-wishlist": "0.74.0-beta6",
-        "magento/module-email": "0.74.0-beta6",
-        "magento/module-shipping": "0.74.0-beta6",
-        "magento/module-config": "0.74.0-beta6",
-        "magento/module-media-storage": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
-        "magento/module-ui": "0.74.0-beta6",
-        "magento/module-quote": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/module-customer": "0.74.0-beta7",
+        "magento/module-authorization": "0.74.0-beta7",
+        "magento/module-payment": "0.74.0-beta7",
+        "magento/module-checkout": "0.74.0-beta7",
+        "magento/module-theme": "0.74.0-beta7",
+        "magento/module-sales-rule": "0.74.0-beta7",
+        "magento/module-sales-sequence": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-widget": "0.74.0-beta7",
+        "magento/module-directory": "0.74.0-beta7",
+        "magento/module-eav": "0.74.0-beta7",
+        "magento/module-tax": "0.74.0-beta7",
+        "magento/module-gift-message": "0.74.0-beta7",
+        "magento/module-reports": "0.74.0-beta7",
+        "magento/module-catalog-inventory": "0.74.0-beta7",
+        "magento/module-wishlist": "0.74.0-beta7",
+        "magento/module-email": "0.74.0-beta7",
+        "magento/module-shipping": "0.74.0-beta7",
+        "magento/module-config": "0.74.0-beta7",
+        "magento/module-media-storage": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
+        "magento/module-ui": "0.74.0-beta7",
+        "magento/module-quote": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Sales/etc/data_object.xml b/app/code/Magento/Sales/etc/service_data_attributes.xml
similarity index 78%
rename from app/code/Magento/Sales/etc/data_object.xml
rename to app/code/Magento/Sales/etc/service_data_attributes.xml
index 8ef8080db8a29120f255cedfe0c083f45d85e5e5..1e7f320c18ed6e98b0c979d23e80e6ff48478fa4 100644
--- a/app/code/Magento/Sales/etc/data_object.xml
+++ b/app/code/Magento/Sales/etc/service_data_attributes.xml
@@ -5,10 +5,10 @@
  * See COPYING.txt for license details.
  */
 -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Api/etc/data_object.xsd">
-    <custom_attributes for="Magento\Sales\Api\Data\OrderInterface">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Api/etc/service_data_attributes.xsd">
+    <extension_attributes for="Magento\Sales\Api\Data\OrderInterface">
         <attribute code="applied_taxes" type="Magento\Tax\Api\Data\OrderTaxDetailsAppliedTaxInterface[]" />
         <attribute code="item_applied_taxes" type="Magento\Tax\Api\Data\OrderTaxDetailsItemInterface[]" />
         <attribute code="converting_from_quote" type="boolean" />
-    </custom_attributes>
+    </extension_attributes>
 </config>
diff --git a/app/code/Magento/Sales/view/adminhtml/layout/customer_form.xml b/app/code/Magento/Sales/view/adminhtml/layout/customer_index_edit.xml
similarity index 91%
rename from app/code/Magento/Sales/view/adminhtml/layout/customer_form.xml
rename to app/code/Magento/Sales/view/adminhtml/layout/customer_index_edit.xml
index 971cc57cfe03cca7f828c517d5cf674bcdf42377..b5de5df96a33838f520c890d682404ba1cc4e096 100644
--- a/app/code/Magento/Sales/view/adminhtml/layout/customer_form.xml
+++ b/app/code/Magento/Sales/view/adminhtml/layout/customer_index_edit.xml
@@ -7,7 +7,7 @@
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
     <body>
-        <referenceBlock name="form">
+        <referenceBlock name="customer_form">
             <block acl="Magento_Sales::actions_view" class="Magento\Sales\Block\Adminhtml\CustomerOrdersTab" name="orders" />
         </referenceBlock>
     </body>
diff --git a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_creditmemo_new.xml b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_creditmemo_new.xml
index 031d2ada6a1493e0fba975ea588642a8f3a6fe8c..a4ee30150b13a4236deca813f902e2be14da5d38 100644
--- a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_creditmemo_new.xml
+++ b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_creditmemo_new.xml
@@ -1,33 +1,35 @@
-<?xml version="1.0"?>
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
-    <update handle="sales_order_item_price"/>
-    <body>
-        <referenceContainer name="content">
-            <block class="Magento\Sales\Block\Adminhtml\Order\Creditmemo\Create" name="sales_creditmemo_create">
-                <block class="Magento\Sales\Block\Adminhtml\Order\Creditmemo\Create\Form" name="form" template="order/creditmemo/create/form.phtml">
-                    <block class="Magento\Sales\Block\Adminhtml\Order\View\Info" name="order_info" template="order/view/info.phtml"/>
-                    <block class="Magento\Sales\Block\Adminhtml\Order\Payment" name="order_payment"/>
-                    <block class="Magento\Sales\Block\Adminhtml\Order\Creditmemo\Create\Items" name="order_items" template="order/creditmemo/create/items.phtml">
-                        <block class="Magento\Sales\Block\Adminhtml\Items\Renderer\DefaultRenderer" as="default" template="order/creditmemo/create/items/renderer/default.phtml"/>
-                        <block class="Magento\Sales\Block\Adminhtml\Items\Column\Qty" name="column_qty" template="items/column/qty.phtml" group="column"/>
-                        <block class="Magento\Sales\Block\Adminhtml\Items\Column\Name" name="column_name" template="items/column/name.phtml" group="column"/>
-                        <block class="Magento\Framework\View\Element\Text\ListText" name="order_item_extra_info"/>
-                        <block class="Magento\Sales\Block\Adminhtml\Order\Totalbar" name="order_totalbar" template="order/totalbar.phtml"/>
-                        <block class="Magento\Sales\Block\Adminhtml\Order\Creditmemo\Totals" name="creditmemo_totals" template="order/totals.phtml">
-                            <block class="Magento\Sales\Block\Adminhtml\Order\Creditmemo\Create\Adjustments" name="adjustments" template="order/creditmemo/create/totals/adjustments.phtml"/>
-                            <block class="Magento\Sales\Block\Adminhtml\Order\Totals\Tax" name="tax" template="order/totals/tax.phtml"/>
-                        </block>
-                        <container name="submit_before" label="Submit Before"/>
-                        <container name="submit_after" label="Submit After"/>
-                    </block>
-                </block>
-            </block>
-        </referenceContainer>
-    </body>
-</page>
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
+    <update handle="sales_order_item_price"/>
+    <body>
+        <referenceContainer name="admin.scope.col.wrap" htmlClass="admin__old" /> <!-- ToDo UI: remove this wrapper with old styles removal. The class name "admin__old" is for tests only, we shouldn't use it in any way -->
+
+        <referenceContainer name="content">
+            <block class="Magento\Sales\Block\Adminhtml\Order\Creditmemo\Create" name="sales_creditmemo_create">
+                <block class="Magento\Sales\Block\Adminhtml\Order\Creditmemo\Create\Form" name="form" template="order/creditmemo/create/form.phtml">
+                    <block class="Magento\Sales\Block\Adminhtml\Order\View\Info" name="order_info" template="order/view/info.phtml"/>
+                    <block class="Magento\Sales\Block\Adminhtml\Order\Payment" name="order_payment"/>
+                    <block class="Magento\Sales\Block\Adminhtml\Order\Creditmemo\Create\Items" name="order_items" template="order/creditmemo/create/items.phtml">
+                        <block class="Magento\Sales\Block\Adminhtml\Items\Renderer\DefaultRenderer" as="default" template="order/creditmemo/create/items/renderer/default.phtml"/>
+                        <block class="Magento\Sales\Block\Adminhtml\Items\Column\Qty" name="column_qty" template="items/column/qty.phtml" group="column"/>
+                        <block class="Magento\Sales\Block\Adminhtml\Items\Column\Name" name="column_name" template="items/column/name.phtml" group="column"/>
+                        <block class="Magento\Framework\View\Element\Text\ListText" name="order_item_extra_info"/>
+                        <block class="Magento\Sales\Block\Adminhtml\Order\Totalbar" name="order_totalbar" template="order/totalbar.phtml"/>
+                        <block class="Magento\Sales\Block\Adminhtml\Order\Creditmemo\Totals" name="creditmemo_totals" template="order/totals.phtml">
+                            <block class="Magento\Sales\Block\Adminhtml\Order\Creditmemo\Create\Adjustments" name="adjustments" template="order/creditmemo/create/totals/adjustments.phtml"/>
+                            <block class="Magento\Sales\Block\Adminhtml\Order\Totals\Tax" name="tax" template="order/totals/tax.phtml"/>
+                        </block>
+                        <container name="submit_before" label="Submit Before"/>
+                        <container name="submit_after" label="Submit After"/>
+                    </block>
+                </block>
+            </block>
+        </referenceContainer>
+    </body>
+</page>
diff --git a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_creditmemo_view.xml b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_creditmemo_view.xml
index 916950e7e358e286ebf34bbc762fd64024dd2074..7208039683c8dbf06f7a60bfd8db9e311aa8cfed 100644
--- a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_creditmemo_view.xml
+++ b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_creditmemo_view.xml
@@ -8,6 +8,7 @@
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
     <update handle="sales_creditmemo_item_price"/>
     <body>
+        <referenceContainer name="admin.scope.col.wrap" htmlClass="admin__old" /> <!-- ToDo UI: remove this wrapper with old styles removal. The class name "admin__old" is for tests only, we shouldn't use it in any way -->
         <referenceContainer name="content">
             <block class="Magento\Sales\Block\Adminhtml\Order\Creditmemo\View" name="sales_creditmemo_view">
                 <block class="Magento\Sales\Block\Adminhtml\Order\Creditmemo\View\Form" name="form" template="order/creditmemo/view/form.phtml">
diff --git a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_invoice_new.xml b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_invoice_new.xml
index 0f922d55922bd65f188dfa6840fa8db1c78915e6..f31b37ea47d0b5cbe64c8f688ba5501e1f433e5f 100644
--- a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_invoice_new.xml
+++ b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_invoice_new.xml
@@ -8,6 +8,8 @@
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
     <update handle="sales_order_item_price"/>
     <body>
+        <referenceContainer name="admin.scope.col.wrap" htmlClass="admin__old" /> <!-- ToDo UI: remove this wrapper with old styles removal. The class name "admin__old" is for tests only, we shouldn't use it in any way -->
+
         <referenceContainer name="content">
             <block class="Magento\Sales\Block\Adminhtml\Order\Invoice\Create" name="sales_invoice_create">
                 <block class="Magento\Sales\Block\Adminhtml\Order\Invoice\Create\Form" name="form" template="order/invoice/create/form.phtml">
diff --git a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_invoice_view.xml b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_invoice_view.xml
index 93552d0ec38418451df0cd93d847c94a81cc1b92..e22eaae5cd8f4092cd672c407b0c521c6b129b3c 100644
--- a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_invoice_view.xml
+++ b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_invoice_view.xml
@@ -8,6 +8,8 @@
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
     <update handle="sales_invoice_item_price"/>
     <body>
+        <referenceContainer name="admin.scope.col.wrap" htmlClass="admin__old" /> <!-- ToDo UI: remove this wrapper with old styles removal. The class name "admin__old" is for tests only, we shouldn't use it in any way -->
+
         <referenceContainer name="content">
             <block class="Magento\Sales\Block\Adminhtml\Order\Invoice\View" name="sales_invoice_view">
                 <block class="Magento\Sales\Block\Adminhtml\Order\Invoice\View\Form" name="form" template="order/invoice/view/form.phtml">
diff --git a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_transactions_grid_block.xml b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_transactions_grid_block.xml
index cbc91390fda6cd951fa9ebf480a3cd1b40e3c2b2..36e653b728b26412248d6286a1a0c936b4e59918 100644
--- a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_transactions_grid_block.xml
+++ b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_transactions_grid_block.xml
@@ -8,6 +8,8 @@
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
     <update handle="sales_transactions_grid_block"/>
     <body>
+        <referenceContainer name="admin.scope.col.wrap" htmlClass="admin__old" /> <!-- ToDo UI: remove this wrapper with old styles removal. The class name "admin__old" is for tests only, we shouldn't use it in any way -->
+        
         <referenceBlock name="sales.transactions.grid">
             <arguments>
                 <argument name="id" xsi:type="string">order_transactions</argument>
diff --git a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_view.xml b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_view.xml
index ed5a0578d7f292c37160a53a417aa5136dce7edb..19260c6cf0849dd9c89287a9291eed94c459d08a 100644
--- a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_view.xml
+++ b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_view.xml
@@ -15,6 +15,8 @@
     </head>
     <update handle="sales_order_item_price"/>
     <body>
+        <referenceContainer name="admin.scope.col.wrap" htmlClass="admin__old" /> <!-- ToDo UI: remove this wrapper with old styles removal. The class name "admin__old" is for tests only, we shouldn't use it in any way -->
+
         <referenceContainer name="content">
             <block class="Magento\Sales\Block\Adminhtml\Order\View" name="sales_order_edit"/>
         </referenceContainer>
diff --git a/app/code/Magento/Sales/view/adminhtml/layout/sales_transactions_view.xml b/app/code/Magento/Sales/view/adminhtml/layout/sales_transactions_view.xml
index aed08edb19e608d84b4a2397972d694dd6473754..0f7144004b45285aa108bfc37999b6596e48240f 100644
--- a/app/code/Magento/Sales/view/adminhtml/layout/sales_transactions_view.xml
+++ b/app/code/Magento/Sales/view/adminhtml/layout/sales_transactions_view.xml
@@ -8,6 +8,8 @@
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
     <update handle="sales_transaction_child_block"/>
     <body>
+        <referenceContainer name="admin.scope.col.wrap" htmlClass="admin__old" /> <!-- ToDo UI: remove this wrapper with old styles removal. The class name "admin__old" is for tests only, we shouldn't use it in any way -->
+
         <referenceContainer name="content">
             <block class="Magento\Sales\Block\Adminhtml\Transactions\Detail" name="sales_transactions.detail" template="transactions/detail.phtml">
                 <block class="Magento\Sales\Block\Adminhtml\Transactions\Detail\Grid" name="sales_transactions.detail.grid" as="detail_grid"/>
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/items/column/name.phtml b/app/code/Magento/Sales/view/adminhtml/templates/items/column/name.phtml
index 410e44f5977e65522e61d063142f0db15a51390e..d8e8c8eda42623412337857b7d75163a62aa8027 100644
--- a/app/code/Magento/Sales/view/adminhtml/templates/items/column/name.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/items/column/name.phtml
@@ -14,33 +14,38 @@
 ?>
 
 <?php if ($_item = $block->getItem()): ?>
-    <div id="order_item_<?php echo $_item->getId() ?>_title" class="product-title"><?php echo $block->escapeHtml($_item->getName()) ?></div>
-    <strong><?php echo __('SKU') ?>:</strong> <?php echo implode('<br />', $this->helper('Magento\Catalog\Helper\Data')->splitSku($block->escapeHtml($block->getSku()))); ?>
-    <?php if ($block->getOrderOptions()): ?>
-        <dl class="item-options">
-        <?php foreach ($block->getOrderOptions() as $_option): ?>
-            <dt><?php echo $_option['label'] ?></dt>
-            <dd>
-            <?php if (isset($_option['custom_view']) && $_option['custom_view']): ?>
-                <?php echo $block->getCustomizedOptionValue($_option); ?>
-            <?php else: ?>
-                <?php $_option = $block->getFormattedOption($_option['value']); ?>
-                <?php echo $_option['value']; ?><?php if (isset($_option['remainder']) && $_option['remainder']): ?><span id="<?php echo $_dots = 'dots' . uniqid()?>"> ...</span><span id="<?php echo $_id = 'id' . uniqid()?>"><?php echo $_option['remainder'] ?></span>
-                    <script>
-require(['prototype'], function(){
+    <div id="order_item_<?php echo $_item->getId() ?>_title"
+         class="product-title">
+        <?php echo $block->escapeHtml($_item->getName()) ?>
+    </div>
 
-    $('<?php echo $_id ?>').hide();
-    $('<?php echo $_id ?>').up().observe('mouseover', function(){$('<?php echo $_id ?>').show();});
-    $('<?php echo $_id ?>').up().observe('mouseover', function(){$('<?php echo $_dots?>').hide();});
-    $('<?php echo $_id ?>').up().observe('mouseout',  function(){$('<?php echo $_id ?>').hide();});
-    $('<?php echo $_id ?>').up().observe('mouseout',  function(){$('<?php echo $_dots ?>').show();});
+    <div class="product-sku-block">
+        <span><?php echo __('SKU') ?>:</span> <?php echo implode('<br />', $this->helper('Magento\Catalog\Helper\Data')->splitSku($block->escapeHtml($block->getSku()))); ?>
+    </div>
 
-});
-</script>
-                <?php endif; ?>
-            <?php endif; ?>
-            </dd>
-        <?php endforeach; ?>
+    <?php if ($block->getOrderOptions()): ?>
+        <dl class="item-options">
+            <?php foreach ($block->getOrderOptions() as $_option): ?>
+                <dt><?php echo $_option['label'] ?>:</dt>
+                <dd>
+                    <?php if (isset($_option['custom_view']) && $_option['custom_view']): ?>
+                        <?php echo $block->getCustomizedOptionValue($_option); ?>
+                    <?php else: ?>
+                        <?php $_option = $block->getFormattedOption($_option['value']); ?>
+                        <?php echo $_option['value']; ?><?php if (isset($_option['remainder']) && $_option['remainder']): ?><span id="<?php echo $_dots = 'dots' . uniqid()?>"> ...</span><span id="<?php echo $_id = 'id' . uniqid()?>"><?php echo $_option['remainder'] ?></span>
+                            <script>
+                                require(['prototype'], function() {
+                                    $('<?php echo $_id ?>').hide();
+                                    $('<?php echo $_id ?>').up().observe('mouseover', function(){$('<?php echo $_id ?>').show();});
+                                    $('<?php echo $_id ?>').up().observe('mouseover', function(){$('<?php echo $_dots?>').hide();});
+                                    $('<?php echo $_id ?>').up().observe('mouseout',  function(){$('<?php echo $_id ?>').hide();});
+                                    $('<?php echo $_id ?>').up().observe('mouseout',  function(){$('<?php echo $_dots ?>').show();});
+                                });
+                            </script>
+                        <?php endif; ?>
+                    <?php endif; ?>
+                </dd>
+            <?php endforeach; ?>
         </dl>
     <?php endif; ?>
     <?php echo $block->escapeHtml($_item->getDescription()) ?>
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/items/column/qty.phtml b/app/code/Magento/Sales/view/adminhtml/templates/items/column/qty.phtml
index 91e20c1f3658451d6d43cfc54f6b657c69526e2d..46b39dc3a78af52bbe12142c47d4876c312e982a 100644
--- a/app/code/Magento/Sales/view/adminhtml/templates/items/column/qty.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/items/column/qty.phtml
@@ -8,34 +8,39 @@
 
 ?>
 <?php if ($_item = $block->getItem()): ?>
-<table cellspacing="0" class="qty-table">
+<table class="data-table qty-table">
     <tr>
-        <td><?php echo __('Ordered') ?></td>
-        <td><strong><?php echo $_item->getQtyOrdered()*1 ?></strong></td>
+        <th><?php echo __('Ordered') ?></th>
+        <td><?php echo $_item->getQtyOrdered()*1 ?></td>
     </tr>
+
     <?php if ((float) $_item->getQtyInvoiced()): ?>
-    <tr>
-        <td><?php echo __('Invoiced') ?></td>
-        <td><strong><?php echo $_item->getQtyInvoiced()*1 ?></strong></td>
-    </tr>
+        <tr>
+            <th><?php echo __('Invoiced') ?></th>
+            <td><?php echo $_item->getQtyInvoiced()*1 ?></td>
+        </tr>
     <?php endif; ?>
+
     <?php if ((float) $_item->getQtyShipped()): ?>
-    <tr>
-        <td><?php echo __('Shipped') ?></td>
-        <td><strong><?php echo $_item->getQtyShipped()*1 ?></strong></td>
-    </tr>
+        <tr>
+            <th><?php echo __('Shipped') ?></th>
+            <td><?php echo $_item->getQtyShipped()*1 ?></td>
+        </tr>
     <?php endif; ?>
+
     <?php if ((float) $_item->getQtyRefunded()): ?>
-    <tr>
-        <td><?php echo __('Refunded') ?></td>
-        <td><strong><?php echo $_item->getQtyRefunded()*1 ?></strong></td>
-    </tr>
+        <tr>
+            <th><?php echo __('Refunded') ?></th>
+            <td><?php echo $_item->getQtyRefunded()*1 ?></td>
+        </tr>
     <?php endif; ?>
+
     <?php if ((float) $_item->getQtyCanceled()): ?>
-    <tr>
-        <td><?php echo __('Canceled') ?></td>
-        <td><strong><?php echo $_item->getQtyCanceled()*1 ?></strong></td>
-    </tr>
+        <tr>
+            <th><?php echo __('Canceled') ?></th>
+            <td><?php echo $_item->getQtyCanceled()*1 ?></td>
+        </tr>
     <?php endif; ?>
+
 </table>
 <?php endif; ?>
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/comments/view.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/comments/view.phtml
index cbe3b6f40e5b08784d20e03f978f0940d9ee0ddc..096b7098612358a568c5d5feba5022f428dfa7db 100644
--- a/app/code/Magento/Sales/view/adminhtml/templates/order/comments/view.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/order/comments/view.phtml
@@ -8,38 +8,62 @@
 
 ?>
 <?php if ($_entity = $block->getEntity()): ?>
-<div id="comments_block">
-    <div class="field-row">
-        <label class="normal" for="history_comment"><?php echo __('Comment Text') ?></label>
-        <textarea name="comment[comment]" rows="3" cols="5" id="history_comment"></textarea>
-    </div>
-    <div class="clearfix">
-        <div class="actions">
-            <?php echo $block->getChildHtml('submit_button') ?>
+<div id="comments_block" class="edit-order-comments">
+    <div class="order-history-block">
+        <div class="admin__field field-row">
+            <label class="admin__field-label"
+                   for="history_comment"><?php echo __('Comment Text') ?></label>
+            <textarea name="comment[comment]"
+                      class="admin__control-textarea"
+                      rows="3"
+                      cols="5"
+                      id="history_comment"></textarea>
         </div>
-        <div class="order-history-comments-options">
-            <?php if ($block->canSendCommentEmail()): ?>
-                <input name="comment[is_customer_notified]" type="checkbox" id="history_notify" value="1" /><label class="normal" for="history_notify"><?php echo __('Notify Customer by Email') ?></label><br />
-            <?php endif; ?>
-            <input name="comment[is_visible_on_front]" type="checkbox" id="history_visible" value="1" /><label class="normal" for="history_visible"> <?php echo __('Visible on Frontend') ?></label>
+        <div class="admin__field">
+            <div class="order-history-comments-options">
+                <?php if ($block->canSendCommentEmail()): ?>
+                    <div class="admin__field admin__field-option">
+                        <input name="comment[is_customer_notified]"
+                               type="checkbox"
+                               class="admin__control-checkbox"
+                               id="history_notify"
+                               value="1" />
+                        <label class="admin__field-label"
+                               for="history_notify"><?php echo __('Notify Customer by Email') ?></label>
+                    </div>
+                <?php endif; ?>
+                <div class="admin__field admin__field-option">
+                    <input name="comment[is_visible_on_front]"
+                           type="checkbox"
+                           id="history_visible"
+                           class="admin__control-checkbox"
+                           value="1" />
+                    <label class="admin__field-label"
+                           for="history_visible"> <?php echo __('Visible on Frontend') ?></label>
+                </div>
+            </div>
+            <div class="order-history-comments-actions">
+                <?php echo $block->getChildHtml('submit_button') ?>
+            </div>
         </div>
     </div>
+
     <ul class="note-list">
-    <?php foreach ($_entity->getCommentsCollection(true) as $_comment): ?>
-        <li>
-            <span class="note-list-date"><?php echo $block->formatDate($_comment->getCreatedAtDate(), \IntlDateFormatter::MEDIUM) ?></span>
-            <span class="note-list-time"><?php echo $block->formatTime($_comment->getCreatedAtDate(), \IntlDateFormatter::MEDIUM) ?></span>
-            <span class="note-list-customer">
-                <?php echo __('Customer') ?>
-                <?php if ($_comment->getIsCustomerNotified()): ?>
-                    <span class="note-list-customer-notified"><?php echo __('Notified') ?></span>
-                <?php else: ?>
-                    <span class="note-list-customer-not-notified"><?php echo __('Not Notified') ?></span>
-                <?php endif; ?>
-            </span>
-            <div class="note-list-comment"><?php echo $block->escapeHtml($_comment->getComment(), ['b', 'br', 'strong', 'i', 'u']) ?></div>
-        </li>
-    <?php endforeach; ?>
+        <?php foreach ($_entity->getCommentsCollection(true) as $_comment): ?>
+            <li>
+                <span class="note-list-date"><?php echo $block->formatDate($_comment->getCreatedAtDate(), \IntlDateFormatter::MEDIUM) ?></span>
+                <span class="note-list-time"><?php echo $block->formatTime($_comment->getCreatedAtDate(), \IntlDateFormatter::MEDIUM) ?></span>
+                <span class="note-list-customer">
+                    <?php echo __('Customer') ?>
+                    <?php if ($_comment->getIsCustomerNotified()): ?>
+                        <span class="note-list-customer-notified"><?php echo __('Notified') ?></span>
+                    <?php else: ?>
+                        <span class="note-list-customer-not-notified"><?php echo __('Not Notified') ?></span>
+                    <?php endif; ?>
+                </span>
+                <div class="note-list-comment"><?php echo $block->escapeHtml($_comment->getComment(), ['b', 'br', 'strong', 'i', 'u']) ?></div>
+            </li>
+        <?php endforeach; ?>
     </ul>
 </div>
 <script>
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/create/abstract.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/create/abstract.phtml
index 956ca1eedf569a14dca9e099c7ca15f98e6e6eb2..4364258410ba46e1083242b1ac611ba6f053734b 100644
--- a/app/code/Magento/Sales/view/adminhtml/templates/order/create/abstract.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/order/create/abstract.phtml
@@ -8,8 +8,8 @@
 
 ?>
 
-<div class="admin__fieldset-wrapper-title">
-    <strong><?php echo $block->getHeaderText() ?></strong>
+<div class="admin__page-section-title">
+    <span class="title"><?php echo $block->getHeaderText() ?></span>
     <?php if($block->getButtonsHtml()): ?>
         <div class="actions"><?php echo $block->getButtonsHtml() ?></div>
     <?php endif; ?>
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/create/data.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/create/data.phtml
index d166ab4edac32983b6d5f784ede2228b21e362c1..7ba8e8a79394a26020ad406ff7b7ca287cb53b4a 100644
--- a/app/code/Magento/Sales/view/adminhtml/templates/order/create/data.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/order/create/data.phtml
@@ -14,82 +14,76 @@
     });
 </script>
     <div class="order-details<?php if ($block->getCustomerId()): ?> order-details-existing-customer<?php endif; ?>">
-        <div class="order-details-inner">
-            <div id="order-additional_area" style="display: none" class="admin__fieldset-wrapper order-additional-area">
-                <?php echo $block->getChildHtml('additional_area') ?>
-            </div>
 
-            <div id="order-search" style="display: none" class="admin__fieldset-wrapper order-search-items">
-                <?php echo $block->getChildHtml('search') ?>
-            </div>
+        <div id="order-additional_area" style="display: none" class="admin__page-section order-additional-area">
+            <?php echo $block->getChildHtml('additional_area') ?>
+        </div>
 
-            <div id="order-items" class="admin__fieldset-wrapper order-items" data-mage-init='{"loader": {}}'>
-                <?php echo $block->getChildHtml('items') ?>
-            </div>
+        <div id="order-search" style="display: none" class="admin__page-section order-search-items">
+            <?php echo $block->getChildHtml('search') ?>
+        </div>
 
-            <div id="order-errors" class="order-errors"><?php echo $block->getChildHtml('errors') ?></div>
+        <section id="order-items" class="admin__page-section order-items" data-mage-init='{"loader": {}}'>
+            <?php echo $block->getChildHtml('items') ?>
+        </section>
 
-            <div id="order-form_account" class="admin__fieldset-wrapper order-account-information">
-                <?php echo $block->getChildHtml('form_account') ?>
-            </div>
+        <div id="order-errors" class="order-errors"><?php echo $block->getChildHtml('errors') ?></div>
 
-            <div id="order-addresses" class="admin__fieldset-wrapper order-addresses">
-                <div class="admin__fieldset-wrapper-title">
-                    <strong class="title"><?php echo __('Address Information') ?></strong>
+        <section id="order-form_account" class="admin__page-section order-account-information">
+            <?php echo $block->getChildHtml('form_account') ?>
+        </section>
+
+        <section id="order-addresses" class="admin__page-section order-addresses">
+            <div class="admin__page-section-title">
+                <span class="title"><?php echo __('Address Information') ?></span>
+            </div>
+            <div class="admin__page-section-content">
+                <div id="order-billing_address" class="admin__page-section-item order-billing-address">
+                    <?php echo $block->getChildHtml('billing_address') ?>
                 </div>
-                <div class="admin__fieldset-wrapper-content">
-                    <div id="order-billing_address" class="order-billing-address">
-                        <?php echo $block->getChildHtml('billing_address') ?>
-                    </div>
-                    <div id="order-shipping_address" class="order-shipping-address">
-                        <?php echo $block->getChildHtml('shipping_address') ?>
-                    </div>
+                <div id="order-shipping_address" class="admin__page-section-item order-shipping-address">
+                    <?php echo $block->getChildHtml('shipping_address') ?>
                 </div>
             </div>
+        </section>
 
-            <div id="order-methods" class="admin__fieldset-wrapper order-methods">
-                <div class="admin__fieldset-wrapper-title">
-                    <strong class="title"><?php echo __('Payment & Shipping Information') ?></strong>
+        <section id="order-methods" class="admin__page-section order-methods">
+            <div class="admin__page-section-title">
+                <span class="title"><?php echo __('Payment &amp; Shipping Information') ?></span>
+            </div>
+            <div class="admin__page-section-content">
+                <div id="order-billing_method" class="admin__page-section-item order-billing-method">
+                    <?php echo $block->getChildHtml('billing_method') ?>
                 </div>
-                <div class="admin__fieldset-wrapper-content">
-                    <div id="order-billing_method" class="order-billing-method">
-                        <?php echo $block->getChildHtml('billing_method') ?>
-                    </div>
-                    <div id="order-shipping_method" class="order-shipping-method">
-                        <?php echo $block->getChildHtml('shipping_method') ?>
-                    </div>
+                <div id="order-shipping_method" class="admin__page-section-item order-shipping-method">
+                    <?php echo $block->getChildHtml('shipping_method') ?>
                 </div>
             </div>
+        </section>
 
-            <?php if ($block->getChildBlock('card_validation')): ?>
-                <div id="order-card_validation" class="admin__fieldset-wrapper order-card-validation">
-                    <?php echo $block->getChildHtml('card_validation') ?>
-                </div>
-            <?php endif; ?>
+        <?php if ($block->getChildBlock('card_validation')): ?>
+        <section id="order-card_validation" class="admin__page-section order-card-validation">
+            <?php echo $block->getChildHtml('card_validation') ?>
+        </section>
+        <?php endif; ?>
 
-            <?php echo $block->getChildHtml('gift_options') ?>
+        <?php echo $block->getChildHtml('gift_options') ?>
 
-            <div class="admin__fieldset-wrapper order-summary">
-                <div class="admin__fieldset-wrapper-title">
-                    <strong class="title"><?php echo __('Order Total') ?></strong>
-                </div>
-                <div class="admin__fieldset-wrapper-content">
-                    <div class="order-history">
-                        <fieldset class="admin__fieldset" id="order-comment">
-                            <legend class="admin__legend"><span><?php echo __('Order History') ?></span></legend>
-                            <br>
-                            <?php echo $block->getChildHtml('comment') ?>
-                        </fieldset>
-                    </div>
-                    <div class="order-totals">
-                        <fieldset id="order-totals" class="order-totals-content admin__fieldset">
-                            <?php echo $block->getChildHtml('totals') ?>
-                        </fieldset>
-                    </div>
-                </div>
+        <section class="admin__page-section order-summary">
+            <div class="admin__page-section-title">
+                <span class="title"><?php echo __('Order Total') ?></span>
             </div>
-
-        </div>
+            <div class="admin__page-section-content">
+                <fieldset class="admin__fieldset order-history" id="order-comment">
+                    <legend class="admin__legend"><span><?php echo __('Order History') ?></span></legend>
+                    <br>
+                    <?php echo $block->getChildHtml('comment') ?>
+                </fieldset>
+                <fieldset id="order-totals" class="admin__fieldset order-totals">
+                    <?php echo $block->getChildHtml('totals') ?>
+                </fieldset>
+            </div>
+        </section>
     </div>
 
     <?php if ($block->getCustomerId()): ?>
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/create/form/account.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/create/form/account.phtml
index 23f4f8379ceaf37ae403c6e73ac3ea205f88398e..8fa45617a3a04a5de8cd988582c19efbf43dceda 100644
--- a/app/code/Magento/Sales/view/adminhtml/templates/order/create/form/account.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/order/create/form/account.phtml
@@ -5,12 +5,11 @@
  */
  ?>
 
-<div class="admin__fieldset-wrapper-title <?php echo $block->getHeaderCssClass() ?>">
+<div class="admin__page-section-title <?php echo $block->getHeaderCssClass() ?>">
     <span class="title"><?php echo $block->getHeaderText() ?></span>
     <div class="actions"></div>
 </div>
-
-<div id="customer_account_fieds" class="admin__fieldset-wrapper-content">
+<div id="customer_account_fieds" class="admin__page-section-content">
     <?php echo $block->getForm()->getHtml() ?>
 </div>
 
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/create/items.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/create/items.phtml
index e2b9bd096a03c7f5f6c414b8cc112977f852bc1f..bb7e4b3597c6ee7c9162666bc1dbf411155a7ee7 100644
--- a/app/code/Magento/Sales/view/adminhtml/templates/order/create/items.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/order/create/items.phtml
@@ -8,7 +8,7 @@
 
 ?>
 
-<div class="admin__fieldset-wrapper-title">
+<div class="admin__page-section-title">
     <strong class="title"><?php echo $block->getHeaderText() ?></strong>
     <div class="actions">
         <?php echo $block->getButtonsHtml() ?>
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/create/items/grid.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/create/items/grid.phtml
index d6c4a2dd5a591b2325af448049f8087cb8653bd3..aaf605a22ce9a659942499c8081832f5b26e92d1 100644
--- a/app/code/Magento/Sales/view/adminhtml/templates/order/create/items/grid.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/order/create/items/grid.phtml
@@ -16,7 +16,7 @@
 <?php $_items = $block->getItems() ?>
 <?php if (empty($_items)): ?>
     <div class="grid" id="order-items_grid">
-        <table class="data-table table-info order-tables">
+        <table class="data-table admin__table-primary order-tables">
             <thead>
                 <tr class="headings">
                     <th class="col-product"><span><?php echo __('Product') ?></span></th>
@@ -40,11 +40,11 @@
 <div class="grid" id="order-items_grid">
     <div class="hor-scroll">
     <?php if (count($_items)>10): ?>
-        <div class="actions update">
-            <?php echo $block->getButtonHtml(__('Update Items and Qty\'s'), 'order.itemsUpdate()'); ?>
+        <div class="actions update actions-update">
+            <?php echo $block->getButtonHtml(__('Update Items and Qty\'s'), 'order.itemsUpdate()', 'action-secondary'); ?>
         </div>
     <?php endif; ?>
-        <table class="data-table table-info order-tables">
+        <table class="data-table admin__table-primary order-tables">
             <thead>
                 <tr class="headings">
                     <th class="col-product"><span><?php echo __('Product') ?></span></th>
@@ -75,8 +75,8 @@
                     <tr>
                         <td class="col-product">
                             <span id="order_item_<?php echo $_item->getId() ?>_title"><?php echo $block->escapeHtml($_item->getName()) ?></span>
-                            <div>
-                                <strong><?php echo __('SKU') ?>:</strong>
+                            <div class="product-sku-block">
+                                <span><?php echo __('SKU') ?>:</span>
                                 <?php echo implode('<br />', $this->helper('Magento\Catalog\Helper\Data')->splitSku($block->escapeHtml($_item->getSku()))); ?>
                             </div>
                             <div class="product-configure-block">
@@ -140,7 +140,7 @@
                         </td>
                         <td class="col-actions last">
                             <select class="admin__control-select" name="item[<?php echo $_item->getId() ?>][action]">
-                                <option value=""></option>
+                                <option value=""><?php echo __('Please select') ?></option>
                                 <option value="remove"><?php echo __('Remove') ?></option>
                                 <?php if ($block->getCustomerId() && $block->getMoveToCustomerStorage()): ?>
                                     <option value="cart"><?php echo __('Move to Shopping Cart') ?></option>
@@ -170,7 +170,7 @@
                     <?php endforeach; ?>
 
                     <?php if ($hasMessageError):?>
-                        <tr class="col-messages-error">
+                        <tr class="row-messages-error">
                             <td colspan="100"> <!-- ToDo UI: remove the 100 -->
                                 <?php foreach ($_item->getMessage(false) as $message):
                                     if (empty($message)) {
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/create/shipping/method/form.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/create/shipping/method/form.phtml
index 7ccbfbb6bd3ec7da874f9ed621c5a736d1cdc132..f1e4430c69ff5937b7a0028d063594639ee27c66 100644
--- a/app/code/Magento/Sales/view/adminhtml/templates/order/create/shipping/method/form.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/order/create/shipping/method/form.phtml
@@ -52,7 +52,7 @@
         </dl>
     </div>
     <?php if ($_rate = $block->getActiveMethodRate()): ?>
-        <div id="order-shipping-method-info">
+        <div id="order-shipping-method-info" class="order-shipping-method-info">
             <dl class="admin__order-shipment-methods">
                 <dt class="admin__order-shipment-methods-title">
                     <?php echo $block->escapeHtml($block->getCarrierName($_rate->getCarrier())) ?>
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/create/sidebar/items.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/create/sidebar/items.phtml
index c3eaf03a4c25526c7211116d86654dcb6e85a935..9ae2ac048ef6aa9e6df1ffa0b6b1f73d893fa9bc 100644
--- a/app/code/Magento/Sales/view/adminhtml/templates/order/create/sidebar/items.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/order/create/sidebar/items.phtml
@@ -9,7 +9,7 @@
 ?>
 <?php /* @var $block \Magento\Sales\Block\Adminhtml\Order\Create\Sidebar\AbstractSidebar */ ?>
 <div class="create-order-sidebar-block" id="sidebar_data_<?php echo $block->getDataId() ?>">
-    <div class="head">
+    <div class="head sidebar-title-block">
         <a href="#" class="action-refresh"
            title="<?php echo $block->escapeHtml(__('Refresh')); ?>"
            onclick="order.loadArea('sidebar_<?php echo $block->getDataId() ?>', 'sidebar_data_<?php echo $block->getDataId() ?>');return false;">
@@ -23,7 +23,7 @@
     <div class="content">
         <div class="auto-scroll">
         <?php if ($block->getItemCount()): ?>
-        <table class="table-info">
+        <table class="admin__table-primary">
             <thead>
                 <tr>
                     <th class="col-item"><?php echo __('Item') ?></th>
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/form.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/form.phtml
index b876ba145accb78c81f8140980e95b76bfb8f1e7..f13fd7a04b50b05f720db68d44501be2c189c928 100644
--- a/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/form.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/form.phtml
@@ -13,58 +13,60 @@
 
     <?php echo $block->getChildHtml('order_info') ?>
 
-    <?php if (!$_order->getIsVirtual()): ?>
-    <div class="clearfix">
-    <?php endif; ?>
-
+    <section class="admin__page-section">
+        <div class="admin__page-section-title">
+            <span class="title"><?php echo __('Payment &amp; Shipping Method') ?></span>
+        </div>
+        <div class="admin__page-section-content">
         <?php if (!$_order->getIsVirtual()): ?>
-        <div class="order-payment-method">
+        <div class="admin__page-section-item order-payment-method">
         <?php else: ?>
-        <div class="order-payment-method order-payment-method-virtual">
+        <div class="admin__page-section-item order-payment-method order-payment-method-virtual">
         <?php endif; ?>
 
             <?php /* Billing Address */ ?>
-            <div class="fieldset-wrapper">
-                <div class="fieldset-wrapper-title">
-                    <span class="title"><?php echo __('Payment Information') ?></span>
+            <div class="admin__page-section-item-title">
+                <span class="title"><?php echo __('Payment Information') ?></span>
+            </div>
+            <div class="admin__page-section-item-content">
+                <div class="order-payment-method-title"><?php echo $block->getChildHtml('order_payment') ?></div>
+                <div class="order-payment-currency">
+                    <?php echo __('The order was placed using %1.', $_order->getOrderCurrencyCode()) ?>
+                </div>
+                <div class="order-payment-additional">
+                    <?php echo $block->getChildHtml('order_payment_additional'); ?>
                 </div>
-                <div><?php echo $block->getChildHtml('order_payment') ?></div>
-                <div class="order-payment-currency"><?php echo __('The order was placed using %1.', $_order->getOrderCurrencyCode()) ?></div>
-                <div class="order-payment-additional"><?php echo $block->getChildHtml('order_payment_additional'); ?></div>
             </div>
-
         </div>
 
         <?php if (!$_order->getIsVirtual()): ?>
-        <div class="order-shipping-address">
+        <div class="admin__page-section-item order-shipping-address">
             <?php /* Shipping Address */ ?>
-            <div class="fieldset-wrapper">
-                <div class="fieldset-wrapper-title">
-                    <span class="title"><?php echo __('Shipping Information') ?></span>
-                </div>
-                <div class="shipping-description-wrapper">
-                    <div class="shipping-description-title"><?php echo $block->escapeHtml($_order->getShippingDescription()) ?></div>
-                    <div class="shipping-description-content">
-                        <?php echo __('Total Shipping Charges'); ?>:
+            <div class="admin__page-section-item-title">
+                <span class="title"><?php echo __('Shipping Information') ?></span>
+            </div>
+            <div class="admin__page-section-item-content shipping-description-wrapper">
+                <div class="shipping-description-title"><?php echo $block->escapeHtml($_order->getShippingDescription()) ?></div>
+                <div class="shipping-description-content">
+                    <?php echo __('Total Shipping Charges'); ?>:
 
-                        <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesPriceInclTax($block->getSource()->getStoreId())): ?>
-                            <?php $_excl = $block->displayShippingPriceInclTax($_order); ?>
-                        <?php else: ?>
-                            <?php $_excl = $block->displayPriceAttribute('shipping_amount', false, ' '); ?>
-                        <?php endif; ?>
-                        <?php $_incl = $block->displayShippingPriceInclTax($_order); ?>
+                    <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesPriceInclTax($block->getSource()->getStoreId())): ?>
+                        <?php $_excl = $block->displayShippingPriceInclTax($_order); ?>
+                    <?php else: ?>
+                        <?php $_excl = $block->displayPriceAttribute('shipping_amount', false, ' '); ?>
+                    <?php endif; ?>
+                    <?php $_incl = $block->displayShippingPriceInclTax($_order); ?>
 
-                        <?php echo $_excl; ?>
-                        <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices($block->getSource()->getStoreId()) && $_incl != $_excl): ?>
-                            (<?php echo __('Incl. Tax'); ?> <?php echo $_incl; ?>)
-                        <?php endif; ?>
-                    </div>
+                    <?php echo $_excl; ?>
+                    <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices($block->getSource()->getStoreId()) && $_incl != $_excl): ?>
+                        (<?php echo __('Incl. Tax'); ?> <?php echo $_incl; ?>)
+                    <?php endif; ?>
                 </div>
             </div>
         </div>
         <?php endif; ?>
-
-    </div><?php /* opening div can be in app\code\Magento\Sales\view\adminhtml\order\view\info.phtml or above */?>
+        </div>
+    </section>
 
     <div id="creditmemo_item_container">
         <?php echo $block->getChildHtml('order_items') ?>
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/items.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/items.phtml
index c09ee04d9435d03df15868073eb92d7e82631786..82770b4f3fa45ba239c13dfb673a1dbb8f5d1bb3 100644
--- a/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/items.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/items.phtml
@@ -9,14 +9,14 @@
 ?>
 <?php $_items = $block->getCreditmemo()->getAllItems() ?>
 
-<div class="fieldset-wrapper">
-    <div class="fieldset-wrapper-title">
+<section class="admin__page-section">
+    <div class="admin__page-section-title">
         <span class="title"><?php echo __('Items to Refund') ?></span>
     </div>
 
     <?php if (count($_items)) : ?>
     <div class="grid">
-        <table cellspacing="0" class="data order-tables">
+        <table class="data-table admin__table-primary order-creditmemo-tables">
             <thead>
                 <tr class="headings">
                     <th class="col-product"><span><?php echo __('Product') ?></span></th>
@@ -61,40 +61,66 @@
         <?php echo __('No Items To Refund') ?>
     </div>
     <?php endif; ?>
-</div>
+</section>
 
 <?php $orderTotalBar = $block->getChildHtml('order_totalbar'); ?>
 
 <?php if (!empty($orderTotalBar)): ?>
-<div class="fieldset-wrapper">
+<section class="fieldset-wrapper">
     <?php echo $orderTotalBar; ?>
-</div>
+</section>
 <?php endif; ?>
 
-<div class="clearfix">
+<section class="admin__page-section">
     <input type="hidden" name="creditmemo[do_offline]" id="creditmemo_do_offline" value="0" />
-    <div class="order-comments-history">
-        <div class="fieldset-wrapper">
-            <div class="fieldset-wrapper-title"><span class="title"><?php echo __('Credit Memo Comments') ?></span></div>
-            <fieldset id="history_form">
-                <label class="normal" for="creditmemo_comment_text"><?php echo __('Credit Memo Comments') ?></label><br/>
-                <textarea id="creditmemo_comment_text" name="creditmemo[comment_text]" rows="3" cols="5"><?php echo $block->getCreditmemo()->getCommentText(); ?></textarea>
-            </fieldset>
-        </div>
+    <div class="admin__page-section-title">
+        <span class="title"><?php echo __('Order Total') ?></span>
     </div>
-    <div class="order-totals creditmemo-totals">
-        <div class="fieldset-wrapper">
-            <div class="fieldset-wrapper-title"><span class="title"><?php echo __('Refund Totals') ?></span></div>
+    <div class="admin__page-section-content">
+        <div class="admin__page-section-item order-comments-history">
+            <div class="admin__page-section-item-title">
+                <span class="title"><?php echo __('Credit Memo Comments') ?></span>
+            </div>
+            <div id="history_form" class="admin__fieldset-wrapper-content">
+                <div class="admin__field">
+                    <label class="normal admin__field-label"
+                           for="creditmemo_comment_text"><?php echo __('Comment Text') ?></label>
+                    <div class="admin__field-control">
+                        <textarea id="creditmemo_comment_text"
+                                  class="admin__control-textarea"
+                                  name="creditmemo[comment_text]"
+                                  rows="3"
+                                  cols="5"><?php echo $block->getCreditmemo()->getCommentText(); ?></textarea>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <div class="admin__page-section-item order-totals creditmemo-totals">
+            <div class="admin__page-section-item-title">
+                <span class="title"><?php echo __('Refund Totals') ?></span>
+            </div>
             <?php echo $block->getChildHtml('creditmemo_totals') ?>
             <div class="order-totals-actions">
-                <div class="field choice field-append-comments">
-                    <input id="notify_customer" name="creditmemo[comment_customer_notify]" value="1" type="checkbox" />
-                    <label for="notify_customer"><span><?php echo __('Append Comments') ?></span></label>
+                <div class="field choice admin__field admin__field-option field-append-comments">
+                    <input id="notify_customer"
+                           class="admin__control-checkbox"
+                           name="creditmemo[comment_customer_notify]"
+                           value="1"
+                           type="checkbox" />
+                    <label for="notify_customer" class="admin__field-label">
+                        <span><?php echo __('Append Comments') ?></span>
+                    </label>
                 </div>
                 <?php if ($block->canSendCreditmemoEmail()):?>
-                <div class="field choice field-email-copy">
-                    <input id="send_email" name="creditmemo[send_email]" value="1" type="checkbox" />
-                    <label for="send_email"><span><?php echo __('Email Copy of Credit Memo') ?></span></label>
+                <div class="field choice admin__field admin__field-option field-email-copy">
+                    <input id="send_email"
+                           class="admin__control-checkbox"
+                           name="creditmemo[send_email]"
+                           value="1"
+                           type="checkbox" />
+                    <label for="send_email" class="admin__field-label">
+                        <span><?php echo __('Email Copy of Credit Memo') ?></span>
+                    </label>
                 </div>
                 <?php endif; ?>
                 <?php echo $block->getChildHtml('submit_before') ?>
@@ -106,7 +132,7 @@
             </div>
         </div>
     </div>
-</div>
+</section>
 
 <script>
 require(['jquery', 'prototype'], function(jQuery){
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/items/renderer/default.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/items/renderer/default.phtml
index 76ec308d8b6696ecb466071cb290bd23d4a7fd3f..c238f2478bffae8180f6391914320fdacdee4db6 100644
--- a/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/items/renderer/default.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/items/renderer/default.phtml
@@ -19,13 +19,20 @@
     <?php if ($block->canParentReturnToStock($_item)) : ?>
         <td class="col-return-to-stock">
         <?php if ($block->canReturnItemToStock($_item)) : ?>
-            <input type="checkbox" name="creditmemo[items][<?php echo $_item->getOrderItemId() ?>][back_to_stock]" value="1"<?php if ($_item->getBackToStock()):?> checked<?php endif;?>/>
+            <input type="checkbox"
+                   class="admin__control-checkbox"
+                   name="creditmemo[items][<?php echo $_item->getOrderItemId() ?>][back_to_stock]"
+                   value="1"<?php if ($_item->getBackToStock()):?> checked<?php endif;?>/>
+            <label class="admin__field-label"></label>
         <?php endif; ?>
         </td>
     <?php endif; ?>
-    <td class="col-refund">
+    <td class="col-refund col-qty">
     <?php if ($block->canEditQty()) : ?>
-        <input type="text" class="input-text qty-input" name="creditmemo[items][<?php echo $_item->getOrderItemId() ?>][qty]" value="<?php echo $_item->getQty()*1 ?>"/>
+        <input type="text"
+               class="input-text admin__control-text qty-input"
+               name="creditmemo[items][<?php echo $_item->getOrderItemId() ?>][qty]"
+               value="<?php echo $_item->getQty()*1 ?>"/>
     <?php else : ?>
         <?php echo $_item->getQty()*1 ?>
     <?php endif; ?>
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/totals/adjustments.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/totals/adjustments.phtml
index 4b7f73a40590b4ae166748ce1cb2c756ab0b7467..8ae81b1a6d0c0d5046ea7ff7ea45a1bcec2b9780 100644
--- a/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/totals/adjustments.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/totals/adjustments.phtml
@@ -11,52 +11,69 @@
 <?php if ($_source): ?>
     <tr>
         <td class="label"><?php echo $block->getShippingLabel() ?><div id="shipping_amount_adv"></div></td>
-        <td><input type="text" name="creditmemo[shipping_amount]" value="<?php echo $block->getShippingAmount()?>" class="input-text not-negative-amount" id="shipping_amount" /></td>
+        <td>
+            <input type="text"
+                   name="creditmemo[shipping_amount]"
+                   value="<?php echo $block->getShippingAmount()?>"
+                   class="input-text admin__control-text not-negative-amount"
+                   id="shipping_amount" />
+        </td>
     </tr>
     <tr>
         <td class="label"><?php echo __('Adjustment Refund') ?><div id="adjustment_positive_adv"></div></td>
-        <td><input type="text" name="creditmemo[adjustment_positive]" value="<?php echo $_source->getBaseAdjustmentFeePositive()*1 ?>" class="input-text not-negative-amount" id="adjustment_positive" /></td>
+        <td>
+            <input type="text"
+                   name="creditmemo[adjustment_positive]"
+                   value="<?php echo $_source->getBaseAdjustmentFeePositive()*1 ?>"
+                   class="input-text admin__control-text not-negative-amount"
+                   id="adjustment_positive" />
+        </td>
     </tr>
     <tr>
         <td class="label"><?php echo __('Adjustment Fee') ?><div id="adjustment_negative_adv"></div></td>
-        <td><input type="text" name="creditmemo[adjustment_negative]" value="<?php echo $_source->getBaseAdjustmentFeeNegative()*1 ?>" class="input-text not-negative-amount" id="adjustment_negative"/>
-        <script>
-require(['prototype'], function(){
+        <td>
+            <input type="text"
+                   name="creditmemo[adjustment_negative]"
+                   value="<?php echo $_source->getBaseAdjustmentFeeNegative()*1 ?>"
+                   class="input-text admin__control-text not-negative-amount"
+                   id="adjustment_negative"/>
+            <script>
+                require(['prototype'], function(){
 
-//<![CDATA[
-Validation.addAllThese([
-    ['not-negative-amount', '<?php echo __('Please enter a positive number in this field.') ?>', function(v) {
-        if(v.length)
-            return /^\s*\d+([,.]\d+)*\s*%?\s*$/.test(v);
-        else
-            return true;
-    }]
-]);
+                //<![CDATA[
+                Validation.addAllThese([
+                    ['not-negative-amount', '<?php echo __('Please enter a positive number in this field.') ?>', function(v) {
+                        if(v.length)
+                            return /^\s*\d+([,.]\d+)*\s*%?\s*$/.test(v);
+                        else
+                            return true;
+                    }]
+                ]);
 
-if ($('shipping_amount')) {
-    $('shipping_amount').advaiceContainer = $('shipping_amount_adv');
-    unblockSubmit('shipping_amount');
-}
-if ($('adjustment_positive')) {
-    $('adjustment_positive').advaiceContainer = $('adjustment_positive_adv');
-    unblockSubmit('adjustment_positive');
-}
-if ($('adjustment_negative')) {
-    $('adjustment_negative').advaiceContainer = $('adjustment_negative_adv');
-    unblockSubmit('adjustment_negative');
-}
+                if ($('shipping_amount')) {
+                    $('shipping_amount').advaiceContainer = $('shipping_amount_adv');
+                    unblockSubmit('shipping_amount');
+                }
+                if ($('adjustment_positive')) {
+                    $('adjustment_positive').advaiceContainer = $('adjustment_positive_adv');
+                    unblockSubmit('adjustment_positive');
+                }
+                if ($('adjustment_negative')) {
+                    $('adjustment_negative').advaiceContainer = $('adjustment_negative_adv');
+                    unblockSubmit('adjustment_negative');
+                }
 
-function unblockSubmit(id) {
-    $(id).observe('focus', function(event) {
-        if ($$('button[class="scalable update-button disabled"]').size() > 0) {
-            enableElements('submit-button');
-        }
-    });
-}
-//]]>
+                function unblockSubmit(id) {
+                    $(id).observe('focus', function(event) {
+                        if ($$('button[class="scalable update-button disabled"]').size() > 0) {
+                            enableElements('submit-button');
+                        }
+                    });
+                }
+                //]]>
 
-});
-</script>
+                });
+            </script>
         </td>
     </tr>
 
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/view/form.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/view/form.phtml
index df2f092e4f8aa839320ce77450ec4fceab97d5e4..ee8ec752df51752961a3b64a2bf415a4a3174ccb 100644
--- a/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/view/form.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/view/form.phtml
@@ -9,51 +9,56 @@
 ?>
 <?php  $_order = $block->getCreditmemo()->getOrder() ?>
 <?php echo $block->getChildHtml('order_info') ?>
-<div class="clearfix">
-<?php if (!$_order->getIsVirtual()): ?>
-<div class="order-payment-method">
-<?php else: ?>
-<div class="order-payment-method order-payment-method-virtual">
-<?php endif; ?>
-    <?php /* Billing Address */?>
-    <div class="fieldset-wrapper">
-        <div class="fieldset-wrapper-title">
-            <span class="title"><?php echo __('Payment Information') ?></span>
-        </div>
-        <div><?php echo $block->getChildHtml('order_payment') ?></div>
-        <div class="order-payment-currency"><?php echo __('The order was placed using %1.', $_order->getOrderCurrencyCode()) ?></div>
-        <div class="order-payment-additional"><?php echo $block->getChildHtml('order_payment_additional'); ?></div>
+<section class="admin__page-section">
+    <div class="admin__page-section-title">
+        <span class="title"><?php echo __('Payment &amp; Shipping Method') ?></span>
     </div>
-</div>
-<?php if (!$_order->getIsVirtual()): ?>
-<div class="order-shipping-address">
-    <?php /* Shipping Address */ ?>
-    <div class="fieldset-wrapper">
-        <div class="fieldset-wrapper-title">
-            <span class="title"><?php echo __('Shipping Information') ?></span>
+    <div class="admin__page-section-content">
+
+        <?php if (!$_order->getIsVirtual()): ?>
+        <div class="admin__page-section-item order-payment-method">
+        <?php else: ?>
+        <div class="admin__page-section-item order-payment-method order-payment-method-virtual">
+        <?php endif; ?>
+            <?php /* Billing Address */?>
+            <div class="admin__page-section-item-title">
+                <span class="title"><?php echo __('Payment Information') ?></span>
+            </div>
+            <div class="admin__page-section-item-content">
+                <div><?php echo $block->getChildHtml('order_payment') ?></div>
+                <div class="order-payment-currency"><?php echo __('The order was placed using %1.', $_order->getOrderCurrencyCode()) ?></div>
+                <div class="order-payment-additional"><?php echo $block->getChildHtml('order_payment_additional'); ?></div>
+            </div>
         </div>
-        <div class="shipping-description-wrapper">
-            <div class="shipping-description-title"><?php echo $block->escapeHtml($_order->getShippingDescription()) ?></div>
-            <div class="shipping-description-content">
-                <?php echo __('Total Shipping Charges'); ?>:
 
-                <?php if ($this->helper('Magento\Tax\Helper\Data')->displayShippingPriceIncludingTax()): ?>
-                    <?php $_excl = $block->displayShippingPriceInclTax($_order); ?>
-                <?php else: ?>
-                    <?php $_excl = $block->displayPriceAttribute('shipping_amount', false, ' '); ?>
-                <?php endif; ?>
-                <?php $_incl = $block->displayShippingPriceInclTax($_order); ?>
+        <?php if (!$_order->getIsVirtual()): ?>
+        <div class="admin__page-section-item order-shipping-address">
+            <?php /* Shipping Address */ ?>
+            <div class="admin__page-section-item-title">
+                <span class="title"><?php echo __('Shipping Information') ?></span>
+            </div>
+            <div class="shipping-description-wrapper admin__page-section-item-content">
+                <div class="shipping-description-title"><?php echo $block->escapeHtml($_order->getShippingDescription()) ?></div>
+                <div class="shipping-description-content">
+                    <?php echo __('Total Shipping Charges'); ?>:
 
-                <?php echo $_excl; ?>
-                <?php if ($this->helper('Magento\Tax\Helper\Data')->displayShippingBothPrices() && $_incl != $_excl): ?>
-                    (<?php echo __('Incl. Tax'); ?> <?php echo $_incl; ?>)
-                <?php endif; ?>
+                    <?php if ($this->helper('Magento\Tax\Helper\Data')->displayShippingPriceIncludingTax()): ?>
+                        <?php $_excl = $block->displayShippingPriceInclTax($_order); ?>
+                    <?php else: ?>
+                        <?php $_excl = $block->displayPriceAttribute('shipping_amount', false, ' '); ?>
+                    <?php endif; ?>
+                    <?php $_incl = $block->displayShippingPriceInclTax($_order); ?>
+
+                    <?php echo $_excl; ?>
+                    <?php if ($this->helper('Magento\Tax\Helper\Data')->displayShippingBothPrices() && $_incl != $_excl): ?>
+                        (<?php echo __('Incl. Tax'); ?> <?php echo $_incl; ?>)
+                    <?php endif; ?>
+                </div>
             </div>
         </div>
+        <?php endif; ?>
     </div>
-</div>
-<?php endif; ?>
-</div>
+</section>
 <?php $_items = $block->getCreditmemo()->getAllItems() ?>
 
 <?php if (count($_items)): ?>
@@ -61,24 +66,30 @@
     <?php echo $block->getChildHtml('creditmemo_items') ?>
 </div>
 <?php else: ?>
-<div class="fieldset-wrapper">
-    <div class="fieldset-wrapper-title">
+<section class="admin__page-section">
+    <div class="admin__page-section-title">
         <span class="title"><?php echo __('Items Refunded') ?></span>
     </div>
-    <div class="no-items"><?php echo __('No Items') ?></div>
-</div>
+    <div class="no-items admin__page-section-content"><?php echo __('No Items') ?></div>
+</section>
 <?php endif; ?>
-<div class="clearfix">
-    <div class="order-comments-history">
-        <div class="fieldset-wrapper">
-            <div class="fieldset-wrapper-title"><span class="title"><?php echo __('Credit Memo History') ?></span></div>
-            <fieldset><?php echo $block->getChildHtml('order_comments') ?></fieldset>
-        </div>
+
+<section class="admin__page-section">
+    <div class="admin__page-section-title">
+        <span class="title"><?php echo __('Memo Total') ?></span>
     </div>
-    <div class="order-totals">
-        <div class="fieldset-wrapper" id="history_form">
-            <div class="fieldset-wrapper-title"><span class="title"><?php echo __('Credit Memo Totals') ?></span></div>
-            <div><?php echo $block->getChildHtml('creditmemo_totals') ?></div>
+    <div class="admin__page-section-content">
+        <div class="admin__page-section-item order-comments-history">
+            <div class="admin__page-section-item-title">
+                <span class="title"><?php echo __('Credit Memo History') ?></span>
+            </div>
+            <div class="admin__page-section-item-content"><?php echo $block->getChildHtml('order_comments') ?></div>
+        </div>
+        <div class="admin__page-section-item order-totals" id="history_form">
+            <div class="admin__page-section-item-title">
+                <span class="title"><?php echo __('Credit Memo Totals') ?></span>
+            </div>
+            <div class="admin__page-section-content"><?php echo $block->getChildHtml('creditmemo_totals') ?></div>
         </div>
     </div>
-</div>
+</section>
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/view/items.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/view/items.phtml
index a75e830aaacb88ff6ec19021c620544ef227bac2..3618871f0c7cac6da817fc5fe72ca8073cb97777 100644
--- a/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/view/items.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/view/items.phtml
@@ -8,12 +8,12 @@
 
 ?>
 <?php $_items = $block->getCreditmemo()->getAllItems() ?>
-<div class="fieldset-wrapper">
-    <div class="fieldset-wrapper-title">
+<div class="admin__page-section">
+    <div class="admin__page-section-title">
         <span class="title"><?php echo __('Items Refunded') ?></span>
     </div>
-    <div class="grid">
-        <table cellspacing="0" class="data">
+    <div class="admin__page-section-content">
+        <table class="data-table admin__table-primary order-creditmemo-tables">
             <thead>
                 <tr class="headings">
                     <th class="col-product"><span><?php echo __('Product') ?></span></th>
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/giftoptions.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/giftoptions.phtml
index c837566257032cc8cd89c1c7e5be2e0a8d0d4edc..bab344f25065b2bfba1be65196fa2a28068d6044 100644
--- a/app/code/Magento/Sales/view/adminhtml/templates/order/giftoptions.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/order/giftoptions.phtml
@@ -8,8 +8,8 @@
 
 ?>
 <?php if ($block->getChildHtml()): ?>
-<div class="admin__fieldset-wrapper order-gift-options">
-    <div class="admin__fieldset-wrapper-title"><strong class="title"><?php echo __('Gift Options') ?></strong></div>
+<section class="admin__page-section order-gift-options">
+    <div class="admin__page-section-title"><strong class="title"><?php echo __('Gift Options') ?></strong></div>
     <?php echo $block->getChildHtml() ?>
-</div>
+</section>
 <?php endif ?>
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/invoice/create/form.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/invoice/create/form.phtml
index ce938f85d2764a1168ee9fb00d92ad9d42a2f84c..b0319ea9791f7b35afe27d1e647e6e9859448e03 100644
--- a/app/code/Magento/Sales/view/adminhtml/templates/order/invoice/create/form.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/order/invoice/create/form.phtml
@@ -7,68 +7,72 @@
 // @codingStandardsIgnoreFile
 
 ?>
-<form id="edit_form" method="post" action="<?php echo $block->getSaveUrl() ?>">
+<form id="edit_form" class="order-invoice-edit" method="post" action="<?php echo $block->getSaveUrl() ?>">
     <?php echo $block->getBlockHtml('formkey')?>
     <?php $_order = $block->getInvoice()->getOrder() ?>
     <?php echo $block->getChildHtml('order_info') ?>
-    <?php if (!$_order->getIsVirtual()): ?>
-    <div class="clearfix">
-    <?php endif; ?>
 
-    <div class="order-payment-method<?php if ($_order->getIsVirtual()): ?> order-payment-method-virtual<?php endif; ?>">
-        <div class="fieldset-wrapper">
-            <div class="fieldset-wrapper-title">
-                <span class="title"><?php echo __('Payment Information') ?></span>
-            </div>
-            <div><?php echo $block->getChildHtml('order_payment') ?></div>
-            <div class="order-payment-currency"><?php echo __('The order was placed using %1.', $_order->getOrderCurrencyCode()) ?></div>
-            <div class="order-payment-additional"><?php echo $block->getChildHtml('order_payment_additional'); ?></div>
+    <section class="admin__page-section">
+        <div class="admin__page-section-title">
+            <span class="title"><?php echo __('Payment &amp; Shipping Method') ?></span>
         </div>
-    </div>
-    <?php if (!$_order->getIsVirtual()): ?>
-    <div class="order-shipping-address">
-        <?php /*Shipping Address */ ?>
-        <div class="fieldset-wrapper">
-            <div class="fieldset-wrapper-title">
-                <span class="title"><?php echo __('Shipping Information') ?></span>
+        <div class="admin__page-section-content">
+            <div class="admin__page-section-item order-payment-method<?php if ($_order->getIsVirtual()): ?> order-payment-method-virtual<?php endif; ?>">
+                <div class="admin__page-section-item-title">
+                    <span class="title"><?php echo __('Payment Information') ?></span>
+                </div>
+                <div class="admin__page-section-item-content">
+                    <div><?php echo $block->getChildHtml('order_payment') ?></div>
+                    <div class="order-payment-currency"><?php echo __('The order was placed using %1.', $_order->getOrderCurrencyCode()) ?></div>
+                    <div class="order-payment-additional"><?php echo $block->getChildHtml('order_payment_additional'); ?></div>
+                </div>
             </div>
-            <div class="shipping-description-wrapper">
-                <div class="shipping-description-title"><?php echo $block->escapeHtml($_order->getShippingDescription()) ?></div>
-                <div class="shipping-description-content">
-                    <?php echo __('Total Shipping Charges'); ?>:
+            <?php if (!$_order->getIsVirtual()): ?>
+            <div class="admin__page-section-item order-shipping-address">
+                <?php /*Shipping Address */ ?>
+                <div class="admin__page-section-item-title">
+                    <span class="title"><?php echo __('Shipping Information') ?></span>
+                </div>
+                <div class="admin__page-section-item-content">
+                    <div class="shipping-description-wrapper">
+                        <div class="shipping-description-title"><?php echo $block->escapeHtml($_order->getShippingDescription()) ?></div>
+                        <div class="shipping-description-content">
+                            <?php echo __('Total Shipping Charges'); ?>:
 
-                    <?php if ($this->helper('Magento\Tax\Helper\Data')->displayShippingPriceIncludingTax()): ?>
-                        <?php $_excl = $block->displayShippingPriceInclTax($_order); ?>
-                    <?php else: ?>
-                        <?php $_excl = $block->displayPriceAttribute('shipping_amount', false, ' '); ?>
-                    <?php endif; ?>
-                    <?php $_incl = $block->displayShippingPriceInclTax($_order); ?>
+                            <?php if ($this->helper('Magento\Tax\Helper\Data')->displayShippingPriceIncludingTax()): ?>
+                                <?php $_excl = $block->displayShippingPriceInclTax($_order); ?>
+                            <?php else: ?>
+                                <?php $_excl = $block->displayPriceAttribute('shipping_amount', false, ' '); ?>
+                            <?php endif; ?>
+                            <?php $_incl = $block->displayShippingPriceInclTax($_order); ?>
 
-                    <?php echo $_excl; ?>
-                    <?php if ($this->helper('Magento\Tax\Helper\Data')->displayShippingBothPrices() && $_incl != $_excl): ?>
-                        (<?php echo __('Incl. Tax'); ?> <?php echo $_incl; ?>)
+                            <?php echo $_excl; ?>
+                            <?php if ($this->helper('Magento\Tax\Helper\Data')->displayShippingBothPrices() && $_incl != $_excl): ?>
+                                (<?php echo __('Incl. Tax'); ?> <?php echo $_incl; ?>)
+                            <?php endif; ?>
+                        </div>
+                    </div>
+                    <?php if ($block->canCreateShipment() && $block->canShipPartiallyItem()): ?>
+                    <div class="admin__field admin__field-option">
+                        <input type="checkbox" name="invoice[do_shipment]" id="invoice_do_shipment" value="1"
+                               class="admin__control-checkbox" <?php echo $block->hasInvoiceShipmentTypeMismatch() ? ' disabled="disabled"' : '' ?> />
+                        <label for="invoice_do_shipment"
+                               class="admin__field-label"><span><?php echo __('Create Shipment') ?></span></label>
+                    </div>
+                    <?php if ($block->hasInvoiceShipmentTypeMismatch()): ?>
+                        <small><?php echo __('Invoice and shipment types do not match for some items on this order. You can create a shipment only after creating the invoice.') ?></small>
+                        <?php endif; ?>
                     <?php endif; ?>
+                    <div id="tracking" style="display:none;"><?php echo $block->getChildHtml('tracking', false) ?></div>
                 </div>
             </div>
-            <?php if ($block->canCreateShipment() && $block->canShipPartiallyItem()): ?>
-            <div>
-                <label for="invoice_do_shipment" class="normal"><?php echo __('Create Shipment') ?></label>
-                <input type="checkbox" name="invoice[do_shipment]" id="invoice_do_shipment" value="1" <?php echo $block->hasInvoiceShipmentTypeMismatch() ? ' disabled="disabled"' : '' ?> />
-            </div>
-            <?php if ($block->hasInvoiceShipmentTypeMismatch()): ?>
-                <small><?php echo __('Invoice and shipment types do not match for some items on this order. You can create a shipment only after creating the invoice.') ?></small>
-                <?php endif; ?>
             <?php endif; ?>
-            <div id="tracking" style="display:none;"><?php echo $block->getChildHtml('tracking', false) ?></div>
         </div>
-    </div>
-    <?php endif; ?>
-
-    </div>
+    </section>
 
-    <div id="invoice_item_container">
+    <section id="invoice_item_container">
         <?php echo $block->getChildHtml('order_items') ?>
-    </div>
+    </section>
 </form>
 <script>
 require(['prototype'], function(){
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/invoice/create/items.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/invoice/create/items.phtml
index 118eca64172985d63ab5794a01f691cd21ada117..883f04cb7f3eb528cde7db31c8254c1dc197a566 100644
--- a/app/code/Magento/Sales/view/adminhtml/templates/order/invoice/create/items.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/order/invoice/create/items.phtml
@@ -8,13 +8,13 @@
 
 ?>
 
-<div class="fieldset-wrapper">
-    <div class="fieldset-wrapper-title">
+<section class="admin__page-section">
+    <div class="admin__page-section-title">
         <?php $_itemsGridLabel = $block->getForcedShipmentCreate() ? 'Items to Invoice and Ship' : 'Items to Invoice'; ?>
         <span class="title"><?php echo __('%1', $_itemsGridLabel) ?></span>
     </div>
-    <div class="grid">
-        <table cellspacing="0" class="data">
+    <div class="admin__page-section-content grid">
+        <table class="data-table admin__table-primary order-invoice-tables">
             <thead>
                 <tr class="headings">
                     <th class="col-product"><span><?php echo __('Product') ?></span></th>
@@ -50,45 +50,55 @@
             <?php endforeach; ?>
         </table>
     </div>
-</div>
+</section>
 
 <?php $orderTotalBar = $block->getChildHtml('order_totalbar'); ?>
 
 <?php if (!empty($orderTotalBar)): ?>
-<div class="fieldset-wrapper">
+<section class="admin__page-section">
     <?php echo $orderTotalBar; ?>
-</div>
+</section>
 <?php endif; ?>
 
-<div class="clearfix">
-    <div class="order-comments-history">
-        <div class="fieldset-wrapper">
-            <div class="fieldset-wrapper-title">
+<section class="admin__page-section">
+    <div class="admin__page-section-title">
+        <span class="title"><?php echo __('Order Total') ?></span>
+    </div>
+    <div class="admin__page-section-content">
+        <div class="admin__page-section-item order-comments-history">
+            <div class="admin__page-section-item-title">
                 <span class="title"><?php echo __('Invoice History') ?></span>
             </div>
-            <div id="history_form" class="order-history-form">
-                <label class="normal" for="invoice_comment_text"><?php echo __('Invoice Comments') ?></label>
-                <textarea id="invoice_comment_text" name="invoice[comment_text]" rows="3" cols="5"><?php echo $block->getInvoice()->getCommentText(); ?></textarea>
+            <div id="history_form" class="admin__page-section-item-content order-history-form">
+                <div class="admin__field">
+                    <label for="invoice_comment_text" class="admin__field-label">
+                        <span><?php echo __('Invoice Comments') ?></span>
+                    </label>
+                    <div class="admin__field-control">
+                        <textarea id="invoice_comment_text" name="invoice[comment_text]" class="admin__control-textarea"
+                                  rows="3" cols="5"><?php echo $block->getInvoice()->getCommentText(); ?></textarea>
+                    </div>
+                </div>
             </div>
         </div>
-    </div>
 
-    <div class="order-totals">
-        <div class="fieldset-wrapper" id="invoice_totals">
-            <div class="fieldset-wrapper-title">
+        <div id="invoice_totals" class="admin__page-section-item order-totals">
+            <div class="admin__page-section-item-title">
                 <span class="title"><?php echo __('Invoice Totals') ?></span>
             </div>
-            <div class="order-totals-actions">
+            <div class="admin__page-section-item-content order-totals-actions">
                 <?php echo $block->getChildHtml('invoice_totals') ?>
                 <?php if ($block->isCaptureAllowed()): ?>
                 <?php if ($block->canCapture()):?>
-                    <div>
-                    <!--
-                      <label for="invoice_do_capture" class="normal"><?php echo __('Capture Amount') ?></label>
-                      <input type="checkbox" name="invoice[do_capture]" id="invoice_do_capture" value="1" checked/>
-                    -->
-                      <label for="invoice_do_capture" class="normal"><?php echo __('Amount') ?></label>
-                      <select name="invoice[capture_case]">
+                    <div class="admin__field">
+                        <?php
+                        /*
+                        <label for="invoice_do_capture" class="normal"><?php echo __('Capture Amount') ?></label>
+                        <input type="checkbox" name="invoice[do_capture]" id="invoice_do_capture" value="1" checked/>
+                        */
+                        ?>
+                      <label for="invoice_do_capture" class="admin__field-label"><?php echo __('Amount') ?></label>
+                      <select class="admin__control-select" name="invoice[capture_case]">
                           <option value="online"><?php echo __('Capture Online') ?></option>
                           <option value="offline"><?php echo __('Capture Offline') ?></option>
                           <option value="not_capture"><?php echo __('Not Capture') ?></option>
@@ -99,14 +109,16 @@
                     <div><?php echo __('The invoice will be created offline without the payment gateway.') ?></div>
                 <?php endif?>
                 <?php endif; ?>
-                <div class="field choice field-append">
-                    <input id="notify_customer" name="invoice[comment_customer_notify]" value="1" type="checkbox" />
-                    <label class="normal" for="notify_customer"><?php echo __('Append Comments') ?></label>
+                <div class="admin__field admin__field-option field-append">
+                    <input id="notify_customer" name="invoice[comment_customer_notify]" value="1" type="checkbox"
+                           class="admin__control-checkbox" />
+                    <label class="admin__field-label" for="notify_customer"><?php echo __('Append Comments') ?></label>
                 </div>
                 <?php if ($block->canSendInvoiceEmail()): ?>
-                <div class="field choice field-email">
-                    <input id="send_email" name="invoice[send_email]" value="1" type="checkbox" />
-                    <label class="normal" for="send_email"><?php echo __('Email Copy of Invoice') ?></label>
+                <div class="admin__field admin__field-option field-email">
+                    <input id="send_email" name="invoice[send_email]" value="1" type="checkbox"
+                           class="admin__control-checkbox" />
+                    <label class="admin__field-label" for="send_email"><?php echo __('Email Copy of Invoice') ?></label>
                 </div>
                 <?php endif; ?>
                 <div class="actions">
@@ -115,7 +127,7 @@
             </div>
         </div>
     </div>
-</div>
+</section>
 
 <script>
 require(['jquery', 'prototype'], function($){
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/invoice/create/items/renderer/default.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/invoice/create/items/renderer/default.phtml
index f416f1ba7b5983e955099a45ce5c887a23d5ae2e..45b53a6d05ea0c65132c86050ed7ab03d30dc530 100644
--- a/app/code/Magento/Sales/view/adminhtml/templates/order/invoice/create/items/renderer/default.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/order/invoice/create/items/renderer/default.phtml
@@ -17,7 +17,9 @@
     <td class="col-qty"><?php echo $block->getColumnHtml($_item, 'qty') ?></td>
     <td class="col-qty-invoice">
     <?php if ($block->canEditQty()) : ?>
-        <input type="text" class="input-text qty-input" name="invoice[items][<?php echo $_item->getOrderItemId() ?>]" value="<?php echo $_item->getQty()*1 ?>"/>
+        <input type="text" class="input-text admin__control-text qty-input"
+               name="invoice[items][<?php echo $_item->getOrderItemId() ?>]"
+               value="<?php echo $_item->getQty()*1 ?>"/>
     <?php else : ?>
         <?php echo $_item->getQty()*1 ?>
     <?php endif; ?>
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/invoice/view/form.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/invoice/view/form.phtml
index d1a08dfeb6d6b4e2d6f654caf88e93922064cc2b..cd625596b541da95d9d24de7069c0d33c71117af 100644
--- a/app/code/Magento/Sales/view/adminhtml/templates/order/invoice/view/form.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/order/invoice/view/form.phtml
@@ -11,84 +11,87 @@
 <?php $_order = $_invoice->getOrder() ?>
 <?php echo $block->getChildHtml('order_info') ?>
 
-<?php /* opening div is in app\code\Magento\Sales\view\adminhtml\order\view\info.phtml */?>
-
-<?php if (!$_order->getIsVirtual()): ?>
-<div class="clearfix"> <?php /* if opening div from app\code\Magento\Sales\view\adminhtml\order\view\info.phtml was closed there */?>
-<?php endif; ?>
-
-    <div class="order-payment-method<?php if ($_order->getIsVirtual()): ?> order-payment-method-virtual<?php endif; ?>">
-        <?php /*Billing Address */ ?>
-        <div class="fieldset-wrapper">
-            <div class="fieldset-wrapper-title">
+<section class="admin__page-section order-view-billing-shipping">
+    <div class="admin__page-section-title">
+        <span class="title"><?php echo __('Payment &amp; Shipping Method') ?></span>
+    </div>
+    <div class="admin__page-section-content">
+        <div class="admin__page-section-item order-payment-method<?php if ($_order->getIsVirtual()): ?> order-payment-method-virtual<?php endif; ?> admin__fieldset-wrapper">
+            <?php /*Billing Address */ ?>
+            <div class="admin__page-section-item-title">
                 <span class="title"><?php echo __('Payment Information') ?></span>
             </div>
-            <div><?php echo $block->getChildHtml('order_payment') ?></div>
-            <div class="order-payment-currency"><?php echo __('The order was placed using %1.', $_order->getOrderCurrencyCode()) ?></div>
-            <div class="order-payment-additional"><?php echo $block->getChildHtml('order_payment_additional'); ?></div>
+            <div class="admin__page-section-item-content">
+                <div><?php echo $block->getChildHtml('order_payment') ?></div>
+                <div class="order-payment-currency">
+                    <?php echo __('The order was placed using %1.', $_order->getOrderCurrencyCode()) ?>
+                </div>
+                <div class="order-payment-additional"><?php echo $block->getChildHtml('order_payment_additional'); ?></div>
+            </div>
         </div>
-    </div>
 
-    <?php if (!$_order->getIsVirtual()): ?>
-    <div class="order-shipping-address">
-        <?php /*Shipping Address */ ?>
-        <div class="fieldset-wrapper">
-            <div class="fieldset-wrapper-title">
-                <span class="title"><?php echo __('Shipping Information') ?></span>
-            </div>
-            <div class="shipping-description-wrapper">
-                <div class="shipping-description-title"><?php echo $block->escapeHtml($_order->getShippingDescription()) ?></div>
-                <div class="shipping-description-content">
-                    <?php echo __('Total Shipping Charges'); ?>:
+        <?php if (!$_order->getIsVirtual()): ?>
+            <div class="admin__page-section-item order-shipping-address">
+                <?php /*Shipping Address */ ?>
+                <div class="admin__page-section-item-title">
+                    <span class="title"><?php echo __('Shipping Information') ?></span>
+                </div>
+                <div class="admin__page-section-item-content shipping-description-wrapper">
+                    <div class="shipping-description-title">
+                        <?php echo $block->escapeHtml($_order->getShippingDescription()) ?>
+                    </div>
+                    <div class="shipping-description-content">
+                        <?php echo __('Total Shipping Charges'); ?>:
 
-                    <?php if ($this->helper('Magento\Tax\Helper\Data')->displayShippingPriceIncludingTax()): ?>
-                        <?php $_excl = $block->displayShippingPriceInclTax($_order); ?>
-                    <?php else: ?>
-                        <?php $_excl = $block->displayPriceAttribute('shipping_amount', false, ' '); ?>
-                    <?php endif; ?>
-                    <?php $_incl = $block->displayShippingPriceInclTax($_order); ?>
+                        <?php if ($this->helper('Magento\Tax\Helper\Data')->displayShippingPriceIncludingTax()): ?>
+                            <?php $_excl = $block->displayShippingPriceInclTax($_order); ?>
+                        <?php else: ?>
+                            <?php $_excl = $block->displayPriceAttribute('shipping_amount', false, ' '); ?>
+                        <?php endif; ?>
+                        <?php $_incl = $block->displayShippingPriceInclTax($_order); ?>
 
-                    <?php echo $_excl; ?>
-                    <?php if ($this->helper('Magento\Tax\Helper\Data')->displayShippingBothPrices() && $_incl != $_excl): ?>
-                        (<?php echo __('Incl. Tax'); ?> <?php echo $_incl; ?>)
-                    <?php endif; ?>
-                    <div><?php echo $block->getChildHtml('shipment_tracking') ?></div>
+                        <?php echo $_excl; ?>
+                        <?php if ($this->helper('Magento\Tax\Helper\Data')->displayShippingBothPrices() && $_incl != $_excl): ?>
+                            (<?php echo __('Incl. Tax'); ?> <?php echo $_incl; ?>)
+                        <?php endif; ?>
+                        <div><?php echo $block->getChildHtml('shipment_tracking') ?></div>
+                    </div>
                 </div>
             </div>
-        </div>
-    </div>
-    <?php endif; ?>
+        <?php endif; ?>
 
-</div>
+    </div>
+</section>
 
-<div class="fieldset-wrapper">
-    <div class="fieldset-wrapper-title">
+<section class="admin__page-section">
+    <div class="admin__page-section-title">
         <span class="title"><?php echo __('Items Invoiced') ?></span>
     </div>
 
-    <div id="invoice_item_container">
+    <div id="invoice_item_container" class="admin__page-section-content">
         <?php echo $block->getChildHtml('invoice_items') ?>
     </div>
-</div>
+</section>
 
-<div class="clearfix">
-    <div class="order-comments-history">
-        <div class="fieldset-wrapper">
-            <div class="fieldset-wrapper-title">
+<section class="admin__page-section">
+    <div class="admin__page-section-title">
+        <span class="title"><?php echo __('Order Total') ?></span>
+    </div>
+    <div class="admin__page-section-content">
+        <div class="admin__page-section-item order-comments-history">
+            <div class="admin__page-section-item-title">
                 <span class="title"><?php echo __('Invoice History') ?></span>
             </div>
-            <fieldset>
+            <div class="admin__page-section-item-content">
                 <?php echo $block->getChildHtml('order_comments') ?>
-            </fieldset>
+            </div>
         </div>
-    </div>
 
-    <div class="order-totals">
-        <div class="fieldset-wrapper" id="history_form">
-            <div class="fieldset-wrapper-title">
+        <div id="history_form" class="admin__page-section-item order-totals">
+            <div class="admin__page-section-item-title">
                 <span class="title"><?php echo __('Invoice Totals') ?></span>
             </div>
             <?php echo $block->getChildHtml('invoice_totals') ?>
         </div>
     </div>
-</div>
+</section>
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/invoice/view/items.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/invoice/view/items.phtml
index 2dd825764ac916f3940e749d2a81798dea4ae633..9298795db0b62507f426147a6d643a0eefca8d03 100644
--- a/app/code/Magento/Sales/view/adminhtml/templates/order/invoice/view/items.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/order/invoice/view/items.phtml
@@ -8,7 +8,7 @@
 
 ?>
 <div class="grid">
-    <table class="data order-tables">
+    <table class="data-table admin__table-primary order-invoice-tables">
         <thead>
             <tr class="headings">
                 <th class="col-product"><span><?php echo __('Product') ?></span></th>
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/totals.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/totals.phtml
index 06b1e692a036a4ff9d9659e835b81fe4142ca137..45b816084520bbe14c11af4050b0cf5d533156e2 100644
--- a/app/code/Magento/Sales/view/adminhtml/templates/order/totals.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/order/totals.phtml
@@ -15,53 +15,56 @@
     <?php echo $block->getChildHtml('footer'); ?>
 </table>
 <?php endif;*/ ?>
-<table class="data-table table-info order-subtotal">
+<table class="data-table admin__table-secondary order-subtotal-table">
     <?php $_totals = $block->getTotals('footer')?>
+
     <?php if ($_totals):?>
-    <tfoot>
-    <?php foreach ($block->getTotals('footer') as $_code => $_total): ?>
-        <?php if ($_total->getBlockName()): ?>
-            <?php echo $block->getChildHtml($_total->getBlockName(), false); ?>
-        <?php else:?>
-        <tr class="col-<?php echo $_code?>">
-            <td <?php echo $block->getLabelProperties()?> class="label">
-                <strong><?php echo $block->escapeHtml($_total->getLabel()); ?></strong>
-            </td>
-            <td <?php echo $block->getValueProperties()?>>
-                <strong><?php echo $block->formatValue($_total) ?></strong>
-            </td>
-        </tr>
-        <?php endif?>
-    <?php endforeach?>
-    </tfoot>
+        <tfoot>
+            <?php foreach ($block->getTotals('footer') as $_code => $_total): ?>
+                <?php if ($_total->getBlockName()): ?>
+                    <?php echo $block->getChildHtml($_total->getBlockName(), false); ?>
+                <?php else:?>
+                <tr class="col-<?php echo $_code?>">
+                    <td <?php echo $block->getLabelProperties()?> class="label">
+                        <strong><?php echo $block->escapeHtml($_total->getLabel()); ?></strong>
+                    </td>
+                    <td <?php echo $block->getValueProperties()?>>
+                        <strong><?php echo $block->formatValue($_total) ?></strong>
+                    </td>
+                </tr>
+                <?php endif?>
+            <?php endforeach?>
+        </tfoot>
     <?php endif?>
 
     <?php $_totals = $block->getTotals('')?>
     <?php if ($_totals):?>
-    <tbody>
-    <?php foreach ($_totals as $_code => $_total): ?>
-        <?php if ($_total->getBlockName()): ?>
-            <?php echo $block->getChildHtml($_total->getBlockName(), false); ?>
-        <?php else:?>
-        <tr class="col-<?php echo $_code?>">
-            <td <?php echo $block->getLabelProperties()?> class="label">
-                <?php if ($_total->getStrong()):?>
-                <strong><?php echo $block->escapeHtml($_total->getLabel()); ?></strong>
+        <tbody>
+            <?php foreach ($_totals as $_code => $_total): ?>
+                <?php if ($_total->getBlockName()): ?>
+                    <?php echo $block->getChildHtml($_total->getBlockName(), false); ?>
                 <?php else:?>
-                <?php echo $block->escapeHtml($_total->getLabel()); ?>
+                    <tr class="col-<?php echo $_code?>">
+                        <td <?php echo $block->getLabelProperties()?> class="label">
+                            <?php if ($_total->getStrong()):?>
+                            <strong><?php echo $block->escapeHtml($_total->getLabel()); ?></strong>
+                            <?php else:?>
+                            <?php echo $block->escapeHtml($_total->getLabel()); ?>
+                            <?php endif?>
+                        </td>
+
+                        <?php if ($_total->getStrong()):?>
+                            <td <?php echo $block->getValueProperties()?>>
+                                <strong><?php echo $block->formatValue($_total) ?></strong>
+                            </td>
+                        <?php else:?>
+                            <td <?php echo $block->getValueProperties()?>>
+                                <span><?php echo $block->formatValue($_total) ?></span>
+                            </td>
+                        <?php endif?>
+                    </tr>
                 <?php endif?>
-            </td>
-            <?php if ($_total->getStrong()):?>
-            <td <?php echo $block->getValueProperties()?>>
-                <strong><?php echo $block->formatValue($_total) ?></strong>
-            <?php else:?>
-            <td <?php echo $block->getValueProperties()?>>
-                <?php echo $block->formatValue($_total) ?>
-            <?php endif?>
-            </td>
-        </tr>
-        <?php endif?>
-    <?php endforeach?>
-    </tbody>
+            <?php endforeach?>
+        </tbody>
     <?php endif?>
 </table>
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/view/form.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/view/form.phtml
index 2ccc60117a6ea662ff928690563244c684be7252..ea8956727f637d25ca32d23a10a3aa34648fda2e 100644
--- a/app/code/Magento/Sales/view/adminhtml/templates/order/view/form.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/order/view/form.phtml
@@ -4,4 +4,4 @@
  * See COPYING.txt for license details.
  */
 ?>
-<div class="entry-edit" id="sales_order_view"></div>
+<div class="entry-edit order-view" id="sales_order_view"></div>
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/view/giftmessage.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/view/giftmessage.phtml
index a7d7d1552fcb732eda9bf4b0887c83e55ae7e854..9fa3eda8f0d7a93ae165b39bbd96653c44e56ea6 100644
--- a/app/code/Magento/Sales/view/adminhtml/templates/order/view/giftmessage.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/order/view/giftmessage.phtml
@@ -9,32 +9,50 @@
 ?>
 <?php if ($block->canDisplayGiftmessage()): ?>
 <?php $_required = $block->getMessage()->getMessage() != ''?>
-<div id="<?php echo $block->getHtmlId() ?>" class="box-left giftmessage-whole-order-container">
+<div id="<?php echo $block->getHtmlId() ?>" class="admin__page-section-content giftmessage-whole-order-container">
     <form class="entry-edit form-inline" id="<?php echo $block->getFieldId('form') ?>" action="<?php echo $block->getSaveUrl() ?>">
-        <fieldset>
+        <fieldset class="admin__fieldset">
             <legend class="admin__legend"><span><?php echo __('Gift Message for the Entire Order'); ?></span></legend>
-            <br>
+            <br/>
 
-            <input type="hidden" id="<?php echo $block->getFieldId('type'); ?>" name="<?php echo $block->getFieldName('type'); ?>" value="order" />
+            <input type="hidden" id="<?php echo $block->getFieldId('type'); ?>"
+                   name="<?php echo $block->getFieldName('type'); ?>"
+                   value="order"/>
 
-            <div class="field field-from-name <?php echo $_required ? 'required' : ''; ?>">
-                <label class="label" for="<?php echo $block->getFieldId('sender'); ?>"><span><?php echo __('From Name'); ?></span></label>
-                <div class="control">
-                    <input class="input-text <?php echo $_required ? 'required-entry' : ''; ?>" type="text" id="<?php echo $block->getFieldId('sender'); ?>" name="<?php echo $block->getFieldName('sender'); ?>" value="<?php echo $block->escapeHtml($block->getMessage()->getSender()); ?>" />
+            <div class="admin__field field-from-name<?php echo $_required ? ' required' : ''; ?>">
+                <label class="admin__field-label"
+                       for="<?php echo $block->getFieldId('sender'); ?>"><span><?php echo __('From Name'); ?></span></label>
+
+                <div class="admin__field-control">
+                    <input class="admin__control-text <?php echo $_required ? 'required-entry' : ''; ?>" type="text"
+                           id="<?php echo $block->getFieldId('sender'); ?>"
+                           name="<?php echo $block->getFieldName('sender'); ?>"
+                           value="<?php echo $block->escapeHtml($block->getMessage()->getSender()); ?>"/>
                 </div>
             </div>
 
-            <div class="field field-to-name <?php echo $_required ? 'required' : ''; ?>">
-                <label class="label" for="<?php echo $block->getFieldId('recipient'); ?>"><span><?php echo __('To Name'); ?></span></label>
-                <div class="control">
-                    <input class="input-text <?php echo $_required ? 'required-entry' : ''; ?>" type="text" id="<?php echo $block->getFieldId('recipient'); ?>" name="<?php echo $block->getFieldName('recipient'); ?>"  value="<?php echo $block->escapeHtml($block->getMessage()->getRecipient()); ?>" />
+            <div class="admin__field field-to-name<?php echo $_required ? ' required' : ''; ?>">
+                <label class="admin__field-label"
+                       for="<?php echo $block->getFieldId('recipient'); ?>"><span><?php echo __('To Name'); ?></span></label>
+
+                <div class="admin__field-control">
+                    <input class="admin__control-text <?php echo $_required ? 'required-entry' : ''; ?>" type="text"
+                           id="<?php echo $block->getFieldId('recipient'); ?>"
+                           name="<?php echo $block->getFieldName('recipient'); ?>"
+                           value="<?php echo $block->escapeHtml($block->getMessage()->getRecipient()); ?>"/>
                 </div>
             </div>
 
-            <div class="field field-gift-message">
-                <label class="label" for="<?php echo $block->getFieldId('message'); ?>"><span><?php echo __('Gift Message'); ?></span></label>
-                <div class="control">
-                    <textarea id="<?php echo $block->getFieldId('message'); ?>" name="<?php echo $block->getFieldName('message') ?>" rows="2" cols="15"><?php echo $block->escapeHtml($block->getMessage()->getMessage()); ?></textarea>
+            <div class="admin__field field-gift-message">
+                <label class="admin__field-label"
+                       for="<?php echo $block->getFieldId('message'); ?>"><span><?php echo __('Gift Message'); ?></span></label>
+
+                <div class="admin__field-control">
+                    <textarea id="<?php echo $block->getFieldId('message'); ?>"
+                              name="<?php echo $block->getFieldName('message') ?>"
+                              class="admin__control-textarea"
+                              rows="2"
+                              cols="15"><?php echo $block->escapeHtml($block->getMessage()->getMessage()); ?></textarea>
                 </div>
             </div>
 
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/view/history.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/view/history.phtml
index a202b3aa0dcee89d76652153dadcd23cb3e2476a..b1c4121b92fc36055dce194757c944a5486fbab3 100644
--- a/app/code/Magento/Sales/view/adminhtml/templates/order/view/history.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/order/view/history.phtml
@@ -7,38 +7,71 @@
 // @codingStandardsIgnoreFile
 
 ?>
-<div id="order_history_block">
+<div id="order_history_block" class="edit-order-comments">
     <?php if ($block->canAddComment()):?>
-    <div id="history_form">
-        <div><?php echo __('Add Order Comments') ?></div>
-        <div>
-            <label for="history_status"><?php echo __('Status') ?></label>
-            <select name="history[status]" id="history_status">
-            <?php foreach ($block->getStatuses() as $_code => $_label): ?>
-                <option value="<?php echo $_code ?>"<?php if ($_code == $block->getOrder()->getStatus()): ?> selected="selected"<?php endif; ?>><?php echo $_label ?></option>
-            <?php endforeach; ?>
-            </select>
-        </div>
-        <div>
-            <label for="history_comment"><?php echo __('Comment') ?></label>
-            <textarea name="history[comment]" rows="3" cols="5" id="history_comment"></textarea>
-        </div>
-        <div class="clearfix">
-            <div class="order-history-comments-options">
-                <?php if ($block->canSendCommentEmail()): ?>
-                <input name="history[is_customer_notified]" type="checkbox" id="history_notify" value="1" /><label for="history_notify"> <?php echo __('Notify Customer by Email') ?></label><br />
-                <?php endif; ?>
-                <input name="history[is_visible_on_front]" type="checkbox" id="history_visible" value="1" /><label for="history_visible"> <?php echo __('Visible on Frontend') ?></label>
+        <div class="order-history-block" id="history_form">
+
+            <div class="admin__field">
+                <label for="history_status" class="admin__field-label"><?php echo __('Status') ?></label>
+                <div class="admin__field-control">
+                    <select name="history[status]" id="history_status" class="admin__control-select">
+                        <?php foreach ($block->getStatuses() as $_code => $_label): ?>
+                            <option value="<?php echo $_code ?>"<?php if ($_code == $block->getOrder()->getStatus()): ?> selected="selected"<?php endif; ?>><?php echo $_label ?></option>
+                        <?php endforeach; ?>
+                    </select>
+                </div>
+            </div>
+
+            <div class="admin__field">
+                <label for="history_comment" class="admin__field-label">
+                    <?php echo __('Comment') ?>
+                </label>
+                <div class="admin__field-control">
+                    <textarea name="history[comment]"
+                              rows="3"
+                              cols="5"
+                              id="history_comment"
+                              class="admin__control-textarea"></textarea>
+                </div>
             </div>
-            <div class="actions">
-                <?php echo $block->getChildHtml('submit_button') ?>
+
+            <div class="admin__field">
+                <div class="order-history-comments-options">
+                    <div class="admin__field admin__field-option">
+                        <?php if ($block->canSendCommentEmail()): ?>
+                            <input name="history[is_customer_notified]"
+                                   type="checkbox"
+                                   id="history_notify"
+                                   class="admin__control-checkbox"
+                                   value="1" />
+                            <label class="admin__field-label" for="history_notify">
+                                <?php echo __('Notify Customer by Email') ?>
+                            </label>
+                        <?php endif; ?>
+                    </div>
+
+                    <div class="admin__field admin__field-option">
+                        <input name="history[is_visible_on_front]"
+                               type="checkbox"
+                               id="history_visible"
+                               class="admin__control-checkbox"
+                               value="1" />
+                        <label class="admin__field-label" for="history_visible">
+                            <?php echo __('Visible on Frontend') ?>
+                        </label>
+                    </div>
+                </div>
+
+                <div class="order-history-comments-actions">
+                    <?php echo $block->getChildHtml('submit_button') ?>
+                </div>
             </div>
         </div>
-    </div>
     <?php endif;?>
+
     <ul class="note-list">
     <?php foreach ($block->getOrder()->getStatusHistoryCollection(true) as $_item): ?>
-        <li>
+        <li class="note-list-item">
             <span class="note-list-date"><?php echo $block->formatDate($_item->getCreatedAtDate(), \IntlDateFormatter::MEDIUM) ?></span>
             <span class="note-list-time"><?php echo $block->formatTime($_item->getCreatedAtDate(), \IntlDateFormatter::MEDIUM) ?></span>
             <span class="note-list-status"><?php echo $_item->getStatusLabel() ?></span>
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/view/info.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/view/info.phtml
index 62900a6f6bb0bb355529cb2b2414e02e5b9ad889..afd5fc24ba3e939735a13492154775d93265827b 100644
--- a/app/code/Magento/Sales/view/adminhtml/templates/order/view/info.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/order/view/info.phtml
@@ -22,165 +22,158 @@ $orderStoreDate = $block->formatDate(
 );
 ?>
 
-<?php /* the opening and closing divs of these two clearfixes are in app\code\core\Mage\Adminhtml\view\adminhtml\sales\order\invoice\create\form.phtml */?>
-
-<div class="clearfix">
-
-    <div class="order-information">
-        <?php /* Order Information */?>
-        <div class="fieldset-wrapper">
+<section class="admin__page-section order-view-account-information">
+    <div class="admin__page-section-title">
+        <span class="title"><?php echo __('Order & Account Information') ?></span>
+    </div>
+    <div class="admin__page-section-content">
+        <div class="admin__page-section-item order-information">
+            <?php /* Order Information */?>
             <?php if ($_order->getEmailSent()):
                 $_email = __('the order confirmation email was sent');
             else:
                 $_email = __('the order confirmation email is not sent');
             endif; ?>
-            <div class="fieldset-wrapper-title">
+            <div class="admin__page-section-item-title">
                 <span class="title">
                     <?php if ($block->getNoUseOrderLink()): ?>
-                    <?php echo __('Order # %1', $_order->getRealOrderId()) ?> (<span><?php echo $_email ?></span>)
+                        <?php echo __('Order # %1', $_order->getRealOrderId()) ?> (<span><?php echo $_email ?></span>)
                     <?php else: ?>
-                    <a href="<?php echo $block->getViewUrl($_order->getId()) ?>"><?php echo __('Order # %1', $_order->getRealOrderId()) ?></a>
-                    <span>(<?php echo $_email ?>)</span>
+                        <a href="<?php echo $block->getViewUrl($_order->getId()) ?>"><?php echo __('Order # %1', $_order->getRealOrderId()) ?></a>
+                        <span>(<?php echo $_email ?>)</span>
                     <?php endif; ?>
                 </span>
             </div>
-            <table class="data-table table-info">
+            <div class="admin__page-section-item-content">
+                <table class="data-table admin__table-secondary order-information-table">
                 <tr>
                     <th><?php echo __('Order Date') ?></th>
                     <td><?php echo $orderAdminDate ?></td>
                 </tr>
                 <?php if ($orderAdminDate != $orderStoreDate):?>
-                <tr>
-                    <th><?php echo __(
-                            'Order Date (%1)',
-                            $block->getCreatedAtStoreDate(
-                                $_order->getStore(),
-                                $_order->getCreatedAt()
-                            )->getTimezone()->getName()
-                        ) ?></th>
-                    <td><?php echo $orderStoreDate ?></td>
-                </tr>
+                    <tr>
+                        <th><?php echo __(
+                                'Order Date (%1)',
+                                $block->getCreatedAtStoreDate(
+                                    $_order->getStore(),
+                                    $_order->getCreatedAt()
+                                )->getTimezone()->getName()
+                            ) ?></th>
+                        <td><?php echo $orderStoreDate ?></td>
+                    </tr>
                 <?php endif;?>
                 <tr>
                     <th><?php echo __('Order Status') ?></th>
                     <td><span id="order_status"><?php echo $_order->getStatusLabel() ?></span></td>
                 </tr>
                 <?php if ($block->isSingleStoreMode() == false):?>
-                <tr>
-                    <th><?php echo __('Purchased From') ?></th>
-                    <td><?php echo $block->getOrderStoreName() ?></td>
-                </tr>
+                    <tr>
+                        <th><?php echo __('Purchased From') ?></th>
+                        <td><?php echo $block->getOrderStoreName() ?></td>
+                    </tr>
                 <?php endif; ?>
                 <?php if ($_order->getRelationChildId()): ?>
-                <tr>
-                    <th><?php echo __('Link to the New Order') ?></th>
-                    <td><a href="<?php echo $block->getViewUrl($_order->getRelationChildId()) ?>">
-                        <?php echo $_order->getRelationChildRealId() ?>
-                    </a></td>
-                </tr>
+                    <tr>
+                        <th><?php echo __('Link to the New Order') ?></th>
+                        <td><a href="<?php echo $block->getViewUrl($_order->getRelationChildId()) ?>">
+                                <?php echo $_order->getRelationChildRealId() ?>
+                            </a></td>
+                    </tr>
                 <?php endif; ?>
                 <?php if ($_order->getRelationParentId()): ?>
-                <tr>
-                    <th><?php echo __('Link to the Previous Order') ?></th>
-                    <td><a href="<?php echo $block->getViewUrl($_order->getRelationParentId()) ?>">
-                        <?php echo $_order->getRelationParentRealId() ?>
-                    </a></td>
-                </tr>
+                    <tr>
+                        <th><?php echo __('Link to the Previous Order') ?></th>
+                        <td><a href="<?php echo $block->getViewUrl($_order->getRelationParentId()) ?>">
+                                <?php echo $_order->getRelationParentRealId() ?>
+                            </a></td>
+                    </tr>
                 <?php endif; ?>
                 <?php if ($_order->getRemoteIp() && $block->shouldDisplayCustomerIp()): ?>
-                <tr>
-                    <th><?php echo __('Placed from IP') ?></th>
-                    <td><?php echo $_order->getRemoteIp(); echo($_order->getXForwardedFor()) ? ' (' . $block->escapeHtml($_order->getXForwardedFor()) . ')' : ''; ?></td>
-                </tr>
+                    <tr>
+                        <th><?php echo __('Placed from IP') ?></th>
+                        <td><?php echo $_order->getRemoteIp(); echo($_order->getXForwardedFor()) ? ' (' . $block->escapeHtml($_order->getXForwardedFor()) . ')' : ''; ?></td>
+                    </tr>
                 <?php endif; ?>
                 <?php if ($_order->getGlobalCurrencyCode() != $_order->getBaseCurrencyCode()): ?>
-                <tr>
-                    <th><?php echo __('%1 / %2 rate:', $_order->getGlobalCurrencyCode(), $_order->getBaseCurrencyCode()) ?></th>
-                    <td><?php echo $_order->getBaseToGlobalRate() ?></td>
-                </tr>
+                    <tr>
+                        <th><?php echo __('%1 / %2 rate:', $_order->getGlobalCurrencyCode(), $_order->getBaseCurrencyCode()) ?></th>
+                        <td><?php echo $_order->getBaseToGlobalRate() ?></td>
+                    </tr>
                 <?php endif; ?>
                 <?php if ($_order->getBaseCurrencyCode() != $_order->getOrderCurrencyCode()): ?>
-                <tr>
-                    <th><?php echo __('%1 / %2 rate:', $_order->getOrderCurrencyCode(), $_order->getBaseCurrencyCode()) ?></th>
-                    <th><?php echo $_order->getBaseToOrderRate() ?></th>
-                </tr>
+                    <tr>
+                        <th><?php echo __('%1 / %2 rate:', $_order->getOrderCurrencyCode(), $_order->getBaseCurrencyCode()) ?></th>
+                        <th><?php echo $_order->getBaseToOrderRate() ?></th>
+                    </tr>
                 <?php endif; ?>
             </table>
+            </div>
         </div>
-    </div>
 
-    <div class="order-account-information">
-        <?php /* Account Information */?>
-        <div class="admin__fieldset-wrapper">
-            <div class="admin__fieldset-wrapper-title">
+        <div class="admin__page-section-item order-account-information">
+            <?php /* Account Information */?>
+            <div class="admin__page-section-item-title">
+                <span class="title"><?php echo __('Account Information') ?></span>
                 <div class="actions"><?php echo $block->getAccountEditLink()?></div>
-                <strong class="title"><?php echo __('Account Information') ?></strong>
             </div>
-            <table class="data-table table-info">
-                <tr>
-                    <th><?php echo __('Customer Name') ?></th>
-                    <td>
-                    <?php if ($_customerUrl = $block->getCustomerViewUrl()) : ?>
-                        <a href="<?php echo $_customerUrl ?>" target="_blank"><strong><?php echo $block->escapeHtml($_order->getCustomerName()) ?></strong></a>
-                    <?php else: ?>
-                        <?php echo $block->escapeHtml($_order->getCustomerName()) ?>
+            <div class="admin__page-section-item-content">
+                <table class="data-table admin__table-secondary order-account-information-table">
+                    <tr>
+                        <th><?php echo __('Customer Name') ?></th>
+                        <td>
+                            <?php if ($_customerUrl = $block->getCustomerViewUrl()) : ?>
+                                <a href="<?php echo $_customerUrl ?>" target="_blank">
+                                    <span><?php echo $block->escapeHtml($_order->getCustomerName()) ?></span>
+                                </a>
+                            <?php else: ?>
+                                <?php echo $block->escapeHtml($_order->getCustomerName()) ?>
+                            <?php endif; ?>
+                        </td>
+                    </tr>
+                    <tr>
+                        <th><?php echo __('Email') ?></th>
+                        <td><a href="mailto:<?php echo $_order->getCustomerEmail() ?>"><?php echo $_order->getCustomerEmail() ?></a></td>
+                    </tr>
+                    <?php if ($_groupName = $block->getCustomerGroupName()) : ?>
+                        <tr>
+                            <th><?php echo __('Customer Group') ?></th>
+                            <td><?php echo $_groupName ?></td>
+                        </tr>
                     <?php endif; ?>
-                    </td>
-                </tr>
-                <tr>
-                    <th><?php echo __('Email') ?></th>
-                    <td><a href="mailto:<?php echo $_order->getCustomerEmail() ?>"><?php echo $_order->getCustomerEmail() ?></a></td>
-                </tr>
-                <?php if ($_groupName = $block->getCustomerGroupName()) : ?>
-                <tr>
-                    <th><?php echo __('Customer Group') ?></th>
-                    <td><?php echo $_groupName ?></td>
-                </tr>
-                <?php endif; ?>
-                <?php foreach ($block->getCustomerAccountData() as $data):?>
-                <tr>
-                    <th><?php echo $data['label'] ?></th>
-                    <td><?php echo $data['value'] ?></td>
-                </tr>
-                <?php endforeach;?>
-            </table>
+                    <?php foreach ($block->getCustomerAccountData() as $data):?>
+                        <tr>
+                            <th><?php echo $data['label'] ?></th>
+                            <td><?php echo $data['value'] ?></td>
+                        </tr>
+                    <?php endforeach;?>
+                </table>
+            </div>
         </div>
     </div>
+</section>
 
-</div>
-
-<div class="clearfix">
-
-    <div class="order-billing-address">
-        <?php /* Billing Address */?>
-        <div class="fieldset-wrapper">
-            <div class="fieldset-wrapper-title">
-                <div class="actions"><?php echo $block->getAddressEditLink($_order->getBillingAddress()); ?></div>
+<section class="admin__page-section order-addresses">
+    <div class="admin__page-section-title">
+        <span class="title"><?php echo __('Address Information') ?></span>
+    </div>
+    <div class="admin__page-section-content">
+        <div class="admin__page-section-item order-billing-address">
+            <?php /* Billing Address */?>
+            <div class="admin__page-section-item-title">
                 <span class="title"><?php echo __('Billing Address') ?></span>
+                <div class="actions"><?php echo $block->getAddressEditLink($_order->getBillingAddress()); ?></div>
             </div>
-            <address><?php echo $block->getFormattedAddress($_order->getBillingAddress()); ?></address>
+            <address class="admin__page-section-item-content"><?php echo $block->getFormattedAddress($_order->getBillingAddress()); ?></address>
         </div>
-    </div>
-
-    <?php if (!$block->getOrder()->getIsVirtual()): ?>
-    <div class="order-shipping-address">
-        <?php /* Shipping Address */ ?>
-        <div class="fieldset-wrapper">
-            <div class="fieldset-wrapper-title">
-                <div class="actions"><?php echo $block->getAddressEditLink($_order->getShippingAddress()); ?></div>
-                <span class="title"><?php echo __('Shipping Address') ?></span>
+        <?php if (!$block->getOrder()->getIsVirtual()): ?>
+            <div class="admin__page-section-item order-shipping-address">
+                <?php /* Shipping Address */ ?>
+                <div class="admin__page-section-item-title">
+                    <span class="title"><?php echo __('Shipping Address') ?></span>
+                    <div class="actions"><?php echo $block->getAddressEditLink($_order->getShippingAddress()); ?></div>
+                </div>
+                <address class="admin__page-section-item-content"><?php echo $block->getFormattedAddress($_order->getShippingAddress()); ?></address>
             </div>
-            <address><?php echo $block->getFormattedAddress($_order->getShippingAddress()); ?></address>
-        </div>
+        <?php endif; ?>
     </div>
-</div>
-    <?php endif; ?>
-
-<?php
-/*
-    closing div of this opening div are in
-    app\code\Magento\Sales\view\adminhtml\order\invoice\view\form.phtml
-    or
-    app\code\Magento\Sales\view\adminhtml\order\view\tab\info.phtml
-*/
-?>
+</section>
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/view/items.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/view/items.phtml
index cb1c7006dd7518fb2a0531d62990980526fecfb9..7fc02861eff16e157e3a8842a84ec731e5ea43dc 100644
--- a/app/code/Magento/Sales/view/adminhtml/templates/order/view/items.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/order/view/items.phtml
@@ -10,7 +10,7 @@
 <?php $_order = $block->getOrder() ?>
 <div class="grid">
   <div class="hor-scroll">
-    <table class="data-table table-info">
+    <table class="data-table admin__table-primary edit-order-table">
         <thead>
             <tr class="headings">
                 <th class="col-product"><span><?php echo __('Product') ?></span></th>
@@ -25,13 +25,13 @@
                 <th class="col-total last"><span><?php echo __('Row Total') ?></span></th>
             </tr>
         </thead>
-        <?php $_items = $block->getItemsCollection() ?>
+        <?php $_items = $block->getItemsCollection();?>
         <?php $i = 0; foreach ($_items as $_item):?>
             <?php if ($_item->getParentItem()) {
-    continue;
-} else {
-    $i++;
-}?>
+                continue;
+            } else {
+                $i++;
+            }?>
             <tbody class="<?php echo $i%2 ? 'even' : 'odd' ?>">
                 <?php echo $block->getItemHtml($_item) ?>
                 <?php echo $block->getItemExtraInfoHtml($_item) ?>
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/view/tab/history.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/view/tab/history.phtml
index 7d9c3acc586e381767ded7f39b09af062bc4b1db..2e8eae106e6a9d0132978547405bb4c31cc787ac 100644
--- a/app/code/Magento/Sales/view/adminhtml/templates/order/view/tab/history.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/order/view/tab/history.phtml
@@ -7,10 +7,10 @@
 // @codingStandardsIgnoreFile
 
 ?>
-<div class="fieldset-wrapper">
+<section class="admin__page-section edit-order-comments">
     <ul class="note-list">
     <?php foreach ($block->getFullHistory() as $_item): ?>
-        <li>
+        <li class="note-list-item">
             <span class="note-list-date"><?php echo $block->getItemCreatedAt($_item) ?></span>
             <span class="note-list-time"><?php echo $block->getItemCreatedAt($_item, 'time') ?></span>
             <span class="note-list-status"><?php echo $block->getItemTitle($_item) ?></span>
@@ -26,10 +26,26 @@
                     <?php endif; ?>
                 </span>
             <?php endif; ?>
-            <?php if ($_comment = $block->getItemComment($_item)): ?>
-                <div class="note-list-comment"><?php echo $_comment ?></div>
-            <?php endif; ?>
         </li>
     <?php endforeach; ?>
     </ul>
-</div>
+    <div class="edit-order-comments-block">
+        <div class="edit-order-comments-block-title">
+            <?php echo __('Notes for this Order') ?>
+        </div>
+        <?php foreach ($block->getFullHistory() as $_item): ?>
+            <?php if ($_comment = $block->getItemComment($_item)): ?>
+                <div class="comments-block-item">
+                    <div class="comments-block-item-comment">
+                        <?php echo $_comment ?>
+                    </div>
+                    <span class="comments-block-item-date-time">
+                        <?php echo __('Comment added') ?>
+                        <?php echo $block->getItemCreatedAt($_item) ?>
+                        <?php echo $block->getItemCreatedAt($_item, 'time') ?>
+                    </span>
+                </div>
+            <?php endif; ?>
+        <?php endforeach; ?>
+    </div>
+</section>
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/view/tab/info.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/view/tab/info.phtml
index a939192eba8c671d8e654beb40aa9495a7016cc8..b315a0053976c6dac80fba6dcb579ee1782cea58 100644
--- a/app/code/Magento/Sales/view/adminhtml/templates/order/view/tab/info.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/order/view/tab/info.phtml
@@ -17,60 +17,55 @@
 <?php echo $block->getChildHtml('order_info') ?>
 <input type="hidden" name="order_id" value="<?php echo $_order->getId() ?>"/>
 
-<?php if (!$_order->getIsVirtual()): ?>
-<div class="clearfix">
-<?php endif; ?>
-
-    <div class="order-payment-method<?php if ($_order->getIsVirtual()): ?> order-payment-method-virtual<?php endif; ?>">
-        <?php /* Payment Method */ ?>
-        <div class="fieldset-wrapper">
-            <div class="fieldset-wrapper-title">
+<section class="admin__page-section order-view-billing-shipping">
+    <div class="admin__page-section-title">
+        <span class="title"><?php echo __('Payment &amp; Shipping Method') ?></span>
+    </div>
+    <div class="admin__page-section-content">
+        <div class="admin__page-section-item order-payment-method<?php if ($_order->getIsVirtual()): ?> order-payment-method-virtual<?php endif; ?>">
+            <?php /* Payment Method */ ?>
+            <div class="admin__page-section-item-title">
                 <span class="title"><?php echo __('Payment Information') ?></span>
             </div>
-            <div><?php echo $block->getPaymentHtml() ?></div>
-            <div class="order-payment-currency"><?php echo __('The order was placed using %1.', $_order->getOrderCurrencyCode()) ?></div>
-            <div class="order-payment-additional"><?php echo $block->getChildHtml('order_payment_additional'); ?></div>
+            <div class="admin__page-section-item-content">
+                <div><?php echo $block->getPaymentHtml() ?></div>
+                <div class="order-payment-currency"><?php echo __('The order was placed using %1.', $_order->getOrderCurrencyCode()) ?></div>
+                <div class="order-payment-additional"><?php echo $block->getChildHtml('order_payment_additional'); ?></div>
+            </div>
         </div>
+        <?php echo $block->getChildHtml('order_shipping_view') ?>
     </div>
-
-<?php if ($_order->getIsVirtual()): ?>
-</div><?php /* opening div is in app\code\Magento\Sales\view\adminhtml\order\view\info.phtml */ ?>
-<?php endif; ?>
-
-<?php echo $block->getChildHtml('order_shipping_view') ?>
-
-<?php if (!$_order->getIsVirtual()): ?>
-</div>
-<?php endif; ?>
+</section>
 
 <?php echo $block->getGiftOptionsHtml() ?>
 
-<div class="fieldset-wrapper">
-    <div class="fieldset-wrapper-title">
+<section class="admin__page-section">
+    <div class="admin__page-section-title">
         <span class="title"><?php echo __('Items Ordered') ?></span>
     </div>
     <?php echo $block->getItemsHtml() ?>
-</div>
+</section>
 
-<div class="clearfix">
-    <div class="order-comments-history">
-        <div class="fieldset-wrapper">
-            <div class="fieldset-wrapper-title">
-                <span class="title"><?php echo __('Comments History') ?></span>
+<section class="admin__page-section">
+    <div class="admin__page-section-title">
+        <span class="title"><?php echo __('Order Total') ?></span>
+    </div>
+    <div class="admin__page-section-content">
+        <div class="admin__page-section-item order-comments-history">
+            <div class="admin__page-section-item-title">
+                <span class="title"><?php echo __('Notes for this Order') ?></span>
             </div>
-            <fieldset><?php echo $block->getChildHtml('order_history') ?></fieldset>
+            <?php echo $block->getChildHtml('order_history') ?>
         </div>
-    </div>
 
-    <div class="order-totals">
-        <div class="fieldset-wrapper">
-            <div class="fieldset-wrapper-title">
+        <div class="admin__page-section-item order-totals">
+            <div class="admin__page-section-item-title">
                 <span class="title"><?php echo __('Order Totals') ?></span>
             </div>
             <?php echo $block->getChildHtml('order_totals') ?>
         </div>
     </div>
-</div>
+</section>
 
 <?php echo $block->getChildHtml('popup_window');?>
 
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/transactions/detail.phtml b/app/code/Magento/Sales/view/adminhtml/templates/transactions/detail.phtml
index 701a7c73a192f9f068b04129bac001f4e001f551..26d231c994314ff2524fe898bebc05817341829a 100644
--- a/app/code/Magento/Sales/view/adminhtml/templates/transactions/detail.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/transactions/detail.phtml
@@ -8,12 +8,12 @@
 
 ?>
 <div data-mage-init='{"floatingHeader": {}}' class="page-actions"><?php echo $block->getButtonsHtml() ?></div>
-<div class="fieldset-wrapper">
-    <div class="fieldset-wrapper-title">
+<section class="admin__page-section">
+    <div class="admin__page-section-title">
         <span class="title"><?php echo __('Transaction Data'); ?></span>
     </div>
-    <div id="log_details_fieldset" class="log-details">
-        <table class="log-info data-table table-info">
+    <div id="log_details_fieldset" class="admin__page-section-content log-details">
+        <table class="log-info data-table admin__table-secondary">
             <tbody>
             <tr>
                 <th><?php echo __('Transaction ID'); ?></th>
@@ -54,22 +54,22 @@
             </tbody>
         </table>
     </div>
-</div>
+</section>
 
-<div class="fieldset-wrapper">
-    <div class="fieldset-wrapper-title">
+<section class="admin__page-section">
+    <div class="admin__page-section-title">
         <span class="title""><?php echo __('Child Transactions'); ?></span>
     </div>
-    <div class="log-details-grid">
+    <div class="admin__page-section-content log-details-grid">
         <?php echo $block->getChildHtml('child_grid') ?>
     </div>
-</div>
+</section>
 
-<div class="fieldset-wrapper">
-    <div class="fieldset-wrapper-title">
+<section class="admin__page-section">
+    <div class="admin__page-section-title">
         <span class="title"><?php echo __('Transaction Details'); ?></span>
     </div>
-    <div class="log-details-grid">
+    <div class="admin__page-section-content log-details-grid">
         <?php echo $block->getChildHtml('detail_grid') ?>
     </div>
-</div>
+</section>
diff --git a/app/code/Magento/Sales/view/adminhtml/web/order/create/scripts.js b/app/code/Magento/Sales/view/adminhtml/web/order/create/scripts.js
index 029a93e92456b0468571bb146a49c3aff2cc7ad0..f936da5c2516adf5ef34db62f334d811daf07adb 100644
--- a/app/code/Magento/Sales/view/adminhtml/web/order/create/scripts.js
+++ b/app/code/Magento/Sales/view/adminhtml/web/order/create/scripts.js
@@ -32,6 +32,7 @@ AdminOrder.prototype = {
         this.productPriceBase = {};
         this.collectElementsValue = true;
         this.isOnlyVirtualProduct = false;
+        this.excludedPaymentMethods = [];
         Event.observe(window, 'load',  (function(){
             this.dataArea = new OrderFormArea('data', $(this.getAreaId('data')), this);
             this.itemsArea = Object.extend(new OrderFormArea('items', $(this.getAreaId('items')), this), {
@@ -74,6 +75,13 @@ AdminOrder.prototype = {
             this.areasLoaded();
             this.itemsArea.onLoad();
         }).bind(this));
+
+        jQuery('#edit_form')
+            .on('submitOrder', function(){
+                jQuery(this).trigger('realOrder');
+            })
+            .on('realOrder', this._realSubmit.bind(this));
+
     },
 
     areasLoaded: function(){
@@ -94,6 +102,10 @@ AdminOrder.prototype = {
         this.addresses = addresses;
     },
 
+    addExcludedPaymentMethod : function(method){
+        this.excludedPaymentMethods.push(method);
+    },
+
     setCustomerId : function(id){
         this.customerId = id;
         this.loadArea('header', true);
@@ -327,6 +339,7 @@ AdminOrder.prototype = {
     },
 
     switchPaymentMethod : function(method){
+        jQuery('#edit_form').trigger('changePaymentMethod', [method]);
         this.setPaymentMethod(method);
         var data = {};
         data['order[payment_method]'] = method;
@@ -354,6 +367,7 @@ AdminOrder.prototype = {
         }
 
         if ($('payment_form_'+method)){
+            jQuery('#' + this.getAreaId('billing_method')).trigger('contentUpdated');
             this.paymentMethod = method;
             var form = 'payment_form_'+method;
             [form + '_before', form, form + '_after'].each(function(el) {
@@ -394,6 +408,9 @@ AdminOrder.prototype = {
                 return false;
             }
         }
+        if (this.isPaymentValidationAvailable() == false) {
+            return false;
+        }
         var data = {};
         var fields = $('payment_form_' + currentMethod).select('input', 'select');
         for(var i=0;i<fields.length;i++){
@@ -1037,15 +1054,30 @@ AdminOrder.prototype = {
         if (!params.form_key) {
             params.form_key = FORM_KEY;
         }
-        var data = this.serializeData('order-billing_method');
-        if (data) {
-            data.each(function(value) {
-                params[value[0]] = value[1];
-            });
+
+        if (this.isPaymentValidationAvailable()) {
+            var data = this.serializeData('order-billing_method');
+            if (data) {
+                data.each(function(value) {
+                    params[value[0]] = value[1];
+                });
+            }
+        } else {
+            params['payment[method]'] = this.paymentMethod;
         }
         return params;
     },
 
+    /**
+     * Prevent from sending credit card information to server for some payment methods
+     *
+     * @returns {boolean}
+     */
+    isPaymentValidationAvailable : function(){
+        return ((typeof this.paymentMethod) == 'undefined'
+            || this.excludedPaymentMethods.indexOf(this.paymentMethod) == -1);
+    },
+
     serializeData : function(container){
         var fields = $(container).select('input', 'select', 'textarea');
         var data = Form.serializeElements(fields, true);
@@ -1068,7 +1100,11 @@ AdminOrder.prototype = {
 
     submit : function()
     {
-        // Temporary solution will be replaced after refactoring order functionality
+        jQuery('#edit_form').trigger('processStart');
+        jQuery('#edit_form').trigger('submitOrder');
+    },
+
+    _realSubmit: function () {
         var disableAndSave = function() {
             disableElements('save');
             jQuery('#edit_form').on('invalid-form.validate', function() {
@@ -1308,4 +1344,4 @@ ControlButton.prototype = {
     }
 };
 
-});
\ No newline at end of file
+});
diff --git a/app/code/Magento/SalesRule/composer.json b/app/code/Magento/SalesRule/composer.json
index 1ef5ba09232d018b9987d406fc67f2ef65af6209..6a4c27c399741ad9c8d74f2e95d2dc64a56b102a 100644
--- a/app/code/Magento/SalesRule/composer.json
+++ b/app/code/Magento/SalesRule/composer.json
@@ -3,26 +3,26 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-config": "0.74.0-beta6",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-rule": "0.74.0-beta6",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/module-sales": "0.74.0-beta6",
-        "magento/module-eav": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-customer": "0.74.0-beta6",
-        "magento/module-directory": "0.74.0-beta6",
-        "magento/module-shipping": "0.74.0-beta6",
-        "magento/module-payment": "0.74.0-beta6",
-        "magento/module-reports": "0.74.0-beta6",
-        "magento/module-catalog-rule": "0.74.0-beta6",
-        "magento/module-widget": "0.74.0-beta6",
-        "magento/module-quote": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-config": "0.74.0-beta7",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-rule": "0.74.0-beta7",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/module-sales": "0.74.0-beta7",
+        "magento/module-eav": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-customer": "0.74.0-beta7",
+        "magento/module-directory": "0.74.0-beta7",
+        "magento/module-shipping": "0.74.0-beta7",
+        "magento/module-payment": "0.74.0-beta7",
+        "magento/module-reports": "0.74.0-beta7",
+        "magento/module-catalog-rule": "0.74.0-beta7",
+        "magento/module-widget": "0.74.0-beta7",
+        "magento/module-quote": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/SalesSequence/composer.json b/app/code/Magento/SalesSequence/composer.json
index f3c49c8f01143db554c75ed5abdcb14935ab4ef2..1f2fc3c267dbeeb9456e40b567f52d62b98531c2 100644
--- a/app/code/Magento/SalesSequence/composer.json
+++ b/app/code/Magento/SalesSequence/composer.json
@@ -3,11 +3,11 @@
   "description": "N/A",
   "require": {
     "php": "~5.5.0|~5.6.0",
-    "magento/framework": "0.74.0-beta6",
+    "magento/framework": "0.74.0-beta7",
     "magento/magento-composer-installer": "*"
   },
   "type": "magento2-module",
-  "version": "0.74.0-beta6",
+  "version": "0.74.0-beta7",
   "license": [
     "OSL-3.0",
     "AFL-3.0"
diff --git a/app/code/Magento/Search/Model/SearchEngine.php b/app/code/Magento/Search/Model/SearchEngine.php
index c4d5c4787a17af5dbfd7f042da520650493642c3..f80e6bfd8796f2d6e2dae2901f27028964c97b6c 100644
--- a/app/code/Magento/Search/Model/SearchEngine.php
+++ b/app/code/Magento/Search/Model/SearchEngine.php
@@ -17,14 +17,21 @@ class SearchEngine implements SearchEngineInterface
     /**
      * @var AdapterInterface
      */
-    protected $adapter;
+    private $adapter = null;
+
+    /**
+     * Adapter factory
+     *
+     * @var AdapterFactory
+     */
+    private $adapterFactory;
 
     /**
      * @param AdapterFactory $adapterFactory
      */
     public function __construct(AdapterFactory $adapterFactory)
     {
-        $this->adapter = $adapterFactory->create();
+        $this->adapterFactory = $adapterFactory;
     }
 
     /**
@@ -32,6 +39,19 @@ class SearchEngine implements SearchEngineInterface
      */
     public function search(RequestInterface $request)
     {
-        return $this->adapter->query($request);
+        return $this->getAdapter()->query($request);
+    }
+
+    /**
+     * Get adapter
+     *
+     * @return AdapterInterface
+     */
+    protected function getAdapter()
+    {
+        if ($this->adapter === null) {
+            $this->adapter = $this->adapterFactory->create();
+        }
+        return $this->adapter;
     }
 }
diff --git a/app/code/Magento/Search/composer.json b/app/code/Magento/Search/composer.json
index 69bc52ccfec60bd0b606af29e9748896b6eefe32..841e086af01a4f23d31d3a89f134f5833f0921dc 100644
--- a/app/code/Magento/Search/composer.json
+++ b/app/code/Magento/Search/composer.json
@@ -3,15 +3,15 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/framework": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-catalog-search": "0.74.0-beta6",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-reports": "0.74.0-beta6",
+        "magento/framework": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-catalog-search": "0.74.0-beta7",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-reports": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Sendfriend/composer.json b/app/code/Magento/Sendfriend/composer.json
index 7acd6e8fa3cece61f1c20f06067106d0b5691ba5..b17ea7f73d12b36993340f6884a195ee48417da0 100644
--- a/app/code/Magento/Sendfriend/composer.json
+++ b/app/code/Magento/Sendfriend/composer.json
@@ -3,15 +3,15 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/module-customer": "0.74.0-beta6",
-        "magento/module-theme": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/module-customer": "0.74.0-beta7",
+        "magento/module-theme": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Shipping/Block/Adminhtml/View/Form.php b/app/code/Magento/Shipping/Block/Adminhtml/View/Form.php
index 2f848e0a150c139f624847ddbdab1d9a89abd174..fa0d8aa70c9e118540e4532bb248db275bb2513c 100644
--- a/app/code/Magento/Shipping/Block/Adminhtml/View/Form.php
+++ b/app/code/Magento/Shipping/Block/Adminhtml/View/Form.php
@@ -79,7 +79,11 @@ class Form extends \Magento\Sales\Block\Adminhtml\Order\AbstractOrder
         return $this->getLayout()->createBlock(
             'Magento\Backend\Block\Widget\Button'
         )->setData(
-            ['label' => __('Create Shipping Label...'), 'onclick' => 'packaging.showWindow();']
+            [
+                'label' => __('Create Shipping Label...'),
+                'onclick' => 'packaging.showWindow();',
+                'class' => 'action-create-label'
+            ]
         )->toHtml();
     }
 
diff --git a/app/code/Magento/Shipping/Model/Order/Track.php b/app/code/Magento/Shipping/Model/Order/Track.php
index 81b506a7d10d9a821df999357d74a3c914feb8a9..9763f2bdb6e49035dd9b5d16b0677b635b6dd39b 100644
--- a/app/code/Magento/Shipping/Model/Order/Track.php
+++ b/app/code/Magento/Shipping/Model/Order/Track.php
@@ -19,7 +19,6 @@ use Magento\Framework\Api\AttributeValueFactory;
  * @method string getTitle()
  * @method string getCarrierCode()
  * @method string getCreatedAt()
- * @method \Magento\Sales\Model\Order\Shipment\Track setCreatedAt(string $value)
  * @method string getUpdatedAt()
  * @method \Magento\Sales\Api\Data\ShipmentTrackExtensionInterface getExtensionAttributes()
  */
diff --git a/app/code/Magento/Shipping/composer.json b/app/code/Magento/Shipping/composer.json
index 54c613d4a0a95d2ab7d0a5eae1435dbfbffa9fff..9a1f9a4a0d0e500376b57cd48b4d615d3e2a6a3a 100644
--- a/app/code/Magento/Shipping/composer.json
+++ b/app/code/Magento/Shipping/composer.json
@@ -3,27 +3,27 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/module-sales": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-directory": "0.74.0-beta6",
-        "magento/module-contact": "0.74.0-beta6",
-        "magento/module-customer": "0.74.0-beta6",
-        "magento/module-payment": "0.74.0-beta6",
-        "magento/module-tax": "0.74.0-beta6",
-        "magento/module-catalog-inventory": "0.74.0-beta6",
-        "magento/module-quote": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/module-sales": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-directory": "0.74.0-beta7",
+        "magento/module-contact": "0.74.0-beta7",
+        "magento/module-customer": "0.74.0-beta7",
+        "magento/module-payment": "0.74.0-beta7",
+        "magento/module-tax": "0.74.0-beta7",
+        "magento/module-catalog-inventory": "0.74.0-beta7",
+        "magento/module-quote": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "ext-gd": "*",
         "magento/magento-composer-installer": "*"
     },
     "suggest": {
-        "magento/module-fedex": "0.74.0-beta6",
-        "magento/module-ups": "0.74.0-beta6"
+        "magento/module-fedex": "0.74.0-beta7",
+        "magento/module-ups": "0.74.0-beta7"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Shipping/view/adminhtml/layout/adminhtml_order_shipment_new.xml b/app/code/Magento/Shipping/view/adminhtml/layout/adminhtml_order_shipment_new.xml
index 1c2aa23262486fb96b9eb05098cdb5e392596e24..de964564823074cc85563a2d677dd519eb1ff7f7 100644
--- a/app/code/Magento/Shipping/view/adminhtml/layout/adminhtml_order_shipment_new.xml
+++ b/app/code/Magento/Shipping/view/adminhtml/layout/adminhtml_order_shipment_new.xml
@@ -7,6 +7,7 @@
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
     <body>
+        <referenceContainer name="admin.scope.col.wrap" htmlClass="admin__old" /> <!-- ToDo UI: remove this wrapper with old styles removal. The class name "admin__old" is for tests only, we shouldn't use it in any way -->
         <referenceContainer name="content">
             <block class="Magento\Shipping\Block\Adminhtml\Create" name="sales_shipment_create">
                 <block class="Magento\Shipping\Block\Adminhtml\Create\Form" name="form" template="create/form.phtml">
diff --git a/app/code/Magento/Shipping/view/adminhtml/layout/adminhtml_order_shipment_view.xml b/app/code/Magento/Shipping/view/adminhtml/layout/adminhtml_order_shipment_view.xml
index 8cdc5f8be0c8b547dd0b606358fb9b8ccb6ac2da..049654bf03a97ff760d1b1f2b80ac9fd48a05512 100644
--- a/app/code/Magento/Shipping/view/adminhtml/layout/adminhtml_order_shipment_view.xml
+++ b/app/code/Magento/Shipping/view/adminhtml/layout/adminhtml_order_shipment_view.xml
@@ -7,6 +7,7 @@
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
     <body>
+        <referenceContainer name="admin.scope.col.wrap" htmlClass="admin__old" /> <!-- ToDo UI: remove this wrapper with old styles removal. The class name "admin__old" is for tests only, we shouldn't use it in any way -->
         <referenceContainer name="content">
             <block class="Magento\Shipping\Block\Adminhtml\View" name="sales_shipment_view">
                 <block class="Magento\Shipping\Block\Adminhtml\View\Form" name="form" template="view/form.phtml">
diff --git a/app/code/Magento/Shipping/view/adminhtml/templates/create/form.phtml b/app/code/Magento/Shipping/view/adminhtml/templates/create/form.phtml
index 28693ed0e0b947dccd7e43c878597d93d9ff29e0..46b4ab5ed56f691d3f7b0421d9e023ef3afaa9e0 100644
--- a/app/code/Magento/Shipping/view/adminhtml/templates/create/form.phtml
+++ b/app/code/Magento/Shipping/view/adminhtml/templates/create/form.phtml
@@ -11,24 +11,27 @@
     <?php echo $block->getBlockHtml('formkey')?>
     <?php  $_order = $block->getShipment()->getOrder() ?>
     <?php echo $block->getChildHtml('order_info') ?>
-    <div class="clearfix">
-        <div class="order-payment-method">
-            <!--Billing Address-->
-            <div class="fieldset-wrapper">
-                <div class="fieldset-wrapper-title">
+    <div class="admin__page-section">
+        <div class="admin__page-section-title">
+            <span class="title"><?php echo __('Payment &amp; Shipping Method') ?></span>
+        </div>
+        <div class="admin__page-section-content">
+            <div class="admin__page-section-item order-payment-method">
+                <?php /* Billing Address */ ?>
+                <div class="admin__page-section-item-title">
                     <span class="title"><?php echo __('Payment Information') ?></span>
                 </div>
-                <div><?php echo $block->getPaymentHtml() ?></div>
-                <div class="order-payment-currency"><?php echo __('The order was placed using %1.', $_order->getOrderCurrencyCode()) ?></div>
+                <div class="admin__page-section-item-content">
+                    <div><?php echo $block->getPaymentHtml() ?></div>
+                    <div class="order-payment-currency"><?php echo __('The order was placed using %1.', $_order->getOrderCurrencyCode()) ?></div>
+                </div>
             </div>
-        </div>
-        <div class="order-shipping-address">
-            <!--Shipping Address-->
-            <div class="fieldset-wrapper">
-                <div class="fieldset-wrapper-title">
+            <div class="admin__page-section-item order-shipping-address">
+                <?php /* Shipping Address */ ?>
+                <div class="admin__page-section-item-title">
                     <span class="title"><?php echo __('Shipping Information') ?></span>
                 </div>
-                <div class="shipping-description-wrapper">
+                <div class="admin__page-section-item-content shipping-description-wrapper">
                     <div class="shipping-description-title"><?php echo $block->escapeHtml($_order->getShippingDescription()) ?></div>
                     <div class="shipping-description-content">
                         <?php echo __('Total Shipping Charges'); ?>:
diff --git a/app/code/Magento/Shipping/view/adminhtml/templates/create/items.phtml b/app/code/Magento/Shipping/view/adminhtml/templates/create/items.phtml
index b1544ff93ea9a2d15080bbea545aca5896c4ffcf..b2001f9ac88a4b9e8b47ccaa7b53f6b02ea4e128 100644
--- a/app/code/Magento/Shipping/view/adminhtml/templates/create/items.phtml
+++ b/app/code/Magento/Shipping/view/adminhtml/templates/create/items.phtml
@@ -7,12 +7,13 @@
 // @codingStandardsIgnoreFile
 
 ?>
-<div class="fieldset-wrapper">
-    <div class="fieldset-wrapper-title">
+
+<section class="admin__page-section">
+    <div class="admin__page-section-title">
         <span class="title"><?php echo __('Items to Ship') ?></span>
     </div>
     <div class="grid">
-        <table cellspacing="0" class="data order-tables">
+        <table class="data-table admin__table-primary order-shipment-table">
             <thead>
                 <tr class="headings">
                     <th class="col-product"><span><?php echo __('Product') ?></span></th>
@@ -34,44 +35,75 @@
             <?php endforeach; ?>
         </table>
     </div>
-</div>
-<div class="clearfix">
-    <div class="order-comments-history">
-        <div class="fieldset-wrapper">
-            <div class="fieldset-wrapper-title"><span class="title"><?php echo __('Shipment Comments') ?></span></div>
-            <fieldset>
-                <div id="order-history_form">
-                    <label class="normal" for="shipment_comment_text"><?php echo __('Shipment Comments') ?></label>
-                    <textarea id="shipment_comment_text" name="shipment[comment_text]" rows="3" cols="5"><?php echo $block->getShipment()->getCommentText(); ?></textarea>
+</section>
+
+<section class="admin__page-section">
+    <div class="admin__page-section-title">
+        <span class="title"><?php echo __('Shipment Total') ?></span>
+    </div>
+    <div class="admin__page-section-content order-comments-history">
+        <div class="admin__page-section-item">
+            <div class="admin__page-section-item-title">
+                <span class="title"><?php echo __('Shipment Comments') ?></span>
+            </div>
+            <div class="admin__page-section-item-content">
+                <div id="order-history_form" class="admin__field">
+                    <label class="admin__field-label"
+                           for="shipment_comment_text">
+                        <span><?php echo __('Comment Text') ?></span></label>
+                    <textarea id="shipment_comment_text"
+                              class="admin__control-textarea"
+                              name="shipment[comment_text]"
+                              rows="3"
+                              cols="5"><?php echo $block->getShipment()->getCommentText(); ?></textarea>
                 </div>
-            </fieldset>
+            </div>
         </div>
     </div>
-    <div class="order-totals">
-        <div class="fieldset-wrapper">
-            <?php if ($block->canCreateShippingLabel()): ?>
-                <div class="field choice field-create">
-                    <input id="create_shipping_label" name="shipment[create_shipping_label]" value="1" type="checkbox"
-                           onclick="toggleCreateLabelCheckbox();"/>
-                    <label class="normal" for="create_shipping_label"><?php echo __('Create Shipping Label') ?></label>
-                </div>
-            <?php endif ?>
-            <div class="field choice field-append">
-                <input id="notify_customer" name="shipment[comment_customer_notify]" value="1" type="checkbox"/>
-                <label class="normal" for="notify_customer"><?php echo __('Append Comments') ?></label>
+    <div class="admin__page-section-item order-totals">
+        <?php if ($block->canCreateShippingLabel()): ?>
+            <div class="field choice admin__field admin__field-option field-create">
+                <input id="create_shipping_label"
+                       class="admin__control-checkbox"
+                       name="shipment[create_shipping_label]"
+                       value="1"
+                       type="checkbox"
+                       onclick="toggleCreateLabelCheckbox();"/>
+                <label class="admin__field-label"
+                       for="create_shipping_label">
+                    <span><?php echo __('Create Shipping Label') ?></span></label>
             </div>
-            <?php if ($block->canSendShipmentEmail()): ?>
-                <div class="field choice field-email">
-                    <input id="send_email" name="shipment[send_email]" value="1" type="checkbox"/>
-                    <label class="normal" for="send_email"><?php echo __('Email Copy of Shipment') ?></label>
-                </div>
-            <?php endif; ?>
-            <div class="actions">
-                <?php echo $block->getChildHtml('submit_button') ?>
+        <?php endif ?>
+
+        <div class="field choice admin__field admin__field-option field-append">
+            <input id="notify_customer"
+                   class="admin__control-checkbox"
+                   name="shipment[comment_customer_notify]"
+                   value="1"
+                   type="checkbox"/>
+            <label class="admin__field-label"
+                   for="notify_customer">
+                <span><?php echo __('Append Comments') ?></span></label>
+        </div>
+
+        <?php if ($block->canSendShipmentEmail()): ?>
+            <div class="field choice admin__field admin__field-option field-email">
+                <input id="send_email"
+                       class="admin__control-checkbox"
+                       name="shipment[send_email]"
+                       value="1"
+                       type="checkbox"/>
+                <label class="admin__field-label"
+                       for="send_email">
+                    <span><?php echo __('Email Copy of Shipment') ?></span></label>
             </div>
+        <?php endif; ?>
+
+        <div class="order-history-comments-actions actions">
+            <?php echo $block->getChildHtml('submit_button') ?>
         </div>
     </div>
-</div>
+</section>
 <script>
 require([
     "jquery",
diff --git a/app/code/Magento/Shipping/view/adminhtml/templates/create/items/renderer/default.phtml b/app/code/Magento/Shipping/view/adminhtml/templates/create/items/renderer/default.phtml
index 1acdd870909d1f38bb2f9783a6e5937e56d729c9..136612ef50ba971ede1a74e9123cc17845d02998 100644
--- a/app/code/Magento/Shipping/view/adminhtml/templates/create/items/renderer/default.phtml
+++ b/app/code/Magento/Shipping/view/adminhtml/templates/create/items/renderer/default.phtml
@@ -13,7 +13,10 @@
     <td class="col-ordered-qty"><?php echo $block->getColumnHtml($_item, 'qty') ?></td>
     <td class="col-qty <?php if ($block->isShipmentRegular()): ?>last<?php endif; ?>">
         <?php if ($block->canShipPartiallyItem()): ?>
-            <input type="text" class="input-text qty-item" name="shipment[items][<?php echo $_item->getOrderItemId() ?>]" value="<?php echo $_item->getQty()*1 ?>" />
+            <input type="text"
+                   class="input-text admin__control-text qty-item"
+                   name="shipment[items][<?php echo $_item->getOrderItemId() ?>]"
+                   value="<?php echo $_item->getQty()*1 ?>" />
         <?php else: ?>
             <?php echo $_item->getQty()*1 ?>
         <?php endif; ?>
diff --git a/app/code/Magento/Shipping/view/adminhtml/templates/order/Tracking/view.phtml b/app/code/Magento/Shipping/view/adminhtml/templates/order/Tracking/view.phtml
index 74a836156b05475a9b361d888800b3061f17e72a..1497b994f9acbc27c31272b23b45895a4f4a09cc 100644
--- a/app/code/Magento/Shipping/view/adminhtml/templates/order/Tracking/view.phtml
+++ b/app/code/Magento/Shipping/view/adminhtml/templates/order/Tracking/view.phtml
@@ -8,49 +8,66 @@
 
 ?>
 <?php /** @var $block Magento\Shipping\Block\Adminhtml\Order\Tracking\View */ ?>
-<table cellspacing="0" class="data-table" id="shipment_tracking_info">
-    <thead>
-        <tr class="headings">
-            <th class="col-carrier"><?php echo __('Carrier') ?></th>
-            <th class="col-title"><?php echo __('Title') ?></th>
-            <th class="col-number"><?php echo __('Number') ?></th>
-            <th class="col-delete last"><?php echo __('Action') ?></th>
-        </tr>
-    </thead>
-    <tfoot>
-        <tr>
-            <td class="col-carrier">
-                <select name="carrier" class="select" onchange="selectCarrier(this)">
-                    <?php foreach ($block->getCarriers() as $_code => $_name): ?>
-                    <option value="<?php echo $_code ?>"><?php echo $block->escapeHtml($_name) ?></option>
-                    <?php endforeach; ?>
-                </select>
-            </td>
-            <td class="col-title"><input class="input-text" type="text" id="tracking_title" name="title" value="" /></td>
-            <td class="col-number"><input class="input-text" type="text" id="tracking_number" name="number" value="" /></td>
-            <td class="col-delete last"><?php echo $block->getSaveButtonHtml() ?></td>
-        </tr>
-    </tfoot>
-<?php if ($_tracks = $block->getShipment()->getAllTracks()): ?>
-    <tbody>
-    <?php $i = 0; foreach ($_tracks as $_track):$i++ ?>
-        <tr class="<?php echo($i%2 == 0) ? 'even' : 'odd' ?>">
-            <td class="col-carrier"><?php echo $block->escapeHtml($block->getCarrierTitle($_track->getCarrierCode())) ?></td>
-            <td class="col-title"><?php echo $block->escapeHtml($_track->getTitle()) ?></td>
-            <td class="col-number">
-                <?php if ($_track->isCustom()): ?>
-                <?php echo $block->escapeHtml($_track->getNumber()) ?>
-                <?php else: ?>
-                <a href="#" onclick="popWin('<?php echo $this->helper('Magento\Shipping\Helper\Data')->getTrackingPopupUrlBySalesModel($_track) ?>','trackorder','width=800,height=600,resizable=yes,scrollbars=yes')"><?php echo $block->escapeHtml($_track->getNumber()) ?></a>
-                <div id="shipment_tracking_info_response_<?php echo $_track->getId() ?>"></div>
-                <?php endif; ?>
-            </td>
-            <td class="col-delete last"><a class="action- delete" href="#" onclick="deleteTrackingNumber('<?php echo $block->getRemoveUrl($_track) ?>'); return false;"><span><?php echo __('Delete') ?></span></a></td>
-        </tr>
-    <?php endforeach; ?>
-    </tbody>
-<?php endif; ?>
-</table>
+<div class="admin__control-table-wrapper">
+    <table class="data-table admin__control-table" id="shipment_tracking_info">
+        <thead>
+            <tr class="headings">
+                <th class="col-carrier"><?php echo __('Carrier') ?></th>
+                <th class="col-title"><?php echo __('Title') ?></th>
+                <th class="col-number"><?php echo __('Number') ?></th>
+                <th class="col-delete last"><?php echo __('Action') ?></th>
+            </tr>
+        </thead>
+        <tfoot>
+            <tr>
+                <td class="col-carrier">
+                    <select name="carrier"
+                            class="select admin__control-select"
+                            onchange="selectCarrier(this)">
+                        <?php foreach ($block->getCarriers() as $_code => $_name): ?>
+                        <option value="<?php echo $_code ?>"><?php echo $block->escapeHtml($_name) ?></option>
+                        <?php endforeach; ?>
+                    </select>
+                </td>
+                <td class="col-title">
+                    <input class="input-text admin__control-text"
+                           type="text"
+                           id="tracking_title"
+                           name="title"
+                           value="" />
+                </td>
+                <td class="col-number">
+                    <input class="input-text admin__control-text"
+                           type="text"
+                           id="tracking_number"
+                           name="number"
+                           value="" />
+                </td>
+                <td class="col-delete last"><?php echo $block->getSaveButtonHtml() ?></td>
+            </tr>
+        </tfoot>
+    <?php if ($_tracks = $block->getShipment()->getAllTracks()): ?>
+        <tbody>
+        <?php $i = 0; foreach ($_tracks as $_track):$i++ ?>
+            <tr class="<?php echo($i%2 == 0) ? 'even' : 'odd' ?>">
+                <td class="col-carrier"><?php echo $block->escapeHtml($block->getCarrierTitle($_track->getCarrierCode())) ?></td>
+                <td class="col-title"><?php echo $block->escapeHtml($_track->getTitle()) ?></td>
+                <td class="col-number">
+                    <?php if ($_track->isCustom()): ?>
+                    <?php echo $block->escapeHtml($_track->getNumber()) ?>
+                    <?php else: ?>
+                    <a href="#" onclick="popWin('<?php echo $this->helper('Magento\Shipping\Helper\Data')->getTrackingPopupUrlBySalesModel($_track) ?>','trackorder','width=800,height=600,resizable=yes,scrollbars=yes')"><?php echo $block->escapeHtml($_track->getNumber()) ?></a>
+                    <div id="shipment_tracking_info_response_<?php echo $_track->getId() ?>"></div>
+                    <?php endif; ?>
+                </td>
+                <td class="col-delete last"><a class="action-delete" href="#" onclick="deleteTrackingNumber('<?php echo $block->getRemoveUrl($_track) ?>'); return false;"><span><?php echo __('Delete') ?></span></a></td>
+            </tr>
+        <?php endforeach; ?>
+        </tbody>
+    <?php endif; ?>
+    </table>
+</div>
+
 <script>
 require(['prototype'], function(){
 
diff --git a/app/code/Magento/Shipping/view/adminhtml/templates/order/packaging/grid.phtml b/app/code/Magento/Shipping/view/adminhtml/templates/order/packaging/grid.phtml
index aa8645eb6238e23547dc15df5e96c2fc388c9dcf..f696adb536c16ca453fb8090930cf2fe5e67f27f 100644
--- a/app/code/Magento/Shipping/view/adminhtml/templates/order/packaging/grid.phtml
+++ b/app/code/Magento/Shipping/view/adminhtml/templates/order/packaging/grid.phtml
@@ -8,65 +8,88 @@
 
 ?>
 <div class="grid">
-    <table cellspacing="0" class="data-table">
-        <thead>
-        <tr>
-            <th class="col-product no-link"><?php echo __('Product Name') ?></th>
-            <th class="col-weight no-link"><?php echo __('Weight') ?></th>
-            <th class="col-custom no-link" <?php echo $block->displayCustomsValue() ? '' : 'style="display: none;"' ?>>
-                <?php echo __('Customs Value') ?>
-            </th>
-            <th class="col-select no-link">
-                <input type="checkbox" name="" onclick="packaging.checkAllItems(this);" class="checkbox" title="<?php echo __('Select All') ?>">
-            </th>
-            <th class="col-qty no-link"><?php echo __('Qty Ordered') ?></th>
-            <th class="col-qty-edit no-link last"><?php echo __('Qty') ?></th>
-        </tr>
-        </thead>
+    <div class="hor-scroll">
+        <table class="data-table admin__table-primary">
+            <thead>
+            <tr>
+                <th class="col-product no-link"><?php echo __('Product Name') ?></th>
+                <th class="col-weight no-link"><?php echo __('Weight') ?></th>
+                <th class="col-custom no-link" <?php echo $block->displayCustomsValue() ? '' : 'style="display: none;"' ?>>
+                    <?php echo __('Customs Value') ?>
+                </th>
+                <th class="col-select no-link">
+                    <div class="admin__field admin__field-option">
+                        <input type="checkbox"
+                               name=""
+                               onclick="packaging.checkAllItems(this);"
+                               class="checkbox admin__control-checkbox"
+                               title="<?php echo __('Select All') ?>">
+                        <label class="admin__field-label"></label>
+                    </div>
+                </th>
+                <th class="col-qty no-link"><?php echo __('Qty Ordered') ?></th>
+                <th class="col-qty-edit no-link last"><?php echo __('Qty') ?></th>
+            </tr>
+            </thead>
 
-        <tbody>
-        <?php foreach ($block->getCollection() as $item): ?>
-            <?php $_order = $block->getShipment()->getOrder() ?>
-            <?php $_orderItem = $_order->getItemById($item->getOrderItemId()); ?>
-            <?php if ($item->getIsVirtual()
-                || ($_orderItem->isShipSeparately() && !($_orderItem->getParentItemId() || $_orderItem->getParentItem()))
-                || (!$_orderItem->isShipSeparately() && ($_orderItem->getParentItemId() || $_orderItem->getParentItem()))): ?>
-                <?php continue; ?>
+            <tbody>
+            <?php foreach ($block->getCollection() as $item): ?>
+                <?php $_order = $block->getShipment()->getOrder() ?>
+                <?php $_orderItem = $_order->getItemById($item->getOrderItemId()); ?>
+                <?php if ($item->getIsVirtual()
+                    || ($_orderItem->isShipSeparately() && !($_orderItem->getParentItemId() || $_orderItem->getParentItem()))
+                    || (!$_orderItem->isShipSeparately() && ($_orderItem->getParentItemId() || $_orderItem->getParentItem()))): ?>
+                    <?php continue; ?>
                 <?php endif; ?>
-        <tr title="#" id="" class="">
-            <td class="col-product name">
-                <?php echo $item->getName(); ?>
-            </td>
-            <td class="col-weight weight ">
-                <?php echo $item->getWeight(); ?>
-            </td>
-            <?php
-            if ($block->displayCustomsValue()) {
-                $customsValueDisplay = '';
-                $customsValueValidation = ' validate-zero-or-greater ';
-            } else {
-                $customsValueDisplay = ' style="display: none;" ';
-                $customsValueValidation = '';
-            }
-            ?>
-            <td <?php echo $customsValueDisplay ?>>
-                <input type="text" name="customs_value" class="input-text <?php echo $customsValueValidation ?>" value="<?php echo $block->formatPrice($item->getPrice()); ?>" size="10" onblur="packaging.recalcContainerWeightAndCustomsValue(this);">
-            </td>
-            <td class="col-select">
-                <input type="checkbox" name="" value="<?php echo $item->getId() ? $item->getId() : $item->getOrderItemId(); ?>" class="checkbox">
-            </td>
-            <td class="col-qty">
-                <?php echo $item->getOrderItem()->getQtyOrdered()*1; ?>
-            </td>
-            <td class="col-qty-edit last">
-                <input type="hidden" name="price" value="<?php echo $item->getPrice(); ?>">
-                <input type="text" name="qty" value="<?php echo $item->getQty()*1; ?>" class="input-text qty<?php if ($item->getOrderItem()->getIsQtyDecimal()): ?> qty-decimal<?php endif ?>">&nbsp;
-                <button type="button" class="action- delete icon-btn" onclick="packaging.deleteItem(this);" style="display:none;">
-                    <span><?php echo __('Delete') ?></span>
-                </button>
-            </td>
-        </tr>
+                <tr title="#" id="" class="">
+                    <td class="col-product name">
+                        <?php echo $item->getName(); ?>
+                    </td>
+                    <td class="col-weight weight ">
+                        <?php echo $item->getWeight(); ?>
+                    </td>
+                    <?php
+                    if ($block->displayCustomsValue()) {
+                        $customsValueDisplay = '';
+                        $customsValueValidation = ' validate-zero-or-greater ';
+                    } else {
+                        $customsValueDisplay = ' style="display: none;" ';
+                        $customsValueValidation = '';
+                    }
+                    ?>
+                    <td <?php echo $customsValueDisplay ?>>
+                        <input type="text"
+                               name="customs_value"
+                               class="input-text admin__control-text <?php echo $customsValueValidation ?>"
+                               value="<?php echo $block->formatPrice($item->getPrice()); ?>"
+                               size="10"
+                               onblur="packaging.recalcContainerWeightAndCustomsValue(this);">
+                    </td>
+                    <td class="col-select">
+                        <div class="admin__field admin__field-option">
+                            <input type="checkbox"
+                                   name=""
+                                   value="<?php echo $item->getId() ? $item->getId() : $item->getOrderItemId(); ?>"
+                                   class="checkbox admin__control-checkbox">
+                            <label class="admin__field-label"></label>
+                        </div>
+                    </td>
+                    <td class="col-qty">
+                        <?php echo $item->getOrderItem()->getQtyOrdered()*1; ?>
+                    </td>
+                    <td class="col-qty-edit last">
+                        <input type="hidden" name="price" value="<?php echo $item->getPrice(); ?>">
+                        <input type="text"
+                               name="qty"
+                               value="<?php echo $item->getQty()*1; ?>"
+                               class="input-text admin__control-text qty<?php if ($item->getOrderItem()->getIsQtyDecimal()): ?> qty-decimal<?php endif ?>">&nbsp;
+                        <button type="button" class="action-delete delete icon-btn" onclick="packaging.deleteItem(this);" style="display:none;">
+                            <span><?php echo __('Delete') ?></span>
+                        </button>
+                    </td>
+                </tr>
             <?php endforeach; ?>
-        </tbody>
-    </table>
+            </tbody>
+        </table>
+    </div>
 </div>
diff --git a/app/code/Magento/Shipping/view/adminhtml/templates/order/packaging/popup.phtml b/app/code/Magento/Shipping/view/adminhtml/templates/order/packaging/popup.phtml
index 7876d0ae1b8754efad94938cd984a7e90169f560..359dde8e59b198aa5be1907d9839c31b64166d20 100644
--- a/app/code/Magento/Shipping/view/adminhtml/templates/order/packaging/popup.phtml
+++ b/app/code/Magento/Shipping/view/adminhtml/templates/order/packaging/popup.phtml
@@ -53,149 +53,186 @@ require([
     <div class="popup-window-wrapper">
         <div class="popup-window-title">
             <div class="actions">
-                <button type="button" class="action-add AddPackageBtn" onclick="packaging.newPackage();">
+                <button type="button" class="action-add action-secondary AddPackageBtn" onclick="packaging.newPackage();">
                     <span><?php echo __('Add Package') ?></span>
                 </button>
             </div>
             <span class="title"><?php echo __('Create Packages') ?></span>
         </div>
         <div class="packaging-content popup-window-content">
-            <div class="messages" style="display:none;"></div>
+            <div class="message message-warning" style="display: none"></div>
             <div id="package_template" style="display:none;">
                 <div class="package-number popup-fieldset-title">
-                    <div class="title"><?php echo __('Package') ?><span></span></div>
+                    <div class="title">
+                        <?php echo __('Package') ?>
+                        <span></span>
+                    </div>
+                </div>
+                <div class="admin__control-table-wrapper">
+                    <table class="data-table admin__control-table">
+                        <thead>
+                            <th class="col-type"><?php echo __('Type') ?></th>
+                            <?php if ($girthEnabled == 1): ?>
+                            <th class="col-size"><?php echo __('Size') ?></th>
+                            <th class="col-girth"><?php echo __('Girth') ?></th>
+                            <th>&nbsp;</th>
+                                <?php endif; ?>
+                            <th class="col-custom" <?php echo $block->displayCustomsValue() ? '' : 'style="display: none;"' ?>>
+                                <?php echo __('Customs Value') ?>
+                            </th>
+                            <th class="col-total-weight"><?php echo __('Total Weight') ?></th>
+                            <th class="col-length"><?php echo __('Length') ?></th>
+                            <th class="col-width"><?php echo __('Width') ?></th>
+                            <th class="col-height"><?php echo __('Height') ?></th>
+                            <th>&nbsp;</th>
+                            <?php if ($block->getDeliveryConfirmationTypes()): ?>
+                            <th class="col-signature"><?php echo __('Signature Confirmation') ?></th>
+                                <?php endif; ?>
+                            <th class="col-actions">&nbsp;</th>
+                        </thead>
+                        <tbody>
+                            <td class="col-type">
+                                <?php $containers = $block->getContainers(); ?>
+                                <select name="package_container"
+                                        onchange="packaging.changeContainerType(this);packaging.checkSizeAndGirthParameter(this, <?php echo  $girthEnabled ?>);"
+                                        <?php if (empty($containers)):?>
+                                            title="<?php echo __('USPS domestic shipments don\'t use package types.') ?>"
+                                            disabled=""
+                                            class="admin__control-select disabled"
+                                        <?php else: ?>
+                                            class="admin__control-select"
+                                        <?php endif; ?>>
+                                    <?php foreach ($block->getContainers() as $key => $value): ?>
+                                        <option value="<?php echo $key ?>" >
+                                            <?php echo $value ?>
+                                        </option>
+                                    <?php endforeach; ?>
+                                </select>
+                            </td>
+                            <?php if ($girthEnabled == 1 && !empty($sizeSource)): ?>
+                            <td>
+                                <select name="package_size"
+                                        class="admin__control-select"
+                                        onchange="packaging.checkSizeAndGirthParameter(this, <?php echo  $girthEnabled ?>);">
+                                    <?php foreach ($sizeSource as $key => $value): ?>
+                                    <option value="<?php echo $sizeSource[$key]['value'] ?>">
+                                        <?php echo $sizeSource[$key]['label'] ?>
+                                    </option>
+                                    <?php endforeach; ?>
+                                </select>
+                            </td>
+                            <td>
+                                <input type="text"
+                                       class="input-text admin__control-text validate-greater-than-zero"
+                                       name="container_girth" />
+                            </td>
+                            <td>
+                                <select name="container_girth_dimension_units"
+                                        class="options-units-dimensions measures admin__control-select"
+                                        onchange="packaging.changeMeasures(this);">
+                                    <option value="<?php echo Zend_Measure_Length::INCH ?>" selected="selected" ><?php echo __('in') ?></option>
+                                    <option value="<?php echo Zend_Measure_Length::CENTIMETER ?>" ><?php echo __('cm') ?></option>
+                                </select>
+                            </td>
+                                <?php endif; ?>
+                            <?php
+                            if ($block->displayCustomsValue()) {
+                                $customsValueDisplay = '';
+                                $customsValueValidation = ' validate-zero-or-greater ';
+                            } else {
+                                $customsValueDisplay = ' style="display: none;" ';
+                                $customsValueValidation = '';
+                            }
+                            ?>
+                            <td class="col-custom" <?php echo $customsValueDisplay ?>>
+                                <input type="text"
+                                       class="customs-value input-text admin__control-text <?php echo $customsValueValidation ?>"
+                                       name="package_customs_value" />
+                                <span class="customs-value-currency">[<?php echo $block->getCustomValueCurrencyCode(); ?>]</span>
+                            </td>
+                            <td class="col-total-weight">
+                                <input type="text"
+                                       class="options-weight input-text admin__control-text required-entry validate-greater-than-zero"
+                                       name="container_weight" />
+                                <select name="container_weight_units"
+                                        class="options-units-weight measures admin__control-select"
+                                        onchange="packaging.changeMeasures(this);">
+                                    <option value="<?php echo Zend_Measure_Weight::POUND ?>" selected="selected"  ><?php echo __('lb') ?></option>
+                                    <option value="<?php echo Zend_Measure_Weight::KILOGRAM ?>" ><?php echo __('kg') ?></option>
+                                </select>
+                            </td>
+                            <td class="col-length">
+                                <input type="text"
+                                       class="input-text admin__control-text validate-greater-than-zero"
+                                       name="container_length" />
+                            </td>
+                            <td class="col-width">
+                                <input type="text"
+                                       class="input-text admin__control-text validate-greater-than-zero"
+                                       name="container_width" />
+                            </td>
+                            <td class="col-height">
+                                <input type="text"
+                                       class="input-text admin__control-text validate-greater-than-zero"
+                                       name="container_height" />
+                            </td>
+                            <td class="col-measure">
+                                <select name="container_dimension_units"
+                                        class="options-units-dimensions measures admin__control-select"
+                                        onchange="packaging.changeMeasures(this);">
+                                    <option value="<?php echo Zend_Measure_Length::INCH ?>" selected="selected" ><?php echo __('in') ?></option>
+                                    <option value="<?php echo Zend_Measure_Length::CENTIMETER ?>" ><?php echo __('cm') ?></option>
+                                </select>
+                            </td>
+                            <?php if ($block->getDeliveryConfirmationTypes()): ?>
+                            <td>
+                                <select name="delivery_confirmation_types" class="admin__control-select">
+                                    <?php foreach ($block->getDeliveryConfirmationTypes() as $key => $value): ?>
+                                    <option value="<?php echo $key ?>" >
+                                        <?php echo $value ?>
+                                    </option>
+                                    <?php endforeach; ?>
+                                </select>
+                            </td>
+                                <?php endif; ?>
+                            <td class="col-actions">
+                                <button type="button" class="action-add AddItemsBtn" onclick="packaging.getItemsForPack(this);">
+                                    <span><?php echo __('Add') ?></span>
+                                </button>
+                                <button type="button" class="action-delete DeletePackageBtn" onclick="packaging.deletePackage(this);">
+                                    <span><?php echo __('Delete Package') ?></span>
+                                </button>
+                            </td>
+                        </tbody>
+                    </table>
                 </div>
-                <table class="data-table" cellspacing="0">
-                    <thead>
-                        <th class="col-type"><?php echo __('Type') ?></th>
-                        <?php if ($girthEnabled == 1): ?>
-                        <th class="col-size"><?php echo __('Size') ?></th>
-                        <th class="col-girth"><?php echo __('Girth') ?></th>
-                        <th>&nbsp;</th>
-                            <?php endif; ?>
-                        <th class="col-custom" <?php echo $block->displayCustomsValue() ? '' : 'style="display: none;"' ?>>
-                            <?php echo __('Customs Value') ?>
-                        </th>
-                        <th class="col-total-weight"><?php echo __('Total Weight') ?></th>
-                        <th class="col-length"><?php echo __('Length') ?></th>
-                        <th class="col-width"><?php echo __('Width') ?></th>
-                        <th class="col-height"><?php echo __('Height') ?></th>
-                        <th>&nbsp;</th>
-                        <?php if ($block->getDeliveryConfirmationTypes()): ?>
-                        <th class="col-signature"><?php echo __('Signature Confirmation') ?></th>
-                            <?php endif; ?>
-                        <th class="col-actions">&nbsp;</th>
-                    </thead>
-                    <tbody>
-                        <td class="col-type">
-                            <?php $containers = $block->getContainers(); ?>
-                            <select name="package_container" onchange="packaging.changeContainerType(this);packaging.checkSizeAndGirthParameter(this, <?php echo  $girthEnabled ?>);"<?php if (empty($containers)):?>
-                                    title="<?php echo __('USPS domestic shipments don\'t use package types.') ?>"
-                                    disabled="" class="disabled"
-                                <?php endif; ?>>
-                                <?php foreach ($block->getContainers() as $key => $value): ?>
-                                <option value="<?php echo $key ?>" >
-                                    <?php echo $value ?>
-                                </option>
-                                <?php endforeach; ?>
-                            </select>
-                        </td>
-                        <?php if ($girthEnabled == 1 && !empty($sizeSource)): ?>
-                        <td>
-                            <select name="package_size" onchange="packaging.checkSizeAndGirthParameter(this, <?php echo  $girthEnabled ?>);">
-                                <?php foreach ($sizeSource as $key => $value): ?>
-                                <option value="<?php echo $sizeSource[$key]['value'] ?>">
-                                    <?php echo $sizeSource[$key]['label'] ?>
-                                </option>
-                                <?php endforeach; ?>
-                            </select>
-                        </td>
-                        <td><input type="text" class="input-text validate-greater-than-zero" name="container_girth" /></td>
-                        <td>
-                            <select name="container_girth_dimension_units" class="options-units-dimensions measures" onchange="packaging.changeMeasures(this);">
-                                <option value="<?php echo Zend_Measure_Length::INCH ?>" selected="selected" ><?php echo __('in') ?></option>
-                                <option value="<?php echo Zend_Measure_Length::CENTIMETER ?>" ><?php echo __('cm') ?></option>
-                            </select>
-                        </td>
-                            <?php endif; ?>
-                        <?php
-                        if ($block->displayCustomsValue()) {
-                            $customsValueDisplay = '';
-                            $customsValueValidation = ' validate-zero-or-greater ';
-                        } else {
-                            $customsValueDisplay = ' style="display: none;" ';
-                            $customsValueValidation = '';
-                        }
-                        ?>
-                        <td class="col-custom" <?php echo $customsValueDisplay ?>>
-                            <input type="text" class="customs-value input-text <?php echo $customsValueValidation ?>" name="package_customs_value" />
-                            <span class="customs-value-currency">[<?php echo $block->getCustomValueCurrencyCode(); ?>]</span>
-                        </td>
-                        <td class="col-total-weight">
-                            <input type="text" class="options-weight input-text required-entry validate-greater-than-zero" name="container_weight" />
-                            <select name="container_weight_units" class="options-units-weight measures" onchange="packaging.changeMeasures(this);">
-                                <option value="<?php echo Zend_Measure_Weight::POUND ?>" selected="selected"  ><?php echo __('lb') ?></option>
-                                <option value="<?php echo Zend_Measure_Weight::KILOGRAM ?>" ><?php echo __('kg') ?></option>
-                            </select>
-                        </td>
-                        <td class="col-length">
-                            <input type="text" class="input-text validate-greater-than-zero" name="container_length" />
-                        </td>
-                        <td class="col-width">
-                            <input type="text" class="input-text validate-greater-than-zero" name="container_width" />
-                        </td>
-                        <td class="col-height">
-                            <input type="text" class="input-text validate-greater-than-zero" name="container_height" />
-                        </td>
-                        <td class="col-measure">
-                            <select name="container_dimension_units" class="options-units-dimensions measures" onchange="packaging.changeMeasures(this);">
-                                <option value="<?php echo Zend_Measure_Length::INCH ?>" selected="selected" ><?php echo __('in') ?></option>
-                                <option value="<?php echo Zend_Measure_Length::CENTIMETER ?>" ><?php echo __('cm') ?></option>
-                            </select>
-                        </td>
-                        <?php if ($block->getDeliveryConfirmationTypes()): ?>
-                        <td>
-                            <select name="delivery_confirmation_types">
-                                <?php foreach ($block->getDeliveryConfirmationTypes() as $key => $value): ?>
-                                <option value="<?php echo $key ?>" >
-                                    <?php echo $value ?>
-                                </option>
-                                <?php endforeach; ?>
-                            </select>
-                        </td>
-                            <?php endif; ?>
-                        <td class="col-actions">
-                            <button type="button" class="action-add AddItemsBtn" onclick="packaging.getItemsForPack(this);">
-                                <span><?php echo __('Add Products') ?></span>
-                            </button>
-                            <button type="button" class="action-delete DeletePackageBtn" onclick="packaging.deletePackage(this);">
-                                <span><?php echo __('Delete Package') ?></span>
-                            </button>
-                        </td>
-                    </tbody>
-                </table>
 
                 <?php if ($block->getContentTypes()): ?>
-                <table class="package-options package-options-contents data-table" cellspacing="0">
-                    <thead>
-                        <th><?php echo __('Contents') ?></th>
-                        <th><?php echo __('Explanation') ?></th>
-                    </thead>
-                    <tbody>
-                        <td>
-                            <select name="content_type" onchange="packaging.changeContentTypes(this);">
-                                <?php foreach ($block->getContentTypes() as $key => $value): ?>
-                                <option value="<?php echo $key ?>" >
-                                    <?php echo $value ?>
-                                </option>
-                                <?php endforeach; ?>
-                            </select>
-                        </td>
-                        <td>
-                            <input name="content_type_other" type="text" class="input-text options-content-type disabled" disabled="disabled" />
-                        </td>
-                    </tbody>
-                </table>
+                    <table class="package-options package-options-contents data-table" cellspacing="0">
+                        <thead>
+                            <th><?php echo __('Contents') ?></th>
+                            <th><?php echo __('Explanation') ?></th>
+                        </thead>
+                        <tbody>
+                            <td>
+                                <select name="content_type"
+                                        class="admin__control-select"
+                                        onchange="packaging.changeContentTypes(this);">
+                                    <?php foreach ($block->getContentTypes() as $key => $value): ?>
+                                    <option value="<?php echo $key ?>" >
+                                        <?php echo $value ?>
+                                    </option>
+                                    <?php endforeach; ?>
+                                </select>
+                            </td>
+                            <td>
+                                <input name="content_type_other"
+                                       type="text"
+                                       class="input-text admin__control-text options-content-type disabled"
+                                       disabled="disabled" />
+                            </td>
+                        </tbody>
+                    </table>
                 <?php endif; ?>
                 <div class="package-add-products">
                     <div class="package_prapare" style="display:none">
@@ -214,7 +251,11 @@ require([
             <div id="packages_content"></div>
         </div>
         <div class="popup-window-buttons-set">
-            <button type="button" class="action-ok disabled SavePackagesBtn" disabled="disabled" onclick="packaging.confirmPackaging();" title="<?php echo __('Products should be added to package(s)')?>">
+            <button type="button"
+                    class="action-save action-secondary disabled SavePackagesBtn"
+                    disabled="disabled"
+                    onclick="packaging.confirmPackaging();"
+                    title="<?php echo __('Products should be added to package(s)')?>">
                 <span><?php echo __('OK') ?></span>
             </button>
             <button type="button" class="action-close" onclick="packaging.cancelPackaging();">
diff --git a/app/code/Magento/Shipping/view/adminhtml/templates/order/tracking.phtml b/app/code/Magento/Shipping/view/adminhtml/templates/order/tracking.phtml
index bf0b417d2bd8adcde2c95cb38c2db26c8be01a5d..cb8d042a65f47a3d149ac8c99efc87c4ab6d1872 100644
--- a/app/code/Magento/Shipping/view/adminhtml/templates/order/tracking.phtml
+++ b/app/code/Magento/Shipping/view/adminhtml/templates/order/tracking.phtml
@@ -64,34 +64,40 @@ require(['prototype'], function(){
 <script id="track_row_template" type="text/x-magento-template">
     <tr>
         <td class="col-carrier">
-            <select name="tracking[<%- data.index %>][carrier_code]" id="trackingC<%- data.index %>" class="select carrier" disabled="disabled">
+            <select name="tracking[<%- data.index %>][carrier_code]"
+                    id="trackingC<%- data.index %>"
+                    class="select admin__control-select carrier"
+                    disabled="disabled">
                 <?php foreach ($block->getCarriers() as $_code => $_name): ?>
                     <option value="<?php echo $_code ?>"><?php echo $block->escapeHtml($_name) ?></option>
                 <?php endforeach; ?>
             </select>
         </td>
-        <td class="col-title"><input class="input-text number-title" type="text" name="tracking[<%- data.index %>][title]" id="trackingT<%- data.index %>" value="" disabled="disabled" /></td>
-        <td class="col-number"><input class="input-text required-entry" type="text" name="tracking[<%- data.index %>][number]" id="trackingN<%- data.index %>" value="" disabled="disabled" /></td>
-        <td class="col-delete last"><a href="#" class="action- delete" onclick="trackingControl.deleteRow(event);return false"><span><?php echo __('Delete') ?></span></a></td>
+        <td class="col-title"><input class="input-text admin__control-text number-title" type="text" name="tracking[<%- data.index %>][title]" id="trackingT<%- data.index %>" value="" disabled="disabled" /></td>
+        <td class="col-number"><input class="input-text admin__control-text required-entry" type="text" name="tracking[<%- data.index %>][number]" id="trackingN<%- data.index %>" value="" disabled="disabled" /></td>
+        <td class="col-delete"><a href="#" class="action-delete" onclick="trackingControl.deleteRow(event);return false"><span><?php echo __('Delete') ?></span></a></td>
     </tr>
 </script>
-<table cellspacing="0" class="data-table" id="tracking_numbers_table">
-    <thead>
-    <tr class="headings">
-        <th class="col-carrier"><?php echo __('Carrier') ?></th>
-        <th class="col-title"><?php echo __('Title') ?></th>
-        <th class="col-number"><?php echo __('Number') ?></th>
-        <th class="col-delete last"><?php echo __('Action') ?></th>
-    </tr>
-    </thead>
-    <tfoot>
-    <tr>
-        <td colspan="4" class="last col-actions-add"><?php echo $block->getChildHtml('add_button') ?></td>
-    </tr>
-    </tfoot>
-    <tbody id="track_row_container">
-    </tbody>
-</table>
+
+<div class="admin__control-table-wrapper">
+    <table class="data-table admin__control-table" id="tracking_numbers_table">
+        <thead>
+        <tr class="headings">
+            <th class="col-carrier"><?php echo __('Carrier') ?></th>
+            <th class="col-title"><?php echo __('Title') ?></th>
+            <th class="col-number"><?php echo __('Number') ?></th>
+            <th class="col-delete"><?php echo __('Action') ?></th>
+        </tr>
+        </thead>
+        <tfoot>
+        <tr>
+            <td colspan="4" class="col-actions-add"><?php echo $block->getChildHtml('add_button') ?></td>
+        </tr>
+        </tfoot>
+        <tbody id="track_row_container">
+        </tbody>
+    </table>
+</div>
 <script>
 require([
     'mage/template',
diff --git a/app/code/Magento/Shipping/view/adminhtml/templates/order/view/info.phtml b/app/code/Magento/Shipping/view/adminhtml/templates/order/view/info.phtml
index e527501f2e5414cfb1001445b8b43d9cfbe3f544..53ce09410322557fa80728cfe384be1d82f958ef 100644
--- a/app/code/Magento/Shipping/view/adminhtml/templates/order/view/info.phtml
+++ b/app/code/Magento/Shipping/view/adminhtml/templates/order/view/info.phtml
@@ -10,33 +10,32 @@
 <?php /** @var $block \Magento\Shipping\Block\Adminhtml\View */ ?>
 <?php $order = $block->getOrder() ?>
 <?php if ($order->getIsVirtual()) : return '';endif; ?>
-<div class="order-shipping-method">
-    <!--Shipping Method-->
-    <div class="fieldset-wrapper">
-        <div class="fieldset-wrapper-title">
-            <span class="title"><?php echo __('Shipping &amp; Handling Information') ?></span>
-        </div>
-        <div class="shipping-description-wrapper">
-            <?php  if ($order->getTracksCollection()->count()) : ?>
-                <p><a href="#" id="linkId" onclick="popWin('<?php echo $this->helper('Magento\Shipping\Helper\Data')->getTrackingPopupUrlBySalesModel($order) ?>','trackorder','width=800,height=600,resizable=yes,scrollbars=yes')" title="<?php echo __('Track Order') ?>"><?php echo __('Track Order') ?></a></p>
-            <?php endif; ?>
-            <?php if ($order->getShippingDescription()): ?>
-                <strong><?php echo $block->escapeHtml($order->getShippingDescription()) ?></strong>
 
-                <?php if ($this->helper('Magento\Tax\Helper\Data')->displayShippingPriceIncludingTax()): ?>
-                    <?php $_excl = $block->displayShippingPriceInclTax($order); ?>
-                <?php else: ?>
-                    <?php $_excl = $block->displayPriceAttribute('shipping_amount', false, ' '); ?>
-                <?php endif; ?>
-                <?php $_incl = $block->displayShippingPriceInclTax($order); ?>
+<?php /* Shipping Method */ ?>
+<div class="admin__page-section-item order-shipping-method">
+    <div class="admin__page-section-item-title">
+        <span class="title"><?php echo __('Shipping &amp; Handling Information') ?></span>
+    </div>
+    <div class="admin__page-section-item-content">
+        <?php  if ($order->getTracksCollection()->count()) : ?>
+            <p><a href="#" id="linkId" onclick="popWin('<?php echo $this->helper('Magento\Shipping\Helper\Data')->getTrackingPopupUrlBySalesModel($order) ?>','trackorder','width=800,height=600,resizable=yes,scrollbars=yes')" title="<?php echo __('Track Order') ?>"><?php echo __('Track Order') ?></a></p>
+        <?php endif; ?>
+        <?php if ($order->getShippingDescription()): ?>
+            <strong><?php echo $block->escapeHtml($order->getShippingDescription()) ?></strong>
 
-                <?php echo $_excl; ?>
-                <?php if ($this->helper('Magento\Tax\Helper\Data')->displayShippingBothPrices() && $_incl != $_excl): ?>
-                    (<?php echo __('Incl. Tax'); ?> <?php echo $_incl; ?>)
-                <?php endif; ?>
+            <?php if ($this->helper('Magento\Tax\Helper\Data')->displayShippingPriceIncludingTax()): ?>
+                <?php $_excl = $block->displayShippingPriceInclTax($order); ?>
             <?php else: ?>
-                <?php echo __('No shipping information available'); ?>
+                <?php $_excl = $block->displayPriceAttribute('shipping_amount', false, ' '); ?>
+            <?php endif; ?>
+            <?php $_incl = $block->displayShippingPriceInclTax($order); ?>
+
+            <?php echo $_excl; ?>
+            <?php if ($this->helper('Magento\Tax\Helper\Data')->displayShippingBothPrices() && $_incl != $_excl): ?>
+                (<?php echo __('Incl. Tax'); ?> <?php echo $_incl; ?>)
             <?php endif; ?>
-        </div>
+        <?php else: ?>
+            <?php echo __('No shipping information available'); ?>
+        <?php endif; ?>
     </div>
 </div>
diff --git a/app/code/Magento/Shipping/view/adminhtml/templates/view/form.phtml b/app/code/Magento/Shipping/view/adminhtml/templates/view/form.phtml
index 7a777c90d468a360a1279cdbccc9f333e8d4d4f4..16dc0556a52a2bdad4ad53a86293f6e842737f38 100644
--- a/app/code/Magento/Shipping/view/adminhtml/templates/view/form.phtml
+++ b/app/code/Magento/Shipping/view/adminhtml/templates/view/form.phtml
@@ -9,94 +9,110 @@
 ?>
 <?php  $_order = $block->getShipment()->getOrder() ?>
 <?php echo $block->getChildHtml('order_info') ?>
-<div class="clearfix">
-    <div class="order-payment-method">
+<section class="admin__page-section order-shipment-billing-shipping">
+    <div class="admin__page-section-title">
+        <span class="title"><?php echo __('Payment &amp; Shipping Method') ?></span>
+    </div>
+    <div class="admin__page-section-content">
+
         <?php /* Billing Address */ ?>
-        <div class="fieldset-wrapper">
-            <div class="fieldset-wrapper-title">
+        <div class="admin__page-section-item order-payment-method">
+            <div class="admin__page-section-item-title">
                 <span class="title"><?php echo __('Payment Information') ?></span>
             </div>
-            <div><?php echo $block->getChildHtml('order_payment') ?></div>
-            <div class="order-payment-currency"><?php echo __('The order was placed using %1.', $_order->getOrderCurrencyCode()) ?></div>
+            <div class="admin__page-section-item-content">
+                <div><?php echo $block->getChildHtml('order_payment') ?></div>
+                <div class="order-payment-currency"><?php echo __('The order was placed using %1.', $_order->getOrderCurrencyCode()) ?></div>
+            </div>
         </div>
-    </div>
-    <div class="order-shipping-address">
+
         <?php /* Shipping Address */ ?>
-        <div class="fieldset-wrapper">
-            <div class="fieldset-wrapper-title">
+        <div class="admin__page-section-item order-shipping-address">
+            <div class="admin__page-section-item-title">
                 <span class="title"><?php echo __('Shipping and Tracking Information') ?></span>
             </div>
-            <div class="shipping-description-wrapper">
-                <?php if ($block->getShipment()->getTracksCollection()->count()): ?>
-                <p>
-                    <a href="#" id="linkId" onclick="popWin('<?php echo $this->helper('Magento\Shipping\Helper\Data')->getTrackingPopupUrlBySalesModel($block->getShipment()) ?>','trackshipment','width=800,height=600,resizable=yes,scrollbars=yes')" title="<?php echo __('Track this shipment') ?>"><?php echo __('Track this shipment') ?></a>
-                </p>
-                <?php endif; ?>
-                <div class="shipping-description-title"><?php echo $block->escapeHtml($_order->getShippingDescription()) ?></div>
-                <?php echo __('Total Shipping Charges'); ?>:
+            <div class="admin__page-section-item-content">
+                <div class="shipping-description-wrapper">
+                    <?php if ($block->getShipment()->getTracksCollection()->count()): ?>
+                        <p>
+                            <a href="#" id="linkId" onclick="popWin('<?php echo $this->helper('Magento\Shipping\Helper\Data')->getTrackingPopupUrlBySalesModel($block->getShipment()) ?>','trackshipment','width=800,height=600,resizable=yes,scrollbars=yes')" title="<?php echo __('Track this shipment') ?>"><?php echo __('Track this shipment') ?></a>
+                        </p>
+                    <?php endif; ?>
+                    <div class="shipping-description-title">
+                        <?php echo $block->escapeHtml($_order->getShippingDescription()) ?>
+                    </div>
 
-                <?php if ($this->helper('Magento\Tax\Helper\Data')->displayShippingPriceIncludingTax()): ?>
-                    <?php $_excl = $block->displayShippingPriceInclTax($_order); ?>
-                <?php else: ?>
-                    <?php $_excl = $block->displayPriceAttribute('shipping_amount', false, ' '); ?>
-                <?php endif; ?>
-                <?php $_incl = $block->displayShippingPriceInclTax($_order); ?>
+                    <?php echo __('Total Shipping Charges'); ?>:
 
-                <?php echo $_excl; ?>
-                <?php if ($this->helper('Magento\Tax\Helper\Data')->displayShippingBothPrices() && $_incl != $_excl): ?>
-                    (<?php echo __('Incl. Tax'); ?> <?php echo $_incl; ?>)
-                <?php endif; ?>
-            </div>
-            <?php if ($block->canCreateShippingLabel()): ?>
-            <p>
-                <?php echo $block->getCreateLabelButton()?>
-                <?php if ($block->getShipment()->getShippingLabel()): ?>
-                    <?php echo $block->getPrintLabelButton() ?>
-                <?php endif ?>
-                <?php if ($block->getShipment()->getPackages()): ?>
-                    <?php echo $block->getShowPackagesButton() ?>
+                    <?php if ($this->helper('Magento\Tax\Helper\Data')->displayShippingPriceIncludingTax()): ?>
+                        <?php $_excl = $block->displayShippingPriceInclTax($_order); ?>
+                    <?php else: ?>
+                        <?php $_excl = $block->displayPriceAttribute('shipping_amount', false, ' '); ?>
+                    <?php endif; ?>
+                    <?php $_incl = $block->displayShippingPriceInclTax($_order); ?>
+
+                    <?php echo $_excl; ?>
+                    <?php if ($this->helper('Magento\Tax\Helper\Data')->displayShippingBothPrices() && $_incl != $_excl): ?>
+                        (<?php echo __('Incl. Tax'); ?> <?php echo $_incl; ?>)
+                    <?php endif; ?>
+                </div>
+                <?php if ($block->canCreateShippingLabel()): ?>
+                <p>
+                    <?php echo $block->getCreateLabelButton()?>
+                    <?php if ($block->getShipment()->getShippingLabel()): ?>
+                        <?php echo $block->getPrintLabelButton() ?>
+                    <?php endif ?>
+                    <?php if ($block->getShipment()->getPackages()): ?>
+                        <?php echo $block->getShowPackagesButton() ?>
+                    <?php endif ?>
+                </p>
                 <?php endif ?>
-            </p>
-            <?php endif ?>
-            <div><?php echo $block->getChildHtml('shipment_tracking') ?></div>
-        <?php echo $block->getChildHtml('shipment_packaging') ?>
-        <script>
-require([
-    'prototype'
-], function(){
+                <?php echo $block->getChildHtml('shipment_tracking') ?>
 
-    setTimeout(function(){
-        packaging.setConfirmPackagingCallback(function(){
-            packaging.sendCreateLabelRequest();
-        });
-        packaging.setLabelCreatedCallback(function(response){
-            setLocation("<?php echo $block->getUrl(
-                'adminhtml/order_shipment/view',
-                ['shipment_id' => $block->getShipment()->getId()]
-            ); ?>");
-        });
-    }, 500);
+                <?php echo $block->getChildHtml('shipment_packaging') ?>
+<script>
+    require([
+        'prototype'
+    ], function () {
 
-});
+        setTimeout(function () {
+            packaging.setConfirmPackagingCallback(function () {
+                packaging.sendCreateLabelRequest();
+            });
+            packaging.setLabelCreatedCallback(function (response) {
+                setLocation("<?php echo $block->getUrl(
+'adminhtml/order_shipment/view',
+['shipment_id' => $block->getShipment()->getId()]
+); ?>");
+            });
+        }, 500);
+
+    });
 </script>
+            </div>
         </div>
     </div>
-</div>
+</section>
 
-<div class="fieldset-wrapper">
-    <div class="fieldset-wrapper-title">
+<section class="admin__page-section">
+    <div class="admin__page-section-title">
         <span class="title"><?php echo __('Items Shipped') ?></span>
     </div>
     <?php echo $block->getChildHtml('shipment_items') ?>
-</div>
+</section>
 
-<div class="clearfix">
-    <?php echo $block->getChildHtml('shipment_packed') ?>
+<section class="admin__page-section">
+    <div class="admin__page-section-title">
+        <span class="title"><?php echo __('Order Total') ?></span>
+    </div>
+    <div class="admin__page-section-content">
+        <?php echo $block->getChildHtml('shipment_packed') ?>
 
-    <div class="order-comments-history">
-        <div class="fieldset-wrapper">
-            <div class="fieldset-wrapper-title"><span class="title"><?php echo __('Shipment History') ?></span></div>
-            <fieldset><?php echo $block->getChildHtml('order_comments') ?></fieldset>
+        <div class="admin__page-section-item order-comments-history">
+            <div class="admin__page-section-item-title">
+                <span class="title"><?php echo __('Shipment History') ?></span>
+            </div>
+            <div class="admin__page-section-item-content"><?php echo $block->getChildHtml('order_comments') ?></div>
         </div>
     </div>
-</div>
+</section>
diff --git a/app/code/Magento/Shipping/view/adminhtml/templates/view/items.phtml b/app/code/Magento/Shipping/view/adminhtml/templates/view/items.phtml
index 4b1d0f39d52bc9a77a7d69ed882368aa6fcdc7dd..1ebeae21eb75e8c9201b4a1c91df6c3d5eb09d6c 100644
--- a/app/code/Magento/Shipping/view/adminhtml/templates/view/items.phtml
+++ b/app/code/Magento/Shipping/view/adminhtml/templates/view/items.phtml
@@ -8,7 +8,7 @@
 
 ?>
 <div class="grid">
-    <table cellspacing="0" class="data">
+    <table class="data-table admin__table-primary order-shipment-table">
         <thead>
             <tr class="headings">
                 <th class="col-product"><span><?php echo __('Product') ?></span></th>
diff --git a/app/code/Magento/Shipping/view/adminhtml/web/order/packaging.js b/app/code/Magento/Shipping/view/adminhtml/web/order/packaging.js
index 566b01dc6e894f41d5521a2c958e05e4b0356c41..fca9b0553afa7a9de06030524a0259bdc4bca504 100644
--- a/app/code/Magento/Shipping/view/adminhtml/web/order/packaging.js
+++ b/app/code/Magento/Shipping/view/adminhtml/web/order/packaging.js
@@ -18,7 +18,7 @@ Packaging.prototype = {
         this.errorQtyOverLimit = params.errorQtyOverLimit;
         this.titleDisabledSaveBtn = params.titleDisabledSaveBtn;
         this.window = $('packaging_window');
-        this.messages = this.window.select('.messages')[0];
+        this.messages = this.window.select('.message-warning')[0];
         this.packagesContent = $('packages_content');
         this.template = $('package_template');
         this.paramsCreateLabelRequest = {};
diff --git a/app/code/Magento/Sitemap/composer.json b/app/code/Magento/Sitemap/composer.json
index 1fa5a0e4091d5cbbe06a12b2229f626960b65e15..883491985063302b2fd8b31d42895b9b2df5ccfe 100644
--- a/app/code/Magento/Sitemap/composer.json
+++ b/app/code/Magento/Sitemap/composer.json
@@ -3,18 +3,18 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/module-eav": "0.74.0-beta6",
-        "magento/module-cms": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-catalog-url-rewrite": "0.74.0-beta6",
-        "magento/module-media-storage": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/module-eav": "0.74.0-beta7",
+        "magento/module-cms": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-catalog-url-rewrite": "0.74.0-beta7",
+        "magento/module-media-storage": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Store/App/FrontController/Plugin/RequestPreprocessor.php b/app/code/Magento/Store/App/FrontController/Plugin/RequestPreprocessor.php
index 57307c083d01246894146ce4e3aa865a172bee20..4d5e21f50edd3273c794c866c5e86d6ebfc8f679 100644
--- a/app/code/Magento/Store/App/FrontController/Plugin/RequestPreprocessor.php
+++ b/app/code/Magento/Store/App/FrontController/Plugin/RequestPreprocessor.php
@@ -79,6 +79,7 @@ class RequestPreprocessor
 
                     $response = $this->_responseFactory->create();
                     $response->setRedirect($redirectUrl, $redirectCode);
+                    $response->setNoCacheHeaders();
                     return $response;
                 }
             }
diff --git a/app/code/Magento/Store/Model/Config/Reader/DefaultReader.php b/app/code/Magento/Store/Model/Config/Reader/DefaultReader.php
index 4f03885e8cd7a910cb35abf05970bd86deb5a790..7bb9981369440c9c8062ffe6308376c8b089a05f 100644
--- a/app/code/Magento/Store/Model/Config/Reader/DefaultReader.php
+++ b/app/code/Magento/Store/Model/Config/Reader/DefaultReader.php
@@ -7,6 +7,9 @@
  */
 namespace Magento\Store\Model\Config\Reader;
 
+use Magento\Framework\App\Config\ScopeConfigInterface;
+use Magento\Framework\Exception\LocalizedException;
+
 class DefaultReader implements \Magento\Framework\App\Config\Scope\ReaderInterface
 {
     /**
@@ -42,14 +45,21 @@ class DefaultReader implements \Magento\Framework\App\Config\Scope\ReaderInterfa
     /**
      * Read configuration data
      *
+     * @param null|string $scope
+     * @throws LocalizedException Exception is thrown when scope other than default is given
      * @return array
      */
-    public function read()
+    public function read($scope = null)
     {
-        $config = $this->_initialConfig->getData(\Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT);
+        $scope = $scope === null ? ScopeConfigInterface::SCOPE_TYPE_DEFAULT : $scope;
+        if ($scope !== ScopeConfigInterface::SCOPE_TYPE_DEFAULT) {
+            throw new \Magento\Framework\Exception\LocalizedException(__("Only default scope allowed"));
+        }
+
+        $config = $this->_initialConfig->getData($scope);
 
         $collection = $this->_collectionFactory->create(
-            ['scope' => \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT]
+            ['scope' => $scope]
         );
         $dbDefaultConfig = [];
         foreach ($collection as $item) {
diff --git a/app/code/Magento/Store/Model/Config/Reader/Store.php b/app/code/Magento/Store/Model/Config/Reader/Store.php
index c5456bcb102f9ad2952c17f33ac41f48c1ae777a..151c3625f2b1dbf596d222eaf10b3f7c9e07ce5e 100644
--- a/app/code/Magento/Store/Model/Config/Reader/Store.php
+++ b/app/code/Magento/Store/Model/Config/Reader/Store.php
@@ -5,6 +5,7 @@
  */
 namespace Magento\Store\Model\Config\Reader;
 
+use Magento\Framework\App\Config\ScopeConfigInterface;
 use Magento\Framework\Exception\NoSuchEntityException;
 
 class Store implements \Magento\Framework\App\Config\Scope\ReaderInterface
@@ -66,7 +67,7 @@ class Store implements \Magento\Framework\App\Config\Scope\ReaderInterface
     /**
      * Read configuration by code
      *
-     * @param string $code
+     * @param null|string $code
      * @return array
      * @throws NoSuchEntityException
      */
@@ -74,7 +75,7 @@ class Store implements \Magento\Framework\App\Config\Scope\ReaderInterface
     {
         if (empty($code)) {
             $store = $this->_storeManager->getStore();
-        } elseif (($code == \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT)) {
+        } elseif (($code == ScopeConfigInterface::SCOPE_TYPE_DEFAULT)) {
             $store = $this->_storeManager->getDefaultStoreView();
         } else {
             $store = $this->_storeFactory->create();
diff --git a/app/code/Magento/Store/Model/Config/Reader/Website.php b/app/code/Magento/Store/Model/Config/Reader/Website.php
index 1448b04bf9afbf5e6b49b5e223f53b9ec2a52f69..7971deb6c9713199cfe7c85617ebe767556edb18 100644
--- a/app/code/Magento/Store/Model/Config/Reader/Website.php
+++ b/app/code/Magento/Store/Model/Config/Reader/Website.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\Store\Model\Config\Reader;
 
+use Magento\Framework\App\Config\ScopeConfigInterface;
+
 class Website implements \Magento\Framework\App\Config\Scope\ReaderInterface
 {
     /**
@@ -62,7 +64,7 @@ class Website implements \Magento\Framework\App\Config\Scope\ReaderInterface
     public function read($code = null)
     {
         $config = array_replace_recursive(
-            $this->_scopePool->getScope(\Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT)->getSource(),
+            $this->_scopePool->getScope(ScopeConfigInterface::SCOPE_TYPE_DEFAULT)->getSource(),
             $this->_initialConfig->getData("websites|{$code}")
         );
 
diff --git a/app/code/Magento/Store/Model/Store.php b/app/code/Magento/Store/Model/Store.php
index 7dbf046110e38000509cbd55318a57efbc1b80f0..494d1c129254154208d81e6956d72027003f9dc4 100644
--- a/app/code/Magento/Store/Model/Store.php
+++ b/app/code/Magento/Store/Model/Store.php
@@ -5,6 +5,7 @@
  */
 namespace Magento\Store\Model;
 
+use Magento\Framework\App\Config\ScopeConfigInterface;
 use Magento\Framework\App\Filesystem\DirectoryList;
 use Magento\Framework\App\Http\Context;
 use Magento\Framework\Model\AbstractModel;
@@ -55,7 +56,7 @@ class Store extends AbstractModel implements
     const XML_PATH_UNSECURE_BASE_URL = 'web/unsecure/base_url';
 
     const XML_PATH_SECURE_BASE_URL = 'web/secure/base_url';
-    
+
     const XML_PATH_SECURE_IN_FRONTEND = 'web/secure/use_in_frontend';
 
     const XML_PATH_SECURE_IN_ADMINHTML = 'web/secure/use_in_adminhtml';
@@ -479,7 +480,7 @@ class Store extends AbstractModel implements
     {
         $data = $this->_config->getValue($path, ScopeInterface::SCOPE_STORE, $this->getCode());
         if (!$data) {
-            $data = $this->_config->getValue($path, \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT);
+            $data = $this->_config->getValue($path, ScopeConfigInterface::SCOPE_TYPE_DEFAULT);
         }
         return $data === false ? null : $data;
     }
@@ -755,7 +756,12 @@ class Store extends AbstractModel implements
             \Magento\Store\Model\ScopeInterface::SCOPE_STORE
         );
 
-        if (!$secureBaseUrl) {
+        if (!$secureBaseUrl ||
+            !$this->_config->getValue(
+                self::XML_PATH_SECURE_IN_FRONTEND,
+                \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+            )
+        ) {
             return false;
         }
 
@@ -783,7 +789,7 @@ class Store extends AbstractModel implements
         if ($configValue == self::PRICE_SCOPE_GLOBAL) {
             return $this->_config->getValue(
                 \Magento\Directory\Model\Currency::XML_PATH_CURRENCY_BASE,
-                \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT
+                ScopeConfigInterface::SCOPE_TYPE_DEFAULT
             );
         } else {
             return $this->_getConfig(\Magento\Directory\Model\Currency::XML_PATH_CURRENCY_BASE);
diff --git a/app/code/Magento/Store/Model/System/Store.php b/app/code/Magento/Store/Model/System/Store.php
index 1859a2957d92f927491aaa33b541d7cab1fa068f..c3382ce1968cf415874b468b6e8126538a75ec9d 100644
--- a/app/code/Magento/Store/Model/System/Store.php
+++ b/app/code/Magento/Store/Model/System/Store.php
@@ -5,10 +5,12 @@
  */
 namespace Magento\Store\Model\System;
 
+use Magento\Framework\Data\OptionSourceInterface;
+
 /**
  * Core System Store Model
  */
-class Store extends \Magento\Framework\Object
+class Store extends \Magento\Framework\Object implements OptionSourceInterface
 {
     /**
      * Website collection
@@ -458,4 +460,14 @@ class Store extends \Magento\Framework\Object
         $this->_isAdminScopeAllowed = (bool)$value;
         return $this;
     }
+
+    /**
+     * Return array of options as value-label pairs
+     *
+     * @return array Format: array(array('value' => '<value>', 'label' => '<label>'), ...)
+     */
+    public function toOptionArray()
+    {
+        return $this->getStoreValuesForForm();
+    }
 }
diff --git a/app/code/Magento/Store/Test/Unit/Model/Config/Reader/DefaultReaderTest.php b/app/code/Magento/Store/Test/Unit/Model/Config/Reader/DefaultReaderTest.php
index 9e91f4b43281522ac0a2d3688167488893df43e3..25875ae67dd5973525a0a59cbf7e2c1635c58691 100644
--- a/app/code/Magento/Store/Test/Unit/Model/Config/Reader/DefaultReaderTest.php
+++ b/app/code/Magento/Store/Test/Unit/Model/Config/Reader/DefaultReaderTest.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\Store\Test\Unit\Model\Config\Reader;
 
+use Magento\Framework\App\Config\ScopeConfigInterface;
+
 class DefaultReaderTest extends \PHPUnit_Framework_TestCase
 {
     /**
@@ -46,7 +48,7 @@ class DefaultReaderTest extends \PHPUnit_Framework_TestCase
         )->method(
             'getData'
         )->with(
-            \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT
+            ScopeConfigInterface::SCOPE_TYPE_DEFAULT
         )->will(
             $this->returnValue(['config' => ['key1' => 'default_value1', 'key2' => 'default_value2']])
         );
diff --git a/app/code/Magento/Store/Test/Unit/Model/StoreTest.php b/app/code/Magento/Store/Test/Unit/Model/StoreTest.php
index c43af1f004dfe6972d9521e3d49bd6474fb99a4b..8d305848c554f900bd521f04490c7b8f18fca6a4 100644
--- a/app/code/Magento/Store/Test/Unit/Model/StoreTest.php
+++ b/app/code/Magento/Store/Test/Unit/Model/StoreTest.php
@@ -8,6 +8,7 @@
 
 namespace Magento\Store\Test\Unit\Model;
 
+use Magento\Framework\App\Config\ScopeConfigInterface;
 use Magento\Store\Model\ScopeInterface;
 use Magento\Framework\App\Config\ReinitableConfigInterface;
 use Magento\Store\Model\Store;
@@ -399,7 +400,7 @@ class StoreTest extends \PHPUnit_Framework_TestCase
                 ['catalog/price/scope', ScopeInterface::SCOPE_STORE, 'scope_code', $priceScope],
                 [
                     \Magento\Directory\Model\Currency::XML_PATH_CURRENCY_BASE,
-                    \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT,
+                    ScopeConfigInterface::SCOPE_TYPE_DEFAULT,
                     null,
                     'USD'
                 ],
@@ -546,12 +547,15 @@ class StoreTest extends \PHPUnit_Framework_TestCase
      *
      * @param bool $expected
      * @param array $value
+     * @param bool $requestSecure
+     * @param bool $useSecureInFrontend
      * @param string|null $secureBaseUrl
      */
     public function testIsCurrentlySecure(
         $expected,
         $value,
         $requestSecure = false,
+        $useSecureInFrontend = true,
         $secureBaseUrl = 'https://example.com:443'
     ) {
         /* @var ReinitableConfigInterface|PHPUnit_Framework_MockObject_MockObject $configMock */
@@ -565,6 +569,12 @@ class StoreTest extends \PHPUnit_Framework_TestCase
                             null,
                             $secureBaseUrl
                         ],
+                        [
+                            Store::XML_PATH_SECURE_IN_FRONTEND,
+                            ScopeInterface::SCOPE_STORE,
+                            null,
+                            $useSecureInFrontend
+                        ]
                     ]));
 
         $this->requestMock->expects($this->any())
@@ -594,8 +604,12 @@ class StoreTest extends \PHPUnit_Framework_TestCase
         return [
             'secure request, no server setting' => [true, [], true],
             'unsecure request, using registered port' => [true, 443],
-            'unsecure request, no secure base url registered' => [false, 443, false, null],
+            'unsecure request, no secure base url registered' => [false, 443, false, true, null],
             'unsecure request, not using registered port' => [false, 80],
+            'unsecure request, using registered port, not using secure in frontend' => [false, 443, false, false],
+            'unsecure request, no secure base url registered, not using secure in frontend' =>
+                [false, 443, false, false, null],
+            'unsecure request, not using registered port, not using secure in frontend' => [false, 80, false, false],
         ];
     }
 
diff --git a/app/code/Magento/Store/Ui/DataProvider/Row.php b/app/code/Magento/Store/Ui/Component/Listing/Column/Store.php
similarity index 59%
rename from app/code/Magento/Store/Ui/DataProvider/Row.php
rename to app/code/Magento/Store/Ui/Component/Listing/Column/Store.php
index e48e25ca61cba0b95b52af9c35ef079e8952b0db..08b0387396799d9b63b3a2f7f1b0982605a700b8 100644
--- a/app/code/Magento/Store/Ui/DataProvider/Row.php
+++ b/app/code/Magento/Store/Ui/Component/Listing/Column/Store.php
@@ -3,16 +3,18 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-namespace Magento\Store\Ui\DataProvider;
+namespace Magento\Store\Ui\Component\Listing\Column;
 
 use Magento\Framework\Escaper;
+use Magento\Framework\View\Element\UiComponent\ContextInterface;
+use Magento\Framework\View\Element\UiComponentFactory;
 use Magento\Store\Model\System\Store as SystemStore;
-use Magento\Ui\Component\Listing\RowInterface;
+use Magento\Ui\Component\Listing\Columns\Column;
 
 /**
  * Class Store
  */
-class Row implements RowInterface
+class Store extends Column
 {
     /**
      * Escaper
@@ -31,26 +33,48 @@ class Row implements RowInterface
     /**
      * Constructor
      *
+     * @param ContextInterface $context
+     * @param UiComponentFactory $uiComponentFactory
      * @param SystemStore $systemStore
      * @param Escaper $escaper
+     * @param array $components
+     * @param array $data
      */
-    public function __construct(SystemStore $systemStore, Escaper $escaper)
-    {
+    public function __construct(
+        ContextInterface $context,
+        UiComponentFactory $uiComponentFactory,
+        SystemStore $systemStore,
+        Escaper $escaper,
+        array $components = [],
+        array $data = []
+    ) {
         $this->systemStore = $systemStore;
         $this->escaper = $escaper;
+        parent::__construct($context, $uiComponentFactory, $components, $data);
+    }
+
+    /**
+     * @param array $items
+     * @return array
+     */
+    public function prepareItems(array & $items)
+    {
+        foreach ($items as & $item) {
+            $item[$this->getData('name')] = $this->prepareItem($item);
+        }
+        return $items;
     }
 
     /**
      * Get data
      *
-     * @param array $dataRow
-     * @param array $data
+     * @param array $item
      * @return mixed
      */
-    public function getData(array $dataRow, array $data = [])
+    public function prepareItem(array $item)
     {
         $content = '';
-        $origStores = $dataRow['store_id'];
+        $origStores = $item['store_id'];
 
         if (empty($origStores)) {
             return '';
diff --git a/app/code/Magento/Store/Ui/DataProvider/Options.php b/app/code/Magento/Store/Ui/Component/Listing/Column/Store/Options.php
similarity index 80%
rename from app/code/Magento/Store/Ui/DataProvider/Options.php
rename to app/code/Magento/Store/Ui/Component/Listing/Column/Store/Options.php
index 950f5bbb606932f456bbeccf859580d3af187639..308a21b9f3100446ae33487823ae10e73ffcc2e6 100644
--- a/app/code/Magento/Store/Ui/DataProvider/Options.php
+++ b/app/code/Magento/Store/Ui/Component/Listing/Column/Store/Options.php
@@ -3,16 +3,16 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-namespace Magento\Store\Ui\DataProvider;
+namespace Magento\Store\Ui\Component\Listing\Column\Store;
 
 use Magento\Framework\Escaper;
+use Magento\Framework\Data\OptionSourceInterface;
 use Magento\Store\Model\System\Store as SystemStore;
-use Magento\Ui\Component\Listing\OptionsInterface;
 
 /**
- * Class Store
+ * Class Options
  */
-class Options implements OptionsInterface
+class Options implements OptionSourceInterface
 {
     /**
      * Escaper
@@ -28,6 +28,11 @@ class Options implements OptionsInterface
      */
     protected $systemStore;
 
+    /**
+     * @var array
+     */
+    protected $options;
+
     /**
      * Constructor
      *
@@ -43,11 +48,13 @@ class Options implements OptionsInterface
     /**
      * Get options
      *
-     * @param array $options
      * @return array
      */
-    public function getOptions(array $options = [])
+    public function toOptionArray()
     {
+        if ($this->options !== null) {
+            return $this->options;
+        }
         $websiteCollection = $this->systemStore->getWebsiteCollection();
         $groupCollection = $this->systemStore->getGroupCollection();
         $storeCollection = $this->systemStore->getStoreCollection();
@@ -76,17 +83,18 @@ class Options implements OptionsInterface
                     if (!empty($stores)) {
                         $name = $this->escaper->escapeHtml($group->getName());
                         $groups[$name]['label'] = str_repeat(' ', 4) . $name;
-                        $groups[$name]['value'] = $stores;
+                        $groups[$name]['value'] = array_values($stores);
                     }
                 }
             }
             if (!empty($groups)) {
                 $name = $this->escaper->escapeHtml($website->getName());
                 $currentOptions[$name]['label'] = $name;
-                $currentOptions[$name]['value'] = $groups;
+                $currentOptions[$name]['value'] = array_values($groups);
             }
         }
+        $this->options = array_values($currentOptions);
 
-        return array_merge_recursive($currentOptions, $options);
+        return $this->options;
     }
 }
diff --git a/app/code/Magento/Store/Ui/DataType/Store.php b/app/code/Magento/Store/Ui/DataType/Store.php
deleted file mode 100644
index 906ecaa02921f6a8e8ceef2d33074296c88bffcb..0000000000000000000000000000000000000000
--- a/app/code/Magento/Store/Ui/DataType/Store.php
+++ /dev/null
@@ -1,16 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Store\Ui\DataType;
-
-use Magento\Ui\Component\Form\Element\DataType\AbstractDataType;
-
-/**
- * Class Store
- */
-class Store extends AbstractDataType
-{
-    //
-}
diff --git a/app/code/Magento/Store/composer.json b/app/code/Magento/Store/composer.json
index d2c3e97181c1e980a0406709dd6c35b74a84a344..2dd66eda7c2112a897d68317d093fa5b0e9fe783 100644
--- a/app/code/Magento/Store/composer.json
+++ b/app/code/Magento/Store/composer.json
@@ -3,15 +3,15 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-directory": "0.74.0-beta6",
-        "magento/module-ui": "0.74.0-beta6",
-        "magento/module-config": "0.74.0-beta6",
-        "magento/module-media-storage": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-directory": "0.74.0-beta7",
+        "magento/module-ui": "0.74.0-beta7",
+        "magento/module-config": "0.74.0-beta7",
+        "magento/module-media-storage": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Store/etc/di.xml b/app/code/Magento/Store/etc/di.xml
index ebbc61f6036c8723c1fe943e07795097b63f1f6d..c1584145c2d3db3ad86924dd7ac6b0099155aa18 100644
--- a/app/code/Magento/Store/etc/di.xml
+++ b/app/code/Magento/Store/etc/di.xml
@@ -79,7 +79,7 @@
         <arguments>
             <argument name="session" xsi:type="object" shared="false">Magento\Framework\Session\Generic\Proxy</argument>
             <argument name="isCustomEntryPoint" xsi:type="init_parameter">Magento\Store\Model\Store::CUSTOM_ENTRY_POINT_PARAM</argument>
-            <argument name="url" xsi:type="object" shared="false">Magento\Framework\UrlInterface</argument>
+            <argument name="url" xsi:type="object" shared="false">Magento\Framework\UrlInterface\Proxy</argument>
         </arguments>
     </type>
     <type name="Magento\Store\Model\StoreManager">
diff --git a/app/code/Magento/Store/view/base/layout/ui_components.xml b/app/code/Magento/Store/view/base/layout/ui_components.xml
deleted file mode 100644
index 54811dfdf1f4035178f5a1aee01ba34923527b28..0000000000000000000000000000000000000000
--- a/app/code/Magento/Store/view/base/layout/ui_components.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0"?>
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/layout_generic.xsd">
-    <block class="Magento\Ui\Component\Filter\Type\Select" name="filter_store">
-        <arguments>
-            <argument name="content_template" xsi:type="string">Magento_Ui::filter/type/select/default.phtml</argument>
-        </arguments>
-    </block>
-    <block class="Magento\Ui\Component\Form\Element\DataType\Text" name="store">
-        <arguments>
-            <argument name="content_template" xsi:type="string">Magento_Ui::data_type/text/default.phtml</argument>
-        </arguments>
-    </block>
-</layout>
diff --git a/app/code/Magento/Tax/Api/Data/AppliedTaxInterface.php b/app/code/Magento/Tax/Api/Data/AppliedTaxInterface.php
index 356d39d0bc106519315c3fa76da8321931c116fd..a5865871a5f59f25f9d72d624d277088d5f4ae41 100644
--- a/app/code/Magento/Tax/Api/Data/AppliedTaxInterface.php
+++ b/app/code/Magento/Tax/Api/Data/AppliedTaxInterface.php
@@ -7,18 +7,6 @@ namespace Magento\Tax\Api\Data;
 
 interface AppliedTaxInterface extends \Magento\Framework\Api\ExtensibleDataInterface
 {
-    /**#@+
-     * Constants defined for keys of array, makes typos less likely
-     */
-    const KEY_TAX_RATE_KEY = 'tax_rate_key';
-
-    const KEY_PERCENT = 'percent';
-
-    const KEY_AMOUNT = 'amount';
-
-    const KEY_RATES = 'rates';
-    /**#@-*/
-
     /**
      * Get tax rate key
      *
diff --git a/app/code/Magento/Tax/Api/Data/AppliedTaxRateInterface.php b/app/code/Magento/Tax/Api/Data/AppliedTaxRateInterface.php
index cee4ab16fd1f0acdde90bd353b3d264e4ba52b11..afd3231335ea011e6daed2e0fa5537849c376362 100644
--- a/app/code/Magento/Tax/Api/Data/AppliedTaxRateInterface.php
+++ b/app/code/Magento/Tax/Api/Data/AppliedTaxRateInterface.php
@@ -8,16 +8,6 @@ namespace Magento\Tax\Api\Data;
 
 interface AppliedTaxRateInterface extends \Magento\Framework\Api\ExtensibleDataInterface
 {
-    /**#@+
-     * Constants defined for keys of array, makes typos less likely
-     */
-    const KEY_CODE = 'code';
-
-    const KEY_TITLE = 'title';
-
-    const KEY_PERCENT = 'percent';
-    /**#@-*/
-
     /**
      * Get code
      *
diff --git a/app/code/Magento/Tax/Api/Data/OrderTaxDetailsAppliedTaxInterface.php b/app/code/Magento/Tax/Api/Data/OrderTaxDetailsAppliedTaxInterface.php
index 7123087eacf565f0341178e6f9643c9a98bf7036..603d287eabff739644b9ed7ada2d397b4c59d857 100644
--- a/app/code/Magento/Tax/Api/Data/OrderTaxDetailsAppliedTaxInterface.php
+++ b/app/code/Magento/Tax/Api/Data/OrderTaxDetailsAppliedTaxInterface.php
@@ -9,20 +9,6 @@ namespace Magento\Tax\Api\Data;
 
 interface OrderTaxDetailsAppliedTaxInterface extends \Magento\Framework\Api\ExtensibleDataInterface
 {
-    /**#@+
-     * Constants defined for keys of array, makes typos less likely
-     */
-    const KEY_CODE = 'code';
-
-    const KEY_TITLE = 'title';
-
-    const KEY_PERCENT = 'percent';
-
-    const KEY_AMOUNT = 'amount';
-
-    const KEY_BASE_AMOUNT = 'base_amount';
-    /**#@-*/
-
     /**
      * Get code
      *
diff --git a/app/code/Magento/Tax/Api/Data/OrderTaxDetailsInterface.php b/app/code/Magento/Tax/Api/Data/OrderTaxDetailsInterface.php
index d68de6f5858aab5c3362c60d62a1d006bc22c42d..d57fb6ba5194faac79dbcddd4e0269adb81c6dae 100644
--- a/app/code/Magento/Tax/Api/Data/OrderTaxDetailsInterface.php
+++ b/app/code/Magento/Tax/Api/Data/OrderTaxDetailsInterface.php
@@ -9,10 +9,6 @@ namespace Magento\Tax\Api\Data;
 
 interface OrderTaxDetailsInterface extends \Magento\Framework\Api\ExtensibleDataInterface
 {
-    const KEY_APPLIED_TAXES = 'applied_taxes';
-
-    const KEY_ITEMS = 'items';
-
     /**
      * Get applied taxes at order level
      *
diff --git a/app/code/Magento/Tax/Api/Data/OrderTaxDetailsItemInterface.php b/app/code/Magento/Tax/Api/Data/OrderTaxDetailsItemInterface.php
index 905a0aa203594097e5377130679dfb4e5bb18a92..a43d4ccd7dfc4b5f1f95ed1fbf29527bdea40e89 100644
--- a/app/code/Magento/Tax/Api/Data/OrderTaxDetailsItemInterface.php
+++ b/app/code/Magento/Tax/Api/Data/OrderTaxDetailsItemInterface.php
@@ -9,18 +9,6 @@ namespace Magento\Tax\Api\Data;
 
 interface OrderTaxDetailsItemInterface extends \Magento\Framework\Api\ExtensibleDataInterface
 {
-    /**#@+
-     * Constants defined for keys of array, makes typos less likely
-     */
-    const KEY_TYPE = 'type';
-
-    const KEY_ITEM_ID = 'item_id';
-
-    const KEY_ASSOCIATED_ITEM_ID = 'associated_item_id';
-
-    const KEY_APPLIED_TAXES = 'applied_taxes';
-    /**#@-*/
-
     /**
      * Get type (shipping, product, weee, gift wrapping, etc)
      *
diff --git a/app/code/Magento/Tax/Api/Data/QuoteDetailsInterface.php b/app/code/Magento/Tax/Api/Data/QuoteDetailsInterface.php
index f7d69e1572f86eaecfad263eeeb026ebe8f280bc..b3250a1f7caa09419ffc35169ac0362ffdc2ef2a 100644
--- a/app/code/Magento/Tax/Api/Data/QuoteDetailsInterface.php
+++ b/app/code/Magento/Tax/Api/Data/QuoteDetailsInterface.php
@@ -9,22 +9,6 @@ namespace Magento\Tax\Api\Data;
 
 interface QuoteDetailsInterface extends \Magento\Framework\Api\ExtensibleDataInterface
 {
-    /**#@+
-     * Constants defined for keys of array, makes typos less likely
-     */
-    const KEY_BILLING_ADDRESS = 'billing_address';
-
-    const KEY_SHIPPING_ADDRESS = 'shipping_address';
-
-    const KEY_CUSTOMER_TAX_CLASS_KEY = 'customer_tax_class_key';
-
-    const KEY_ITEMS = 'items';
-
-    const CUSTOMER_TAX_CLASS_ID = 'customer_tax_class_id';
-
-    const KEY_CUSTOMER_ID = 'customer_id';
-    /**#@-*/
-
     /**
      * Get customer billing address
      *
diff --git a/app/code/Magento/Tax/Api/Data/QuoteDetailsItemInterface.php b/app/code/Magento/Tax/Api/Data/QuoteDetailsItemInterface.php
index ea3e57327f3115581853572e3159628b600c31cd..daffa01d4f87651346965eab83a723e7f806df28 100644
--- a/app/code/Magento/Tax/Api/Data/QuoteDetailsItemInterface.php
+++ b/app/code/Magento/Tax/Api/Data/QuoteDetailsItemInterface.php
@@ -7,32 +7,6 @@ namespace Magento\Tax\Api\Data;
 
 interface QuoteDetailsItemInterface extends \Magento\Framework\Api\ExtensibleDataInterface
 {
-    /**#@+
-     * Constants defined for keys of array, makes typos less likely
-     */
-    const KEY_CODE = 'code';
-
-    const KEY_TYPE = 'type';
-
-    const KEY_TAX_CLASS_KEY = 'tax_class_key';
-
-    const KEY_UNIT_PRICE = 'unit_price';
-
-    const KEY_QUANTITY = 'quantity';
-
-    const KEY_TAX_INCLUDED = 'tax_included';
-
-    const KEY_SHORT_DESCRIPTION = 'short_description';
-
-    const KEY_DISCOUNT_AMOUNT = 'discount_amount';
-
-    const KEY_PARENT_CODE = 'parent_code';
-
-    const KEY_ASSOCIATED_ITEM_CODE = 'associated_item_code';
-
-    const KEY_TAX_CLASS_ID = 'tax_class_id';
-    /**#@-*/
-
     /**
      * Get code (sku or shipping code)
      *
@@ -172,7 +146,7 @@ interface QuoteDetailsItemInterface extends \Magento\Framework\Api\ExtensibleDat
     /**
      * Get associated item code if this item is associated with another item, null otherwise
      *
-     * @return mixed|null
+     * @return int|null
      */
     public function getAssociatedItemCode();
 
diff --git a/app/code/Magento/Tax/Api/Data/TaxClassInterface.php b/app/code/Magento/Tax/Api/Data/TaxClassInterface.php
index 80774ef47c646bed3cb54e3813b7968c37536adc..632219c6ad66986690b0655198feceb4f271b0a5 100644
--- a/app/code/Magento/Tax/Api/Data/TaxClassInterface.php
+++ b/app/code/Magento/Tax/Api/Data/TaxClassInterface.php
@@ -9,15 +9,6 @@ namespace Magento\Tax\Api\Data;
 
 interface TaxClassInterface extends \Magento\Framework\Api\ExtensibleDataInterface
 {
-    /**#@+
-     *
-     * Tax class field key.
-     */
-    const KEY_ID = 'class_id';
-    const KEY_NAME = 'class_name';
-    const KEY_TYPE = 'class_type';
-    /**#@-*/
-
     /**
      * Get tax class ID.
      *
diff --git a/app/code/Magento/Tax/Api/Data/TaxClassKeyInterface.php b/app/code/Magento/Tax/Api/Data/TaxClassKeyInterface.php
index 9f0a25a170cbadbd71ad8e1c1e7d7cd6de7d0c27..d6f5d742ad88069a9810c5f815a3a0ac8668f18a 100644
--- a/app/code/Magento/Tax/Api/Data/TaxClassKeyInterface.php
+++ b/app/code/Magento/Tax/Api/Data/TaxClassKeyInterface.php
@@ -10,19 +10,10 @@ use Magento\Framework\Api\ExtensibleDataInterface;
 
 interface TaxClassKeyInterface extends ExtensibleDataInterface
 {
-    /**#@+
-     * Constants defined for keys of array, makes typos less likely
-     */
-    const KEY_TYPE = 'type';
-
-    const KEY_VALUE = 'value';
-    /**#@-*/
-
     /**#@+
      * Constants defined for type of tax class key
      */
-    const TYPE_ID = 'id';
-
+    const TYPE_ID   = 'id';
     const TYPE_NAME = 'name';
     /**#@-*/
 
diff --git a/app/code/Magento/Tax/Api/Data/TaxDetailsInterface.php b/app/code/Magento/Tax/Api/Data/TaxDetailsInterface.php
index f06ba96bc54ca28a6ed4e167d48bbc4e553dcd15..ce0ae30e69e15cf434a0e034be6d913afc9cc245 100644
--- a/app/code/Magento/Tax/Api/Data/TaxDetailsInterface.php
+++ b/app/code/Magento/Tax/Api/Data/TaxDetailsInterface.php
@@ -8,21 +8,6 @@ namespace Magento\Tax\Api\Data;
 
 interface TaxDetailsInterface extends \Magento\Framework\Api\ExtensibleDataInterface
 {
-    /**#@+
-     * Constants defined for keys of array, makes typos less likely
-     */
-    const KEY_SUBTOTAL = 'subtotal';
-
-    const KEY_TAX_AMOUNT = 'tax_amount';
-
-    const KEY_DISCOUNT_TAX_COMPENSATION_AMOUNT = 'discount_tax_compensation_amount';
-
-    const KEY_APPLIED_TAXES = 'applied_taxes';
-
-    const KEY_ITEMS = 'items';
-
-    /**#@-*/
-
     /**
      * Get subtotal
      *
diff --git a/app/code/Magento/Tax/Api/Data/TaxDetailsItemInterface.php b/app/code/Magento/Tax/Api/Data/TaxDetailsItemInterface.php
index fad3229d7076a589363cbabf9f5bcb064984e04f..0550b6614dfc76ef111e29179a96551e476a831b 100644
--- a/app/code/Magento/Tax/Api/Data/TaxDetailsItemInterface.php
+++ b/app/code/Magento/Tax/Api/Data/TaxDetailsItemInterface.php
@@ -8,36 +8,6 @@ namespace Magento\Tax\Api\Data;
 
 interface TaxDetailsItemInterface extends \Magento\Framework\Api\ExtensibleDataInterface
 {
-    /**#@+
-     * Constants defined for keys of array, makes typos less likely
-     */
-    const KEY_CODE = 'code';
-
-    const KEY_TYPE = 'type';
-
-    const KEY_TAX_PERCENT = 'tax_percent';
-
-    const KEY_PRICE = 'price';
-
-    const KEY_PRICE_INCL_TAX = 'price_incl_tax';
-
-    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';
-
-    const KEY_DISCOUNT_AMOUNT = 'discount_amount';
-
-    const KEY_DISCOUNT_TAX_COMPENSATION_AMOUNT = 'discount_tax_compensation_amount';
-
-    const KEY_APPLIED_TAXES = 'applied_taxes';
-
-    const KEY_ASSOCIATED_ITEM_CODE = 'associated_item_code';
-    /**#@-*/
-
     /**
      * Get code (sku or shipping code)
      *
@@ -221,7 +191,7 @@ interface TaxDetailsItemInterface extends \Magento\Framework\Api\ExtensibleDataI
     /**
      * Return associated item code if this item is associated with another item, null otherwise
      *
-     * @return mixed|null
+     * @return int|null
      */
     public function getAssociatedItemCode();
 
diff --git a/app/code/Magento/Tax/Api/Data/TaxRateInterface.php b/app/code/Magento/Tax/Api/Data/TaxRateInterface.php
index 881bb7fa7e013838c558f5514af373dcbe6fceaa..34cf62414862a644f928531ce9fafe996648c32e 100644
--- a/app/code/Magento/Tax/Api/Data/TaxRateInterface.php
+++ b/app/code/Magento/Tax/Api/Data/TaxRateInterface.php
@@ -9,22 +9,6 @@ namespace Magento\Tax\Api\Data;
 
 interface TaxRateInterface extends \Magento\Framework\Api\ExtensibleDataInterface
 {
-    /**#@+
-     * Constants defined for keys of array, makes typos less likely
-     */
-    const KEY_ID = 'id';
-    const KEY_COUNTRY_ID = 'tax_country_id';
-    const KEY_REGION_ID = 'tax_region_id';
-    const KEY_REGION_NAME = 'region_name';
-    const KEY_POSTCODE = 'tax_postcode';
-    const KEY_ZIP_IS_RANGE = 'zip_is_range';
-    const KEY_ZIP_RANGE_FROM = 'zip_from';
-    const KEY_ZIP_RANGE_TO = 'zip_to';
-    const KEY_PERCENTAGE_RATE = 'rate';
-    const KEY_CODE = 'code';
-    const KEY_TITLES = 'titles';
-    /**#@-*/
-
     /**
      * Get id
      *
diff --git a/app/code/Magento/Tax/Api/Data/TaxRateTitleInterface.php b/app/code/Magento/Tax/Api/Data/TaxRateTitleInterface.php
index 8d3991070b9565d9527c7c036aca9e45864d15f4..7dcfd2413759636b184d8e6cac0a789d6ecfacee 100644
--- a/app/code/Magento/Tax/Api/Data/TaxRateTitleInterface.php
+++ b/app/code/Magento/Tax/Api/Data/TaxRateTitleInterface.php
@@ -9,15 +9,6 @@ namespace Magento\Tax\Api\Data;
 
 interface TaxRateTitleInterface extends \Magento\Framework\Api\ExtensibleDataInterface
 {
-    /**#@+
-     *
-     * Tax rate field key.
-     */
-    const KEY_STORE_ID = 'store_id';
-
-    const KEY_VALUE_ID = 'value';
-    /**#@-*/
-
     /**
      * Get store id
      *
diff --git a/app/code/Magento/Tax/Block/Adminhtml/Rate/Form.php b/app/code/Magento/Tax/Block/Adminhtml/Rate/Form.php
index 08a7803aa85474510a9135d22b7819dd4122c03c..84e32da4ae97439c3fbc7d8e8fccefc364b9f6cc 100644
--- a/app/code/Magento/Tax/Block/Adminhtml/Rate/Form.php
+++ b/app/code/Magento/Tax/Block/Adminhtml/Rate/Form.php
@@ -65,6 +65,11 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic
      */
     protected $_taxRateCollection;
 
+    /**
+     * @var \Magento\Tax\Model\Calculation\Rate\Converter
+     */
+    protected $_taxRateConverter;
+
     /**
      * @param \Magento\Backend\Block\Template\Context $context
      * @param \Magento\Framework\Registry $registry
@@ -75,6 +80,7 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic
      * @param \Magento\Tax\Helper\Data $taxData
      * @param \Magento\Tax\Api\TaxRateRepositoryInterface $taxRateRepository
      * @param \Magento\Tax\Model\TaxRateCollection $taxRateCollection
+     * @param \Magento\Tax\Model\Calculation\Rate\Converter $taxRateConverter
      * @param array $data
      * @SuppressWarnings(PHPMD.ExcessiveParameterList)
      */
@@ -88,6 +94,7 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic
         \Magento\Tax\Helper\Data $taxData,
         \Magento\Tax\Api\TaxRateRepositoryInterface $taxRateRepository,
         \Magento\Tax\Model\TaxRateCollection $taxRateCollection,
+        \Magento\Tax\Model\Calculation\Rate\Converter $taxRateConverter,
         array $data = []
     ) {
         $this->_regionFactory = $regionFactory;
@@ -96,6 +103,7 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic
         $this->_taxData = $taxData;
         $this->_taxRateRepository = $taxRateRepository;
         $this->_taxRateCollection = $taxRateCollection;
+        $this->_taxRateConverter = $taxRateConverter;
         parent::__construct($context, $registry, $formFactory, $data);
     }
 
@@ -127,7 +135,7 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic
         }
 
         $sessionFormValues = (array)$this->_coreRegistry->registry(RegistryConstants::CURRENT_TAX_RATE_FORM_DATA);
-        $formData = isset($taxRateDataObject) ? $this->extractTaxRateData($taxRateDataObject) : [];
+        $formData = isset($taxRateDataObject) ? $this->_taxRateConverter->createArrayFromServiceObject($taxRateDataObject) : [];
         $formData = array_merge($formData, $sessionFormValues);
 
         if (isset($formData['zip_is_range']) && $formData['zip_is_range'] && !isset($formData['tax_postcode'])) {
@@ -286,65 +294,4 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic
 
         return parent::_prepareForm();
     }
-
-    /**
-     * Get Tax Rates Collection
-     *
-     * @return mixed
-     */
-    public function getRateCollection()
-    {
-        if ($this->getData('rate_collection') == null) {
-            $items = $this->_taxRateCollection->getItems();
-            $rates = [];
-            foreach ($items as $rate) {
-                $rateData = $rate->getData();
-                if (isset($rateData['titles'])) {
-                    foreach ($rateData['titles'] as $storeId => $value) {
-                        $rateData['title[' . $storeId . ']'] = $value;
-                    }
-                }
-                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\Api\Data\TaxRateInterface $taxRate
-     * @return array
-     */
-    protected function extractTaxRateData($taxRate)
-    {
-        $formData = [
-            'tax_calculation_rate_id' => $taxRate->getId(),
-            'tax_country_id' => $taxRate->getTaxCountryId(),
-            'tax_region_id' => $taxRate->getTaxRegionId(),
-            'tax_postcode' => $taxRate->getTaxPostcode(),
-            'code' => $taxRate->getCode(),
-            'rate' => $taxRate->getRate(),
-            'zip_is_range' => false,
-        ];
-
-        if ($taxRate->getZipFrom() && $taxRate->getZipTo()) {
-            $formData['zip_is_range'] = true;
-            $formData['zip_from'] = $taxRate->getZipFrom();
-            $formData['zip_to'] = $taxRate->getZipTo();
-        }
-
-        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/Rule/Edit/Form.php b/app/code/Magento/Tax/Block/Adminhtml/Rule/Edit/Form.php
index 0d2b16bee6f0dff1154bba3c025f3a0f9b0b541a..fb434ca6dd3092395c7df36a0f4cd1dfa0fdd222 100644
--- a/app/code/Magento/Tax/Block/Adminhtml/Rule/Edit/Form.php
+++ b/app/code/Magento/Tax/Block/Adminhtml/Rule/Edit/Form.php
@@ -297,6 +297,16 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic
         return $this->getUrl('tax/rate/ajaxSave/');
     }
 
+    /**
+     * Retrieve Tax Rate load URL
+     *
+     * @return string
+     */
+    public function getTaxRateLoadUrl()
+    {
+        return $this->getUrl('tax/rate/ajaxLoad/');
+    }
+
     /**
      * Extract tax rule data in a format which is
      *
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Rate.php b/app/code/Magento/Tax/Controller/Adminhtml/Rate.php
index 7fce6e7e37d8f1d73045a7274b67efdd0e972d9a..e25e0a19a87a2752204de23adc90e6106e6c559e 100644
--- a/app/code/Magento/Tax/Controller/Adminhtml/Rate.php
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Rate.php
@@ -6,6 +6,8 @@
 
 namespace Magento\Tax\Controller\Adminhtml;
 
+use Magento\Framework\Controller\ResultFactory;
+
 /**
  * Adminhtml tax rate controller
  *
@@ -19,38 +21,30 @@ class Rate extends \Magento\Backend\App\Action
     protected $_coreRegistry;
 
     /**
-     * @var \Magento\Tax\Api\TaxRateRepositoryInterface
+     * @var \Magento\Tax\Model\Calculation\Rate\Converter
      */
-    protected $_taxRateRepository;
+    protected $_taxRateConverter;
 
     /**
-     * @var \Magento\Tax\Api\Data\TaxRateInterfaceFactory
-     */
-    protected $_taxRateDataObjectFactory;
-
-    /**
-     * @var \Magento\Tax\Api\Data\TaxRateTitleInterfaceFactory
+     * @var \Magento\Tax\Api\TaxRateRepositoryInterface
      */
-    protected $_taxRateTitleDataObjectFactory;
+    protected $_taxRateRepository;
 
     /**
      * @param \Magento\Backend\App\Action\Context $context
      * @param \Magento\Framework\Registry $coreRegistry
+     * @param \Magento\Tax\Model\Calculation\Rate\Converter $taxRateConverter
      * @param \Magento\Tax\Api\TaxRateRepositoryInterface $taxRateRepository
-     * @param \Magento\Tax\Api\Data\TaxRateInterfaceFactory $taxRateDataObjectFactory
-     * @param \Magento\Tax\Api\Data\TaxRateTitleInterfaceFactory $taxRateTitleDataObjectFactory
      */
     public function __construct(
         \Magento\Backend\App\Action\Context $context,
         \Magento\Framework\Registry $coreRegistry,
-        \Magento\Tax\Api\TaxRateRepositoryInterface $taxRateRepository,
-        \Magento\Tax\Api\Data\TaxRateInterfaceFactory $taxRateDataObjectFactory,
-        \Magento\Tax\Api\Data\TaxRateTitleInterfaceFactory $taxRateTitleDataObjectFactory
+        \Magento\Tax\Model\Calculation\Rate\Converter $taxRateConverter,
+        \Magento\Tax\Api\TaxRateRepositoryInterface $taxRateRepository
     ) {
         $this->_coreRegistry = $coreRegistry;
+        $this->_taxRateConverter = $taxRateConverter;
         $this->_taxRateRepository = $taxRateRepository;
-        $this->_taxRateDataObjectFactory = $taxRateDataObjectFactory;
-        $this->_taxRateTitleDataObjectFactory = $taxRateTitleDataObjectFactory;
         parent::__construct($context);
     }
 
@@ -76,21 +70,15 @@ class Rate extends \Magento\Backend\App\Action
     /**
      * Initialize action
      *
-     * @return \Magento\Backend\App\Action
+     * @return \Magento\Backend\Model\View\Result\Page
      */
-    protected function _initAction()
+    protected function initResultPage()
     {
-        $this->_view->loadLayout();
-        $this->_setActiveMenu(
-            'Magento_Tax::sales_tax_rates'
-        )->_addBreadcrumb(
-            __('Sales'),
-            __('Sales')
-        )->_addBreadcrumb(
-            __('Tax'),
-            __('Tax')
-        );
-        return $this;
+        $resultPage = $this->resultFactory->create(ResultFactory::TYPE_PAGE);
+        $resultPage->setActiveMenu('Magento_Tax::sales_tax_rates')
+            ->addBreadcrumb(__('Sales'), __('Sales'))
+            ->addBreadcrumb(__('Tax'), __('Tax'));
+        return $resultPage;
     }
 
     /**
@@ -100,50 +88,4 @@ class Rate extends \Magento\Backend\App\Action
     {
         return $this->_authorization->isAllowed('Magento_Tax::manage_tax');
     }
-
-    /**
-     * Populate a tax rate data object
-     *
-     * @param array $formData
-     * @return \Magento\Tax\Api\Data\TaxRateInterface
-     */
-    protected function populateTaxRateData($formData)
-    {
-        $taxRate = $this->_taxRateDataObjectFactory->create();
-        $taxRate->setId($this->extractFormData($formData, 'tax_calculation_rate_id'))
-            ->setTaxCountryId($this->extractFormData($formData, 'tax_country_id'))
-            ->setTaxRegionId($this->extractFormData($formData, 'tax_region_id'))
-            ->setTaxPostcode($this->extractFormData($formData, 'tax_postcode'))
-            ->setCode($this->extractFormData($formData, 'code'))
-            ->setRate($this->extractFormData($formData, 'rate'));
-        if (isset($formData['zip_is_range']) && $formData['zip_is_range']) {
-            $taxRate->setZipFrom($this->extractFormData($formData, 'zip_from'))
-                ->setZipTo($this->extractFormData($formData, 'zip_to'))->setZipIsRange(1);
-        }
-
-        if (isset($formData['title'])) {
-            $titles = [];
-            foreach ($formData['title'] as $storeId => $value) {
-                $titles[] = $this->_taxRateTitleDataObjectFactory->create()->setStoreId($storeId)->setValue($value);
-            }
-            $taxRate->setTitles($titles);
-        }
-
-        return $taxRate;
-    }
-
-    /**
-     * 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
index 6b90cbf270fdfed7a610a436104a2ef5d1e5c8e6..2fe8a5b1572e38dcf05676653a2fd8d633ca38ed 100644
--- a/app/code/Magento/Tax/Controller/Adminhtml/Rate/Add.php
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Rate/Add.php
@@ -13,7 +13,7 @@ class Add extends \Magento\Tax\Controller\Adminhtml\Rate
     /**
      * Show Add Form
      *
-     * @return void
+     * @return \Magento\Backend\Model\View\Result\Page
      */
     public function execute()
     {
@@ -22,26 +22,18 @@ class Add extends \Magento\Tax\Controller\Adminhtml\Rate
             $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->getPage()->getConfig()->getTitle()->prepend(__('Tax Zones and Rates'));
-        $this->_view->getPage()->getConfig()->getTitle()->prepend(__('New Tax Rate'));
-        $this->_view->renderLayout();
+        $resultPage = $this->initResultPage();
+        $layout = $resultPage->getLayout();
+        $toolbarSaveBlock = $layout->createBlock('Magento\Tax\Block\Adminhtml\Rate\Toolbar\Save')
+            ->assign('header', __('Add New Tax Rate'))
+            ->assign('form', $layout->createBlock('Magento\Tax\Block\Adminhtml\Rate\Form', 'tax_rate_form'));
+
+        $resultPage->addBreadcrumb(__('Manage Tax Rates'), __('Manage Tax Rates'), $this->getUrl('tax/rate'))
+            ->addBreadcrumb(__('New Tax Rate'), __('New Tax Rate'))
+            ->addContent($toolbarSaveBlock);
+
+        $resultPage->getConfig()->getTitle()->prepend(__('Tax Zones and Rates'));
+        $resultPage->getConfig()->getTitle()->prepend(__('New Tax Rate'));
+        return $resultPage;
     }
 }
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Rate/AjaxDelete.php b/app/code/Magento/Tax/Controller/Adminhtml/Rate/AjaxDelete.php
index fd09d178fcd755d362a1e831257dfdba6e84e182..7d5e8285ebbe6792357da00fbf158182051e69fc 100644
--- a/app/code/Magento/Tax/Controller/Adminhtml/Rate/AjaxDelete.php
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Rate/AjaxDelete.php
@@ -6,36 +6,33 @@
  */
 namespace Magento\Tax\Controller\Adminhtml\Rate;
 
+use Magento\Framework\Controller\ResultFactory;
+
 class AjaxDelete extends \Magento\Tax\Controller\Adminhtml\Rate
 {
     /**
      * Delete Tax Rate via AJAX
      *
-     * @return void
+     * @return \Magento\Framework\Controller\Result\Json
      */
     public function execute()
     {
         $rateId = (int)$this->getRequest()->getParam('tax_calculation_rate_id');
         try {
             $this->_taxRateRepository->deleteById($rateId);
-            $responseContent = $this->_objectManager->get(
-                'Magento\Framework\Json\Helper\Data'
-            )->jsonEncode(
-                ['success' => true, 'error_message' => '']
-            );
+            $responseContent = ['success' => true, 'error_message' => ''];
         } catch (\Magento\Framework\Exception\LocalizedException $e) {
-            $responseContent = $this->_objectManager->get(
-                'Magento\Framework\Json\Helper\Data'
-            )->jsonEncode(
-                ['success' => false, 'error_message' => $e->getMessage()]
-            );
+            $responseContent = ['success' => false, 'error_message' => $e->getMessage()];
         } catch (\Exception $e) {
-            $responseContent = $this->_objectManager->get(
-                'Magento\Framework\Json\Helper\Data'
-            )->jsonEncode(
-                ['success' => false, 'error_message' => __('An error occurred while deleting this tax rate.')]
-            );
+            $responseContent = [
+                'success' => false,
+                'error_message' => __('An error occurred while deleting this tax rate.')
+            ];
         }
-        $this->getResponse()->representJson($responseContent);
+
+        /** @var \Magento\Framework\Controller\Result\Json $resultJson */
+        $resultJson = $this->resultFactory->create(ResultFactory::TYPE_JSON);
+        $resultJson->setData($responseContent);
+        return $resultJson;
     }
 }
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Rate/AjaxLoad.php b/app/code/Magento/Tax/Controller/Adminhtml/Rate/AjaxLoad.php
new file mode 100755
index 0000000000000000000000000000000000000000..673ea280bab25ed504a240bfcddb25d1e2cbadfe
--- /dev/null
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Rate/AjaxLoad.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Tax\Controller\Adminhtml\Rate;
+
+use Magento\Framework\Exception\NoSuchEntityException;
+use Magento\Framework\Controller\ResultFactory;
+
+class AjaxLoad extends \Magento\Tax\Controller\Adminhtml\Rate
+{
+    /**
+     * Json needed for the Ajax Edit Form
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $rateId = (int)$this->getRequest()->getParam('id');
+        try {
+            /* @var \Magento\Tax\Api\Data\TaxRateInterface */
+            $taxRateDataObject = $this->_taxRateRepository->get($rateId);
+            /* @var array */
+            $resultArray= $this->_taxRateConverter->createArrayFromServiceObject($taxRateDataObject, true);
+
+            $responseContent = [
+                'success' => true,
+                'error_message' => '',
+                'result'=>$resultArray,
+                ];
+        } catch (NoSuchEntityException $e) {
+            $responseContent = [
+                'success' => false,
+                'error_message' => $e->getMessage(),
+            ];
+        } catch (\Exception $e) {
+            $responseContent = [
+                'success' => false,
+                'error_message' => __('An error occurred while loading this tax rate.'),
+            ];
+        }
+
+        /** @var \Magento\Framework\Controller\Result\Json $resultJson */
+        $resultJson = $this->resultFactory->create(ResultFactory::TYPE_JSON);
+        $resultJson->setData($responseContent);
+        return $resultJson;
+    }
+}
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Rate/AjaxSave.php b/app/code/Magento/Tax/Controller/Adminhtml/Rate/AjaxSave.php
index e78dc538074af4c59adb3ba4f02abe273059b2da..32ba0758fbd58b291e036ec525b06c6c3c3242c4 100644
--- a/app/code/Magento/Tax/Controller/Adminhtml/Rate/AjaxSave.php
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Rate/AjaxSave.php
@@ -6,54 +6,47 @@
  */
 namespace Magento\Tax\Controller\Adminhtml\Rate;
 
+use Magento\Framework\Controller\ResultFactory;
+
 class AjaxSave extends \Magento\Tax\Controller\Adminhtml\Rate
 {
     /**
      * Save Tax Rate via AJAX
      *
-     * @return void
+     * @return \Magento\Framework\Controller\Result\Json
      */
     public function execute()
     {
-        $responseContent = '';
         try {
             $rateData = $this->_processRateData($this->getRequest()->getPostValue());
             /** @var \Magento\Tax\Api\Data\TaxRateInterface  $taxRate */
-            $taxRate = $this->populateTaxRateData($rateData);
+            $taxRate = $this->_taxRateConverter->populateTaxRateData($rateData);
             $this->_taxRateRepository->save($taxRate);
-            $responseContent = $this->_objectManager->get(
-                'Magento\Framework\Json\Helper\Data'
-            )->jsonEncode(
-                [
-                    'success' => true,
-                    'error_message' => '',
-                    'tax_calculation_rate_id' => $taxRate->getId(),
-                    'code' => $taxRate->getCode(),
-                ]
-            );
+            $responseContent = [
+                'success' => true,
+                'error_message' => '',
+                'tax_calculation_rate_id' => $taxRate->getId(),
+                'code' => $taxRate->getCode(),
+            ];
         } catch (\Magento\Framework\Exception\LocalizedException $e) {
-            $responseContent = $this->_objectManager->get(
-                'Magento\Framework\Json\Helper\Data'
-            )->jsonEncode(
-                [
-                    'success' => false,
-                    'error_message' => $e->getMessage(),
-                    'tax_calculation_rate_id' => '',
-                    'code' => '',
-                ]
-            );
+            $responseContent = [
+                'success' => false,
+                'error_message' => $e->getMessage(),
+                'tax_calculation_rate_id' => '',
+                'code' => '',
+            ];
         } catch (\Exception $e) {
-            $responseContent = $this->_objectManager->get(
-                'Magento\Framework\Json\Helper\Data'
-            )->jsonEncode(
-                [
-                    'success' => false,
-                    'error_message' => __('Something went wrong saving this rate.'),
-                    'tax_calculation_rate_id' => '',
-                    'code' => '',
-                ]
-            );
+            $responseContent = [
+                'success' => false,
+                'error_message' => __('Something went wrong saving this rate.'),
+                'tax_calculation_rate_id' => '',
+                'code' => '',
+            ];
         }
-        $this->getResponse()->representJson($responseContent);
+
+        /** @var \Magento\Framework\Controller\Result\Json $resultJson */
+        $resultJson = $this->resultFactory->create(ResultFactory::TYPE_JSON);
+        $resultJson->setData($responseContent);
+        return $resultJson;
     }
 }
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Rate/Delete.php b/app/code/Magento/Tax/Controller/Adminhtml/Rate/Delete.php
index bcf14907b4eff3410da0d7a637f2fb7554a00f57..9ee9be000e87c91ed034f8158df818bd74fa1897 100755
--- a/app/code/Magento/Tax/Controller/Adminhtml/Rate/Delete.php
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Rate/Delete.php
@@ -7,6 +7,7 @@
 namespace Magento\Tax\Controller\Adminhtml\Rate;
 
 use Magento\Framework\Exception\NoSuchEntityException;
+use Magento\Framework\Controller\ResultFactory;
 
 class Delete extends \Magento\Tax\Controller\Adminhtml\Rate
 {
@@ -18,20 +19,19 @@ class Delete extends \Magento\Tax\Controller\Adminhtml\Rate
     public function execute()
     {
         if ($rateId = $this->getRequest()->getParam('rate')) {
+            /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
+            $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
             try {
                 $this->_taxRateRepository->deleteById($rateId);
 
                 $this->messageManager->addSuccess(__('The tax rate has been deleted.'));
-                $this->getResponse()->setRedirect($this->getUrl("*/*/"));
-                return;
+                return $resultRedirect->setPath("*/*/");
             } catch (NoSuchEntityException $e) {
                 $this->messageManager->addError(
                     __('Something went wrong deleting this rate because of an incorrect rate ID.')
                 );
-                $this->getResponse()->setRedirect($this->getUrl('tax/*/'));
-                return;
+                return $resultRedirect->setPath("tax/*/");
             }
-            return $this->getDefaultResult();
         }
     }
 
@@ -42,11 +42,11 @@ class Delete extends \Magento\Tax\Controller\Adminhtml\Rate
      */
     public function getDefaultResult()
     {
-        $resultRedirect = $this->resultRedirectFactory->create();
+        $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
         if ($this->getRequest()->getServer('HTTP_REFERER')) {
             $resultRedirect->setRefererUrl();
         } else {
-            $resultRedirect->setUrl($this->getUrl("*/*/"));
+            $resultRedirect->setPath("*/*/");
         }
         return $resultRedirect;
     }
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Rate/Edit.php b/app/code/Magento/Tax/Controller/Adminhtml/Rate/Edit.php
index 27d8003a4b22b760a015dd7aaaf1054217f3fd2c..e13ae2293e6c22bb6ec6e3493b0d6798864decd9 100644
--- a/app/code/Magento/Tax/Controller/Adminhtml/Rate/Edit.php
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Rate/Edit.php
@@ -8,13 +8,14 @@ namespace Magento\Tax\Controller\Adminhtml\Rate;
 
 use Magento\Framework\Exception\NoSuchEntityException;
 use Magento\Tax\Controller\RegistryConstants;
+use Magento\Framework\Controller\ResultFactory;
 
 class Edit extends \Magento\Tax\Controller\Adminhtml\Rate
 {
     /**
      * Show Edit Form
      *
-     * @return void
+     * @return \Magento\Backend\Model\View\Result\Page|\Magento\Backend\Model\View\Result\Redirect
      */
     public function execute()
     {
@@ -23,35 +24,27 @@ class Edit extends \Magento\Tax\Controller\Adminhtml\Rate
         try {
             $taxRateDataObject = $this->_taxRateRepository->get($rateId);
         } catch (NoSuchEntityException $e) {
-            $this->getResponse()->setRedirect($this->getUrl("*/*/"));
-            return;
+            /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
+            $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
+            return $resultRedirect->setPath("*/*/");
         }
 
-        $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(
+        $resultPage = $this->initResultPage();
+        $layout = $resultPage->getLayout();
+
+        $toolbarSaveBlock = $layout->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->getPage()->getConfig()->getTitle()->prepend(__('Tax Zones and Rates'));
-        $this->_view->getPage()->getConfig()->getTitle()->prepend(sprintf("%s", $taxRateDataObject->getCode()));
-        $this->_view->renderLayout();
+                $layout->createBlock('Magento\Tax\Block\Adminhtml\Rate\Form', 'tax_rate_form')->setShowLegend(true)
+            );
+
+        $resultPage->addBreadcrumb(__('Manage Tax Rates'), __('Manage Tax Rates'), $this->getUrl('tax/rate'))
+            ->addBreadcrumb(__('Edit Tax Rate'), __('Edit Tax Rate'))
+            ->addContent($toolbarSaveBlock);
+
+        $resultPage->getConfig()->getTitle()->prepend(__('Tax Zones and Rates'));
+        $resultPage->getConfig()->getTitle()->prepend(sprintf("%s", $taxRateDataObject->getCode()));
+        return $resultPage;
     }
 }
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Rate/Index.php b/app/code/Magento/Tax/Controller/Adminhtml/Rate/Index.php
index 17e1349e4f05aa59274a4c841e3c504c79d5dcd0..d38d6ddd9af1407a69f268cb085eafcf9d84ad77 100644
--- a/app/code/Magento/Tax/Controller/Adminhtml/Rate/Index.php
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Rate/Index.php
@@ -11,12 +11,13 @@ class Index extends \Magento\Tax\Controller\Adminhtml\Rate
     /**
      * Show Main Grid
      *
-     * @return void
+     * @return \Magento\Backend\Model\View\Result\Page
      */
     public function execute()
     {
-        $this->_initAction()->_addBreadcrumb(__('Manage Tax Rates'), __('Manage Tax Rates'));
-        $this->_view->getPage()->getConfig()->getTitle()->prepend(__('Tax Zones and Rates'));
-        $this->_view->renderLayout();
+        $resultPage = $this->initResultPage();
+        $resultPage->addBreadcrumb(__('Manage Tax Rates'), __('Manage Tax Rates'));
+        $resultPage->getConfig()->getTitle()->prepend(__('Tax Zones and Rates'));
+        return $resultPage;
     }
 }
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Rate/Save.php b/app/code/Magento/Tax/Controller/Adminhtml/Rate/Save.php
index 8a7e1cba1c0c49b6c3c86117e2101c217b023258..36dbcc284eabb831c206477b1da004c886686429 100644
--- a/app/code/Magento/Tax/Controller/Adminhtml/Rate/Save.php
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Rate/Save.php
@@ -7,16 +7,19 @@
 namespace Magento\Tax\Controller\Adminhtml\Rate;
 
 use Magento\Framework\Exception\NoSuchEntityException;
+use Magento\Framework\Controller\ResultFactory;
 
 class Save extends \Magento\Tax\Controller\Adminhtml\Rate
 {
     /**
      * Save Rate and Data
      *
-     * @return void
+     * @return \Magento\Backend\Model\View\Result\Redirect
      */
     public function execute()
     {
+        /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
+        $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
         $ratePost = $this->getRequest()->getPostValue();
         if ($ratePost) {
             $rateId = $this->getRequest()->getParam('tax_calculation_rate_id');
@@ -29,22 +32,19 @@ class Save extends \Magento\Tax\Controller\Adminhtml\Rate
             }
 
             try {
-                $taxData = $this->populateTaxRateData($ratePost);
+                $taxData = $this->_taxRateConverter->populateTaxRateData($ratePost);
                 $this->_taxRateRepository->save($taxData);
 
                 $this->messageManager->addSuccess(__('The tax rate has been saved.'));
-                $this->getResponse()->setRedirect($this->getUrl("*/*/"));
-                return;
+                return $resultRedirect->setPath('*/*/');
             } 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;
+            return $resultRedirect->setUrl($this->_redirect->getRedirectUrl($this->getUrl('*')));
         }
-        $this->getResponse()->setRedirect($this->getUrl('tax/rate'));
+        return $resultRedirect->setPath('tax/rate');
     }
 }
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Rule.php b/app/code/Magento/Tax/Controller/Adminhtml/Rule.php
index 577babe2ae7a01a64ba730f0d44e344e48a02555..f4a88b5f036653086711718297624377d27bfd53 100644
--- a/app/code/Magento/Tax/Controller/Adminhtml/Rule.php
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Rule.php
@@ -12,6 +12,7 @@
 namespace Magento\Tax\Controller\Adminhtml;
 
 use Magento\Backend\App\Action;
+use Magento\Framework\Controller\ResultFactory;
 
 class Rule extends \Magento\Backend\App\Action
 {
@@ -49,21 +50,15 @@ class Rule extends \Magento\Backend\App\Action
     /**
      * Initialize action
      *
-     * @return $this
+     * @return \Magento\Backend\Model\View\Result\Page
      */
-    protected function _initAction()
+    protected function initResultPage()
     {
-        $this->_view->loadLayout();
-        $this->_setActiveMenu(
-            'Magento_Tax::sales_tax_rules'
-        )->_addBreadcrumb(
-            __('Tax'),
-            __('Tax')
-        )->_addBreadcrumb(
-            __('Tax Rules'),
-            __('Tax Rules')
-        );
-        return $this;
+        $resultPage = $this->resultFactory->create(ResultFactory::TYPE_PAGE);
+        $resultPage->setActiveMenu('Magento_Tax::sales_tax_rules')
+            ->addBreadcrumb(__('Tax'), __('Tax'))
+            ->addBreadcrumb(__('Tax Rules'), __('Tax Rules'));
+        return $resultPage;
     }
 
     /**
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Rule/Delete.php b/app/code/Magento/Tax/Controller/Adminhtml/Rule/Delete.php
index 4fff21c62f6352e4c1c4ac14b9504864755317bf..c0a26cbcecf15cefa89d893a60744dc653cc6c05 100755
--- a/app/code/Magento/Tax/Controller/Adminhtml/Rule/Delete.php
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Rule/Delete.php
@@ -6,25 +6,28 @@
  */
 namespace Magento\Tax\Controller\Adminhtml\Rule;
 
+use Magento\Framework\Controller\ResultFactory;
+
 class Delete extends \Magento\Tax\Controller\Adminhtml\Rule
 {
     /**
-     * @return \Magento\Backend\Model\View\Result\Redirect|void
+     *
+     * @throws \Exception
+     * @return \Magento\Backend\Model\View\Result\Redirect
      */
     public function execute()
     {
+        /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
+        $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
         $ruleId = (int)$this->getRequest()->getParam('rule');
         try {
             $this->ruleService->deleteById($ruleId);
             $this->messageManager->addSuccess(__('The tax rule has been deleted.'));
-            $this->_redirect('tax/*/');
-            return;
+            return $resultRedirect->setPath('tax/*/');
         } catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
             $this->messageManager->addError(__('This rule no longer exists.'));
-            $this->_redirect('tax/*/');
-            return;
+            return $resultRedirect->setPath('tax/*/');
         }
-        return $this->getDefaultResult();
     }
 
     /**
@@ -34,7 +37,8 @@ class Delete extends \Magento\Tax\Controller\Adminhtml\Rule
      */
     public function getDefaultResult()
     {
-        $resultRedirect = $this->resultRedirectFactory->create();
+        /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
+        $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
         return $resultRedirect->setUrl($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
index 86663f854fd90536784575fc2dff3b1fd501de68..ebbabcf833aed5f6eea84d58dfd91ffa35514a08 100644
--- a/app/code/Magento/Tax/Controller/Adminhtml/Rule/Edit.php
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Rule/Edit.php
@@ -6,11 +6,12 @@
  */
 namespace Magento\Tax\Controller\Adminhtml\Rule;
 
+use Magento\Framework\Controller\ResultFactory;
 
 class Edit extends \Magento\Tax\Controller\Adminhtml\Rule
 {
     /**
-     * @return void
+     * @return \Magento\Backend\Model\View\Result\Page|\Magento\Backend\Model\View\Result\Redirect
      */
     public function execute()
     {
@@ -25,8 +26,9 @@ class Edit extends \Magento\Tax\Controller\Adminhtml\Rule
             } catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
                 $backendSession->unsRuleData();
                 $this->messageManager->addError(__('This rule no longer exists.'));
-                $this->_redirect('tax/*/');
-                return;
+                /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
+                $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
+                return $resultRedirect->setPath('tax/*/');
             }
         } else {
             $pageTitle = __('New Tax Rule');
@@ -36,9 +38,10 @@ class Edit extends \Magento\Tax\Controller\Adminhtml\Rule
             $this->_coreRegistry->register('tax_rule_form_data', $data);
         }
         $breadcrumb = $taxRuleId ? __('Edit Rule') : __('New Rule');
-        $this->_initAction()->_addBreadcrumb($breadcrumb, $breadcrumb);
-        $this->_view->getPage()->getConfig()->getTitle()->prepend(__('Tax Rules'));
-        $this->_view->getPage()->getConfig()->getTitle()->prepend($pageTitle);
-        $this->_view->renderLayout();
+        $resultPage = $this->initResultPage();
+        $resultPage->addBreadcrumb($breadcrumb, $breadcrumb);
+        $resultPage->getConfig()->getTitle()->prepend(__('Tax Rules'));
+        $resultPage->getConfig()->getTitle()->prepend($pageTitle);
+        return $resultPage;
     }
 }
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Rule/Index.php b/app/code/Magento/Tax/Controller/Adminhtml/Rule/Index.php
index f64f5a2db19b11335a0f514c2c083a39367ac9a2..b3ea7586cf90bd507139b000ea52e8f3ac414735 100644
--- a/app/code/Magento/Tax/Controller/Adminhtml/Rule/Index.php
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Rule/Index.php
@@ -10,12 +10,12 @@ namespace Magento\Tax\Controller\Adminhtml\Rule;
 class Index extends \Magento\Tax\Controller\Adminhtml\Rule
 {
     /**
-     * @return $this
+     * @return \Magento\Backend\Model\View\Result\Page
      */
     public function execute()
     {
-        $this->_initAction();
-        $this->_view->getPage()->getConfig()->getTitle()->prepend(__('Tax Rules'));
-        $this->_view->renderLayout();
+        $resultPage = $this->initResultPage();
+        $resultPage->getConfig()->getTitle()->prepend(__('Tax Rules'));
+        return $resultPage;
     }
 }
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Rule/NewAction.php b/app/code/Magento/Tax/Controller/Adminhtml/Rule/NewAction.php
index 94b15bc53b7eed8d741b5b202efd0e8167ad463f..79f4fa7d752e72dafcb21e342d5aa95dd3af57fd 100644
--- a/app/code/Magento/Tax/Controller/Adminhtml/Rule/NewAction.php
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Rule/NewAction.php
@@ -6,14 +6,17 @@
  */
 namespace Magento\Tax\Controller\Adminhtml\Rule;
 
+use Magento\Framework\Controller\ResultFactory;
 
 class NewAction extends \Magento\Tax\Controller\Adminhtml\Rule
 {
     /**
-     * @return void
+     * @return \Magento\Backend\Model\View\Result\Forward
      */
     public function execute()
     {
-        $this->_forward('edit');
+        /** @var \Magento\Backend\Model\View\Result\Forward $resultForward */
+        $resultForward = $this->resultFactory->create(ResultFactory::TYPE_FORWARD);
+        return $resultForward->forward('edit');
     }
 }
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Rule/Save.php b/app/code/Magento/Tax/Controller/Adminhtml/Rule/Save.php
index 155c2bb0b76e3cad9efc59090547a3098cba684e..fdcaa2f15c127540fc9f07713b2ec3dc17da8a1d 100644
--- a/app/code/Magento/Tax/Controller/Adminhtml/Rule/Save.php
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Rule/Save.php
@@ -6,14 +6,17 @@
  */
 namespace Magento\Tax\Controller\Adminhtml\Rule;
 
+use Magento\Framework\Controller\ResultFactory;
 
 class Save extends \Magento\Tax\Controller\Adminhtml\Rule
 {
     /**
-     * @return void
+     * @return \Magento\Backend\Model\View\Result\Redirect
      */
     public function execute()
     {
+        /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
+        $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
         $postData = $this->getRequest()->getPostValue();
         if ($postData) {
             $postData['calculate_subtotal'] = $this->getRequest()->getParam('calculate_subtotal', 0);
@@ -24,12 +27,9 @@ class Save extends \Magento\Tax\Controller\Adminhtml\Rule
                 $this->messageManager->addSuccess(__('The tax rule has been saved.'));
 
                 if ($this->getRequest()->getParam('back')) {
-                    $this->_redirect('tax/*/edit', ['rule' => $taxRule->getId()]);
-                    return;
+                    return $resultRedirect->setPath('tax/*/edit', ['rule' => $taxRule->getId()]);
                 }
-
-                $this->_redirect('tax/*/');
-                return;
+                return $resultRedirect->setPath('tax/*/');
             } catch (\Magento\Framework\Exception\LocalizedException $e) {
                 $this->messageManager->addError($e->getMessage());
             } catch (\Exception $e) {
@@ -37,9 +37,8 @@ class Save extends \Magento\Tax\Controller\Adminhtml\Rule
             }
 
             $this->_objectManager->get('Magento\Backend\Model\Session')->setRuleData($postData);
-            $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($this->getUrl('*')));
-            return;
+            return $resultRedirect->setUrl($this->_redirect->getRedirectUrl($this->getUrl('*')));
         }
-        $this->getResponse()->setRedirect($this->getUrl('tax/rule'));
+        return $resultRedirect->setPath('tax/rule');
     }
 }
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Tax/AjaxDelete.php b/app/code/Magento/Tax/Controller/Adminhtml/Tax/AjaxDelete.php
index d817e1134442fe0602b5eb583fa7f6293f4407a7..20e413ed5e78f886d9fbb4be3b8562c1249bc022 100644
--- a/app/code/Magento/Tax/Controller/Adminhtml/Tax/AjaxDelete.php
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Tax/AjaxDelete.php
@@ -6,36 +6,32 @@
  */
 namespace Magento\Tax\Controller\Adminhtml\Tax;
 
+use Magento\Framework\Controller\ResultFactory;
+
 class AjaxDelete extends \Magento\Tax\Controller\Adminhtml\Tax
 {
     /**
      * Delete Tax Class via AJAX
      *
-     * @return void
+     * @return \Magento\Framework\Controller\Result\Json
      */
     public function execute()
     {
         $classId = (int)$this->getRequest()->getParam('class_id');
         try {
             $this->taxClassRepository->deleteById($classId);
-            $responseContent = $this->_objectManager->get(
-                'Magento\Framework\Json\Helper\Data'
-            )->jsonEncode(
-                ['success' => true, 'error_message' => '']
-            );
+            $responseContent = ['success' => true, 'error_message' => ''];
         } catch (\Magento\Framework\Exception\LocalizedException $e) {
-            $responseContent = $this->_objectManager->get(
-                'Magento\Framework\Json\Helper\Data'
-            )->jsonEncode(
-                ['success' => false, 'error_message' => $e->getMessage()]
-            );
+            $responseContent = ['success' => false, 'error_message' => $e->getMessage()];
         } catch (\Exception $e) {
-            $responseContent = $this->_objectManager->get(
-                'Magento\Framework\Json\Helper\Data'
-            )->jsonEncode(
-                ['success' => false, 'error_message' => __('Something went wrong deleting this tax class.')]
-            );
+            $responseContent = [
+                'success' => false,
+                'error_message' => __('Something went wrong deleting this tax class.')
+            ];
         }
-        $this->getResponse()->representJson($responseContent);
+        /** @var \Magento\Framework\Controller\Result\Json $resultJson */
+        $resultJson = $this->resultFactory->create(ResultFactory::TYPE_JSON);
+        $resultJson->setData($responseContent);
+        return $resultJson;
     }
 }
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Tax/AjaxSave.php b/app/code/Magento/Tax/Controller/Adminhtml/Tax/AjaxSave.php
index f338428b3ddb8dcfd77a1ffdf93f6de637b4cfa8..b8f72a7fa6d439e9849df9c4c81c57c2e8655931 100644
--- a/app/code/Magento/Tax/Controller/Adminhtml/Tax/AjaxSave.php
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Tax/AjaxSave.php
@@ -6,12 +6,14 @@
  */
 namespace Magento\Tax\Controller\Adminhtml\Tax;
 
+use Magento\Framework\Controller\ResultFactory;
+
 class AjaxSave extends \Magento\Tax\Controller\Adminhtml\Tax
 {
     /**
      * Save Tax Class via AJAX
      *
-     * @return void
+     * @return \Magento\Framework\Controller\Result\Json
      */
     public function execute()
     {
@@ -24,30 +26,30 @@ class AjaxSave extends \Magento\Tax\Controller\Adminhtml\Tax
                 ->setClassName($this->_processClassName((string)$this->getRequest()->getPost('class_name')));
             $taxClassId = $this->taxClassRepository->save($taxClass);
 
-            $responseContent = $this->_objectManager->get(
-                'Magento\Framework\Json\Helper\Data'
-            )->jsonEncode(
-                [
-                    'success' => true,
-                    'error_message' => '',
-                    'class_id' => $taxClassId,
-                    'class_name' => $taxClass->getClassName(),
-                ]
-            );
+            $responseContent = [
+                'success' => true,
+                'error_message' => '',
+                'class_id' => $taxClassId,
+                'class_name' => $taxClass->getClassName(),
+            ];
         } catch (\Magento\Framework\Exception\LocalizedException $e) {
-            $responseContent = $this->_objectManager->get('Magento\Framework\Json\Helper\Data')->jsonEncode(
-                ['success' => false, 'error_message' => $e->getMessage(), 'class_id' => '', 'class_name' => '']
-            );
+            $responseContent = [
+                'success' => false,
+                'error_message' => $e->getMessage(),
+                'class_id' => '',
+                'class_name' => ''
+            ];
         } catch (\Exception $e) {
-            $responseContent = $this->_objectManager->get('Magento\Framework\Json\Helper\Data')->jsonEncode(
-                [
-                    'success' => false,
-                    'error_message' => __('Something went wrong saving this tax class.'),
-                    'class_id' => '',
-                    'class_name' => '',
-                ]
-            );
+            $responseContent = [
+                'success' => false,
+                'error_message' => __('Something went wrong saving this tax class.'),
+                'class_id' => '',
+                'class_name' => '',
+            ];
         }
-        $this->getResponse()->representJson($responseContent);
+        /** @var \Magento\Framework\Controller\Result\Json $resultJson */
+        $resultJson = $this->resultFactory->create(ResultFactory::TYPE_JSON);
+        $resultJson->setData($responseContent);
+        return $resultJson;
     }
 }
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Tax/IgnoreTaxNotification.php b/app/code/Magento/Tax/Controller/Adminhtml/Tax/IgnoreTaxNotification.php
index 71db454cc337847c5f47dbef985ebf9e06360a82..9fede0b0238787abcc72a691b7473f588a90434b 100644
--- a/app/code/Magento/Tax/Controller/Adminhtml/Tax/IgnoreTaxNotification.php
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Tax/IgnoreTaxNotification.php
@@ -6,6 +6,9 @@
  */
 namespace Magento\Tax\Controller\Adminhtml\Tax;
 
+use Magento\Framework\App\Config\ScopeConfigInterface;
+use Magento\Framework\Controller\ResultFactory;
+
 class IgnoreTaxNotification extends \Magento\Tax\Controller\Adminhtml\Tax
 {
     /**
@@ -32,7 +35,7 @@ class IgnoreTaxNotification extends \Magento\Tax\Controller\Adminhtml\Tax
     /**
      * Set tax ignore notification flag and redirect back
      *
-     * @return \Magento\Framework\App\ResponseInterface
+     * @return \Magento\Backend\Model\View\Result\Redirect
      */
     public function execute()
     {
@@ -41,7 +44,7 @@ class IgnoreTaxNotification extends \Magento\Tax\Controller\Adminhtml\Tax
             try {
                 $path = 'tax/notification/ignore_' . $section;
                 $this->_objectManager->get('Magento\Config\Model\Resource\Config')
-                    ->saveConfig($path, 1, \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT, 0);
+                    ->saveConfig($path, 1, ScopeConfigInterface::SCOPE_TYPE_DEFAULT, 0);
             } catch (\Exception $e) {
                 $this->messageManager->addError($e->getMessage());
             }
@@ -51,6 +54,8 @@ class IgnoreTaxNotification extends \Magento\Tax\Controller\Adminhtml\Tax
         $this->_cacheTypeList->cleanType('block_html');
         $this->_eventManager->dispatch('adminhtml_cache_refresh_type', ['type' => 'block_html']);
 
-        $this->getResponse()->setRedirect($this->_redirect->getRefererUrl());
+        /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
+        $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
+        return $resultRedirect->setRefererUrl();
     }
 }
diff --git a/app/code/Magento/Tax/Model/Calculation/Rate.php b/app/code/Magento/Tax/Model/Calculation/Rate.php
index 18dde7c54f14d54945d1625e034e07ce7833f502..fae528a7d943f8b48b5023d3aaf2ad468a62bb98 100644
--- a/app/code/Magento/Tax/Model/Calculation/Rate.php
+++ b/app/code/Magento/Tax/Model/Calculation/Rate.php
@@ -20,8 +20,24 @@ use Magento\Tax\Api\Data\TaxRateInterface;
  * @method \Magento\Tax\Model\Resource\Calculation\Rate getResource()
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
-class Rate extends \Magento\Framework\Model\AbstractExtensibleModel implements \Magento\Tax\Api\Data\TaxRateInterface
+class Rate extends \Magento\Framework\Model\AbstractExtensibleModel implements TaxRateInterface
 {
+    /**#@+
+     * Constants defined for keys of array, makes typos less likely
+     */
+    const KEY_ID              = 'id';
+    const KEY_COUNTRY_ID      = 'tax_country_id';
+    const KEY_REGION_ID       = 'tax_region_id';
+    const KEY_REGION_NAME     = 'region_name';
+    const KEY_POSTCODE        = 'tax_postcode';
+    const KEY_ZIP_IS_RANGE    = 'zip_is_range';
+    const KEY_ZIP_RANGE_FROM  = 'zip_from';
+    const KEY_ZIP_RANGE_TO    = 'zip_to';
+    const KEY_PERCENTAGE_RATE = 'rate';
+    const KEY_CODE            = 'code';
+    const KEY_TITLES          = 'titles';
+    /**#@-*/
+
     /**
      * List of tax titles
      *
diff --git a/app/code/Magento/Tax/Model/Calculation/Rate/Converter.php b/app/code/Magento/Tax/Model/Calculation/Rate/Converter.php
index 7a407da4de340f4d8a8c82bc2df877786ecdcc3a..5fd8da907a5d8b81a297511758895d0dfa2156bd 100644
--- a/app/code/Magento/Tax/Model/Calculation/Rate/Converter.php
+++ b/app/code/Magento/Tax/Model/Calculation/Rate/Converter.php
@@ -12,6 +12,27 @@ namespace Magento\Tax\Model\Calculation\Rate;
  */
 class Converter
 {
+    /**
+     * @var \Magento\Tax\Api\Data\TaxRateInterfaceFactory
+     */
+    protected $taxRateDataObjectFactory;
+
+    /**
+     * @var \Magento\Tax\Api\Data\TaxRateTitleInterfaceFactory
+     */
+    protected $taxRateTitleDataObjectFactory;
+
+    /**
+     * @param \Magento\Tax\Api\Data\TaxRateInterfaceFactory $taxRateDataObjectFactory
+     * @param \Magento\Tax\Api\Data\TaxRateTitleInterfaceFactory $taxRateTitleDataObjectFactory,
+     */
+    public function __construct(
+        \Magento\Tax\Api\Data\TaxRateInterfaceFactory $taxRateDataObjectFactory,
+        \Magento\Tax\Api\Data\TaxRateTitleInterfaceFactory $taxRateTitleDataObjectFactory
+    ) {
+        $this->taxRateDataObjectFactory = $taxRateDataObjectFactory;
+        $this->taxRateTitleDataObjectFactory = $taxRateTitleDataObjectFactory;
+    }
     /**
      * Convert a tax rate data object to an array of associated titles
      *
@@ -29,4 +50,105 @@ class Converter
         }
         return $titleData;
     }
+
+    /**
+     * Extract tax rate data in a format which is
+     *
+     * @param \Magento\Tax\Api\Data\TaxRateInterface $taxRate
+     * @param Boolean $returnNumericLogic
+     * @return array
+     * @SuppressWarnings(PHPMD.NPathComplexity)
+     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+     */
+    public function createArrayFromServiceObject(
+        \Magento\Tax\Api\Data\TaxRateInterface $taxRate,
+        $returnNumericLogic = false
+    ) {
+        $taxRateFormData = [
+            'tax_calculation_rate_id' => $taxRate->getId(),
+            'tax_country_id' => $taxRate->getTaxCountryId(),
+            'tax_region_id' => $taxRate->getTaxRegionId(),
+            'tax_postcode' => $taxRate->getTaxPostcode(),
+            'code' => $taxRate->getCode(),
+            'rate' => $taxRate->getRate(),
+            'zip_is_range' => $returnNumericLogic?0:false,
+        ];
+
+        if ($taxRate->getZipFrom() && $taxRate->getZipTo()) {
+            $taxRateFormData['zip_is_range'] = $returnNumericLogic?1:true;
+            $taxRateFormData['zip_from'] = $taxRate->getZipFrom();
+            $taxRateFormData['zip_to'] = $taxRate->getZipTo();
+        }
+
+        if ($returnNumericLogic) {
+            //format for the ajax on multiple sites titles
+            $titleArray=($this->createTitleArrayFromServiceObject($taxRate));
+            if (is_array($titleArray)) {
+                foreach ($titleArray as $storeId => $title) {
+                    $taxRateFormData['title[' . $storeId . ']']=$title;
+                }
+            }
+        } else {
+            //format for the form array on multiple sites titles
+            $titleArray=($this->createTitleArrayFromServiceObject($taxRate));
+            if (is_array($titleArray)) {
+                $titleData = [];
+                foreach ($titleArray as $storeId => $title) {
+                    $titleData[] = [$storeId => $title];
+                }
+                if (count($titleArray)>0) {
+                    $taxRateFormData['title'] = $titleData;
+                }
+            }
+        }
+
+        return $taxRateFormData;
+    }
+
+
+    /**
+     * Convert an array to a tax rate data object
+     *
+     * @param array $formData
+     * @return \Magento\Tax\Api\Data\TaxRateInterface
+     */
+    public function populateTaxRateData($formData)
+    {
+        $taxRate = $this->taxRateDataObjectFactory->create();
+        $taxRate->setId($this->extractFormData($formData, 'tax_calculation_rate_id'))
+            ->setTaxCountryId($this->extractFormData($formData, 'tax_country_id'))
+            ->setTaxRegionId($this->extractFormData($formData, 'tax_region_id'))
+            ->setTaxPostcode($this->extractFormData($formData, 'tax_postcode'))
+            ->setCode($this->extractFormData($formData, 'code'))
+            ->setRate($this->extractFormData($formData, 'rate'));
+        if (isset($formData['zip_is_range']) && $formData['zip_is_range']) {
+            $taxRate->setZipFrom($this->extractFormData($formData, 'zip_from'))
+                ->setZipTo($this->extractFormData($formData, 'zip_to'))->setZipIsRange(1);
+        }
+
+        if (isset($formData['title'])) {
+            $titles = [];
+            foreach ($formData['title'] as $storeId => $value) {
+                $titles[] = $this->taxRateTitleDataObjectFactory->create()->setStoreId($storeId)->setValue($value);
+            }
+            $taxRate->setTitles($titles);
+        }
+
+        return $taxRate;
+    }
+
+    /**
+     * 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/Model/Calculation/Rate/Title.php b/app/code/Magento/Tax/Model/Calculation/Rate/Title.php
index a98b220548940e240774250f868c8b1abb8c4f1d..141e62435538b94a97d91671966161b6bf174b7c 100644
--- a/app/code/Magento/Tax/Model/Calculation/Rate/Title.php
+++ b/app/code/Magento/Tax/Model/Calculation/Rate/Title.php
@@ -17,9 +17,16 @@ namespace Magento\Tax\Model\Calculation\Rate;
 
 use Magento\Tax\Api\Data\TaxRateTitleInterface;
 
-class Title extends \Magento\Framework\Model\AbstractExtensibleModel implements
-    \Magento\Tax\Api\Data\TaxRateTitleInterface
+class Title extends \Magento\Framework\Model\AbstractExtensibleModel implements TaxRateTitleInterface
 {
+    /**#@+
+     *
+     * Tax rate field key.
+     */
+    const KEY_STORE_ID = 'store_id';
+    const KEY_VALUE_ID = 'value';
+    /**#@-*/
+
     /**
      * @return void
      */
diff --git a/app/code/Magento/Tax/Model/Calculation/RateRepository.php b/app/code/Magento/Tax/Model/Calculation/RateRepository.php
index a185acd15844412198f779b0efd4dc58e224a7fa..6f099ea27ae35038fac754ea19d97066355c7b47 100644
--- a/app/code/Magento/Tax/Model/Calculation/RateRepository.php
+++ b/app/code/Magento/Tax/Model/Calculation/RateRepository.php
@@ -15,7 +15,7 @@ use Magento\Framework\Api\SortOrder;
 use Magento\Framework\Exception\InputException;
 use Magento\Framework\Exception\LocalizedException;
 use Magento\Framework\Exception\AlreadyExistsException;
-use Magento\Tax\Api\Data\TaxRateInterface as TaxRateDataObject;
+use Magento\Tax\Model\Calculation\Rate;
 use Magento\Tax\Model\Calculation\Rate\Converter;
 use Magento\Tax\Model\Resource\Calculation\Rate\Collection;
 
@@ -210,7 +210,7 @@ class RateRepository implements \Magento\Tax\Api\TaxRateRepositoryInterface
     protected function translateField($field)
     {
         switch ($field) {
-            case TaxRateDataObject::KEY_REGION_NAME:
+            case Rate::KEY_REGION_NAME:
                 return 'region_table.code';
             default:
                 return "main_table." . $field;
diff --git a/app/code/Magento/Tax/Model/Calculation/Rule.php b/app/code/Magento/Tax/Model/Calculation/Rule.php
index 13d287ce5da36b67ece5d16a634a1ba3a743ca44..dc7e0cfac6f2c4932e6c1515b277483e78e88a7c 100644
--- a/app/code/Magento/Tax/Model/Calculation/Rule.php
+++ b/app/code/Magento/Tax/Model/Calculation/Rule.php
@@ -21,21 +21,14 @@ class Rule extends \Magento\Framework\Model\AbstractExtensibleModel implements T
      *
      * Tax rule field key.
      */
-    const KEY_ID = 'id';
-
-    const KEY_CODE = 'code';
-
+    const KEY_ID       = 'id';
+    const KEY_CODE     = 'code';
     const KEY_PRIORITY = 'priority';
-
     const KEY_POSITION = 'position';
-
     const KEY_CUSTOMER_TAX_CLASS_IDS = 'customer_tax_class_ids';
-
-    const KEY_PRODUCT_TAX_CLASS_IDS = 'product_tax_class_ids';
-
-    const KEY_TAX_RATE_IDS = 'tax_rate_ids';
-
-    const KEY_CALCULATE_SUBTOTAL = 'calculate_subtotal';
+    const KEY_PRODUCT_TAX_CLASS_IDS  = 'product_tax_class_ids';
+    const KEY_TAX_RATE_IDS           = 'tax_rate_ids';
+    const KEY_CALCULATE_SUBTOTAL     = 'calculate_subtotal';
     /**#@-*/
 
     /**
diff --git a/app/code/Magento/Tax/Model/ClassModel.php b/app/code/Magento/Tax/Model/ClassModel.php
index 603fc708d47286e0dffdd25f8724756445f6cac1..610527d58eb625ed32510e99dabbb11d58af3bc8 100644
--- a/app/code/Magento/Tax/Model/ClassModel.php
+++ b/app/code/Magento/Tax/Model/ClassModel.php
@@ -19,6 +19,14 @@ use Magento\Tax\Api\Data\TaxClassInterface;
 class ClassModel extends \Magento\Framework\Model\AbstractExtensibleModel implements
     \Magento\Tax\Api\Data\TaxClassInterface
 {
+    /**#@+
+     * Constants defined for keys of array, makes typos less likely
+     */
+    const KEY_ID   = 'class_id';
+    const KEY_NAME = 'class_name';
+    const KEY_TYPE = 'class_type';
+    /**#@-*/
+
     /**
      * Defines Customer Tax Class string
      */
diff --git a/app/code/Magento/Tax/Model/ClassModelRegistry.php b/app/code/Magento/Tax/Model/ClassModelRegistry.php
index e4667c061776813e7fa833bae372904527505eb5..da438fcbdf3d55ddb4d5127a36b89d402ec2e4cc 100644
--- a/app/code/Magento/Tax/Model/ClassModelRegistry.php
+++ b/app/code/Magento/Tax/Model/ClassModelRegistry.php
@@ -7,7 +7,6 @@
 namespace Magento\Tax\Model;
 
 use Magento\Framework\Exception\NoSuchEntityException;
-use Magento\Tax\Api\Data\TaxClassInterface;
 use Magento\Tax\Model\ClassModel as TaxClassModel;
 use Magento\Tax\Model\ClassModelFactory as TaxClassModelFactory;
 
@@ -67,7 +66,7 @@ class ClassModelRegistry
         $taxClassModel = $this->taxClassModelFactory->create()->load($taxClassId);
         if (!$taxClassModel->getId()) {
             // tax class does not exist
-            throw NoSuchEntityException::singleField(TaxClassInterface::KEY_ID, $taxClassId);
+            throw NoSuchEntityException::singleField(TaxClassModel::KEY_ID, $taxClassId);
         }
         $this->taxClassRegistryById[$taxClassModel->getId()] = $taxClassModel;
         return $taxClassModel;
diff --git a/app/code/Magento/Tax/Model/Config/Notification.php b/app/code/Magento/Tax/Model/Config/Notification.php
index c886452442406056cb369dd15210a1c32b0c9829..f4b395a290856cf26c36fae743ac7a3ce9797c9b 100644
--- a/app/code/Magento/Tax/Model/Config/Notification.php
+++ b/app/code/Magento/Tax/Model/Config/Notification.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\Tax\Model\Config;
 
+use Magento\Framework\App\Config\ScopeConfigInterface;
+
 /**
  * Tax Config Notification
  */
@@ -59,7 +61,7 @@ class Notification extends \Magento\Framework\App\Config\Value
      */
     protected function _resetNotificationFlag($path)
     {
-        $this->resourceConfig->saveConfig($path, 0, \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT, 0);
+        $this->resourceConfig->saveConfig($path, 0, ScopeConfigInterface::SCOPE_TYPE_DEFAULT, 0);
         return $this;
     }
 }
diff --git a/app/code/Magento/Tax/Model/Rate/Source.php b/app/code/Magento/Tax/Model/Rate/Source.php
index 8e4342ca28f161887bfc6aecf3e1d1f6ccb41b44..0d999d6698b6ba76630b3d81a815c8649e466cb5 100644
--- a/app/code/Magento/Tax/Model/Rate/Source.php
+++ b/app/code/Magento/Tax/Model/Rate/Source.php
@@ -8,8 +8,8 @@ namespace Magento\Tax\Model\Rate;
 
 use Magento\Framework\Api\SearchCriteriaBuilder;
 use Magento\Framework\Convert\Object as Converter;
-use Magento\Tax\Api\Data\TaxRateInterface as TaxRate;
 use Magento\Tax\Api\TaxRateRepositoryInterface;
+use Magento\Tax\Model\Calculation\Rate;
 
 /**
  * Tax rate source model.
@@ -57,8 +57,8 @@ class Source implements \Magento\Framework\Data\OptionSourceInterface
             $searchResults = $this->taxRateRepository->getList($searchCriteria);
             $this->options = $this->converter->toOptionArray(
                 $searchResults->getItems(),
-                TaxRate::KEY_ID,
-                TaxRate::KEY_CODE
+                Rate::KEY_ID,
+                Rate::KEY_CODE
             );
         }
         return $this->options;
diff --git a/app/code/Magento/Tax/Model/Sales/Order/Details.php b/app/code/Magento/Tax/Model/Sales/Order/Details.php
index 5161ab9fe6f7397f08cb88972033a8a6be6f6ef4..0294aff0f68eeef1f3e903a3ecbc85246d4fd3c9 100644
--- a/app/code/Magento/Tax/Model/Sales/Order/Details.php
+++ b/app/code/Magento/Tax/Model/Sales/Order/Details.php
@@ -13,6 +13,13 @@ namespace Magento\Tax\Model\Sales\Order;
 class Details extends \Magento\Framework\Model\AbstractExtensibleModel implements
     \Magento\Tax\Api\Data\OrderTaxDetailsInterface
 {
+    /**#@+
+     * Constants defined for keys of array, makes typos less likely
+     */
+    const KEY_APPLIED_TAXES = 'applied_taxes';
+    const KEY_ITEMS         = 'items';
+    /**#@-*/
+
     /**
      * {@inheritdoc}
      */
diff --git a/app/code/Magento/Tax/Model/Sales/Order/Tax.php b/app/code/Magento/Tax/Model/Sales/Order/Tax.php
index 29ce7e404f5696bcff549d3b276f6b14f6aea1d2..3b67f9222800f2f55585bff22409966003799d2e 100644
--- a/app/code/Magento/Tax/Model/Sales/Order/Tax.php
+++ b/app/code/Magento/Tax/Model/Sales/Order/Tax.php
@@ -25,6 +25,16 @@ namespace Magento\Tax\Model\Sales\Order;
 class Tax extends \Magento\Framework\Model\AbstractExtensibleModel implements
     \Magento\Tax\Api\Data\OrderTaxDetailsAppliedTaxInterface
 {
+    /**#@+
+     * Constants defined for keys of array, makes typos less likely
+     */
+    const KEY_CODE        = 'code';
+    const KEY_TITLE       = 'title';
+    const KEY_PERCENT     = 'percent';
+    const KEY_AMOUNT      = 'amount';
+    const KEY_BASE_AMOUNT = 'base_amount';
+    /**#@-*/
+
     /**
      * @return void
      */
diff --git a/app/code/Magento/Tax/Model/Sales/Order/Tax/Item.php b/app/code/Magento/Tax/Model/Sales/Order/Tax/Item.php
index a6b6148ed0c9eaca83d07b74c4d32f53ce3a1e74..8ecadf3eec08696f763a1f72ea1bbfa256dcd575 100644
--- a/app/code/Magento/Tax/Model/Sales/Order/Tax/Item.php
+++ b/app/code/Magento/Tax/Model/Sales/Order/Tax/Item.php
@@ -11,6 +11,15 @@ namespace Magento\Tax\Model\Sales\Order\Tax;
 class Item extends \Magento\Framework\Model\AbstractExtensibleModel implements
     \Magento\Tax\Api\Data\OrderTaxDetailsItemInterface
 {
+    /**#@+
+     * Constants defined for keys of array, makes typos less likely
+     */
+    const KEY_TYPE               = 'type';
+    const KEY_ITEM_ID            = 'item_id';
+    const KEY_ASSOCIATED_ITEM_ID = 'associated_item_id';
+    const KEY_APPLIED_TAXES      = 'applied_taxes';
+    /**#@-*/
+
     /**
      * {@inheritdoc}
      */
diff --git a/app/code/Magento/Tax/Model/Sales/Order/TaxManagement.php b/app/code/Magento/Tax/Model/Sales/Order/TaxManagement.php
index c665dfd00e8f8a65f487faacb618c1475991b10b..fed06b4dd1983da04c39ff4625bf22c0626a4707 100644
--- a/app/code/Magento/Tax/Model/Sales/Order/TaxManagement.php
+++ b/app/code/Magento/Tax/Model/Sales/Order/TaxManagement.php
@@ -10,7 +10,8 @@ namespace Magento\Tax\Model\Sales\Order;
 use Magento\Framework\Exception\NoSuchEntityException;
 use Magento\Tax\Api\Data\OrderTaxDetailsAppliedTaxInterfaceFactory as TaxDetailsDataObjectFactory;
 use Magento\Tax\Api\Data\OrderTaxDetailsAppliedTaxInterface as AppliedTax;
-use Magento\Tax\Api\Data\OrderTaxDetailsItemInterface as Item;
+use Magento\Tax\Model\Sales\Order\Tax;
+use Magento\Tax\Model\Sales\Order\Tax\Item;
 
 class TaxManagement implements \Magento\Tax\Api\OrderTaxManagementInterface
 {
@@ -83,7 +84,7 @@ class TaxManagement implements \Magento\Tax\Api\OrderTaxManagementInterface
      * Aggregate item applied taxes to get order applied taxes
      *
      * @param TaxDetailsDataObjectFactory $appliedTaxDataObjectFactory
-     * @param Item[] $items
+     * @param \Magento\Tax\Api\Data\OrderTaxDetailsItemInterface[] $items
      * @return AppliedTax[]
      */
     protected function aggregateAppliedTaxes(TaxDetailsDataObjectFactory $appliedTaxDataObjectFactory, $items)
@@ -96,25 +97,25 @@ class TaxManagement implements \Magento\Tax\Api\OrderTaxManagementInterface
                 $code = $itemAppliedTax->getCode();
                 if (!isset($orderAppliedTaxesData[$code])) {
                     $orderAppliedTaxesData[$code] = [
-                        AppliedTax::KEY_CODE => $code,
-                        AppliedTax::KEY_TITLE => $itemAppliedTax->getTitle(),
-                        AppliedTax::KEY_PERCENT => $itemAppliedTax->getPercent(),
-                        AppliedTax::KEY_AMOUNT => $itemAppliedTax->getAmount(),
-                        AppliedTax::KEY_BASE_AMOUNT => $itemAppliedTax->getBaseAmount(),
+                        Tax::KEY_CODE => $code,
+                        Tax::KEY_TITLE => $itemAppliedTax->getTitle(),
+                        Tax::KEY_PERCENT => $itemAppliedTax->getPercent(),
+                        Tax::KEY_AMOUNT => $itemAppliedTax->getAmount(),
+                        Tax::KEY_BASE_AMOUNT => $itemAppliedTax->getBaseAmount(),
                     ];
                 } else {
-                    $orderAppliedTaxesData[$code][AppliedTax::KEY_AMOUNT] += $itemAppliedTax->getAmount();
-                    $orderAppliedTaxesData[$code][AppliedTax::KEY_BASE_AMOUNT] += $itemAppliedTax->getBaseAmount();
+                    $orderAppliedTaxesData[$code][Tax::KEY_AMOUNT] += $itemAppliedTax->getAmount();
+                    $orderAppliedTaxesData[$code][Tax::KEY_BASE_AMOUNT] += $itemAppliedTax->getBaseAmount();
                 }
             }
         }
         foreach ($orderAppliedTaxesData as $orderAppliedTaxData) {
             $orderAppliedTaxes[] = $appliedTaxDataObjectFactory->create()
-                ->setCode($orderAppliedTaxData[AppliedTax::KEY_CODE])
-                ->setTitle($orderAppliedTaxData[AppliedTax::KEY_TITLE])
-                ->setPercent($orderAppliedTaxData[AppliedTax::KEY_PERCENT])
-                ->setAmount($orderAppliedTaxData[AppliedTax::KEY_AMOUNT])
-                ->setBaseAmount($orderAppliedTaxData[AppliedTax::KEY_BASE_AMOUNT]);
+                ->setCode($orderAppliedTaxData[Tax::KEY_CODE])
+                ->setTitle($orderAppliedTaxData[Tax::KEY_TITLE])
+                ->setPercent($orderAppliedTaxData[Tax::KEY_PERCENT])
+                ->setAmount($orderAppliedTaxData[Tax::KEY_AMOUNT])
+                ->setBaseAmount($orderAppliedTaxData[Tax::KEY_BASE_AMOUNT]);
         }
         return $orderAppliedTaxes;
     }
diff --git a/app/code/Magento/Tax/Model/Sales/Quote/ItemDetails.php b/app/code/Magento/Tax/Model/Sales/Quote/ItemDetails.php
index 71d18024ea5f1a199b99ff3811fa4d82d7009ed7..cd893b122f89381b05baa4b5cc41e59d120bd40b 100644
--- a/app/code/Magento/Tax/Model/Sales/Quote/ItemDetails.php
+++ b/app/code/Magento/Tax/Model/Sales/Quote/ItemDetails.php
@@ -13,12 +13,28 @@ use Magento\Tax\Api\Data\QuoteDetailsItemInterface;
  */
 class ItemDetails extends AbstractExtensibleModel implements QuoteDetailsItemInterface
 {
+    /**#@+
+     * Constants defined for keys of array, makes typos less likely
+     */
+    const KEY_CODE                 = 'code';
+    const KEY_TYPE                 = 'type';
+    const KEY_TAX_CLASS_KEY        = 'tax_class_key';
+    const KEY_UNIT_PRICE           = 'unit_price';
+    const KEY_QUANTITY             = 'quantity';
+    const KEY_TAX_INCLUDED         = 'tax_included';
+    const KEY_SHORT_DESCRIPTION    = 'short_description';
+    const KEY_DISCOUNT_AMOUNT      = 'discount_amount';
+    const KEY_PARENT_CODE          = 'parent_code';
+    const KEY_ASSOCIATED_ITEM_CODE = 'associated_item_code';
+    const KEY_TAX_CLASS_ID         = 'tax_class_id';
+    /**#@-*/
+
     /**
      * {@inheritdoc}
      */
     public function getCode()
     {
-        return $this->getData(QuoteDetailsItemInterface::KEY_CODE);
+        return $this->getData(self::KEY_CODE);
     }
 
     /**
@@ -26,7 +42,7 @@ class ItemDetails extends AbstractExtensibleModel implements QuoteDetailsItemInt
      */
     public function getType()
     {
-        return $this->getData(QuoteDetailsItemInterface::KEY_TYPE);
+        return $this->getData(self::KEY_TYPE);
     }
 
     /**
@@ -34,7 +50,7 @@ class ItemDetails extends AbstractExtensibleModel implements QuoteDetailsItemInt
      */
     public function getTaxClassKey()
     {
-        return $this->getData(QuoteDetailsItemInterface::KEY_TAX_CLASS_KEY);
+        return $this->getData(self::KEY_TAX_CLASS_KEY);
     }
 
     /**
@@ -42,7 +58,7 @@ class ItemDetails extends AbstractExtensibleModel implements QuoteDetailsItemInt
      */
     public function getUnitPrice()
     {
-        return $this->getData(QuoteDetailsItemInterface::KEY_UNIT_PRICE);
+        return $this->getData(self::KEY_UNIT_PRICE);
     }
 
     /**
@@ -50,7 +66,7 @@ class ItemDetails extends AbstractExtensibleModel implements QuoteDetailsItemInt
      */
     public function getQuantity()
     {
-        return $this->getData(QuoteDetailsItemInterface::KEY_QUANTITY);
+        return $this->getData(self::KEY_QUANTITY);
     }
 
     /**
@@ -58,7 +74,7 @@ class ItemDetails extends AbstractExtensibleModel implements QuoteDetailsItemInt
      */
     public function getTaxIncluded()
     {
-        return $this->getData(QuoteDetailsItemInterface::KEY_TAX_INCLUDED);
+        return $this->getData(self::KEY_TAX_INCLUDED);
     }
 
     /**
@@ -66,7 +82,7 @@ class ItemDetails extends AbstractExtensibleModel implements QuoteDetailsItemInt
      */
     public function getShortDescription()
     {
-        return $this->getData(QuoteDetailsItemInterface::KEY_SHORT_DESCRIPTION);
+        return $this->getData(self::KEY_SHORT_DESCRIPTION);
     }
 
     /**
@@ -74,7 +90,7 @@ class ItemDetails extends AbstractExtensibleModel implements QuoteDetailsItemInt
      */
     public function getDiscountAmount()
     {
-        return $this->getData(QuoteDetailsItemInterface::KEY_DISCOUNT_AMOUNT);
+        return $this->getData(self::KEY_DISCOUNT_AMOUNT);
     }
 
     /**
@@ -82,7 +98,7 @@ class ItemDetails extends AbstractExtensibleModel implements QuoteDetailsItemInt
      */
     public function getParentCode()
     {
-        return $this->getData(QuoteDetailsItemInterface::KEY_PARENT_CODE);
+        return $this->getData(self::KEY_PARENT_CODE);
     }
 
     /**
@@ -90,7 +106,7 @@ class ItemDetails extends AbstractExtensibleModel implements QuoteDetailsItemInt
      */
     public function getAssociatedItemCode()
     {
-        return $this->getData(QuoteDetailsItemInterface::KEY_ASSOCIATED_ITEM_CODE);
+        return $this->getData(self::KEY_ASSOCIATED_ITEM_CODE);
     }
 
     /**
@@ -98,7 +114,7 @@ class ItemDetails extends AbstractExtensibleModel implements QuoteDetailsItemInt
      */
     public function getTaxClassId()
     {
-        return $this->getData(QuoteDetailsItemInterface::KEY_TAX_CLASS_ID);
+        return $this->getData(self::KEY_TAX_CLASS_ID);
     }
 
     /**
@@ -109,7 +125,7 @@ class ItemDetails extends AbstractExtensibleModel implements QuoteDetailsItemInt
      */
     public function setCode($code)
     {
-        return $this->setData(QuoteDetailsItemInterface::KEY_CODE, $code);
+        return $this->setData(self::KEY_CODE, $code);
     }
 
     /**
@@ -120,7 +136,7 @@ class ItemDetails extends AbstractExtensibleModel implements QuoteDetailsItemInt
      */
     public function setType($type)
     {
-        return $this->setData(QuoteDetailsItemInterface::KEY_TYPE, $type);
+        return $this->setData(self::KEY_TYPE, $type);
     }
 
     /**
@@ -131,7 +147,7 @@ class ItemDetails extends AbstractExtensibleModel implements QuoteDetailsItemInt
      */
     public function setTaxClassKey(\Magento\Tax\Api\Data\TaxClassKeyInterface $taxClassKey = null)
     {
-        return $this->setData(QuoteDetailsItemInterface::KEY_TAX_CLASS_KEY, $taxClassKey);
+        return $this->setData(self::KEY_TAX_CLASS_KEY, $taxClassKey);
     }
 
     /**
@@ -142,7 +158,7 @@ class ItemDetails extends AbstractExtensibleModel implements QuoteDetailsItemInt
      */
     public function setUnitPrice($unitPrice)
     {
-        return $this->setData(QuoteDetailsItemInterface::KEY_UNIT_PRICE, $unitPrice);
+        return $this->setData(self::KEY_UNIT_PRICE, $unitPrice);
     }
 
     /**
@@ -153,7 +169,7 @@ class ItemDetails extends AbstractExtensibleModel implements QuoteDetailsItemInt
      */
     public function setQuantity($quantity)
     {
-        return $this->setData(QuoteDetailsItemInterface::KEY_QUANTITY, $quantity);
+        return $this->setData(self::KEY_QUANTITY, $quantity);
     }
 
     /**
@@ -164,7 +180,7 @@ class ItemDetails extends AbstractExtensibleModel implements QuoteDetailsItemInt
      */
     public function setIsTaxIncluded($isTaxIncluded)
     {
-        return $this->setData(QuoteDetailsItemInterface::KEY_TAX_INCLUDED, $isTaxIncluded);
+        return $this->setData(self::KEY_TAX_INCLUDED, $isTaxIncluded);
     }
 
     /**
@@ -175,7 +191,7 @@ class ItemDetails extends AbstractExtensibleModel implements QuoteDetailsItemInt
      */
     public function setShortDescription($shortDescription)
     {
-        return $this->setData(QuoteDetailsItemInterface::KEY_SHORT_DESCRIPTION, $shortDescription);
+        return $this->setData(self::KEY_SHORT_DESCRIPTION, $shortDescription);
     }
 
     /**
@@ -186,7 +202,7 @@ class ItemDetails extends AbstractExtensibleModel implements QuoteDetailsItemInt
      */
     public function setDiscountAmount($discountAmount)
     {
-        return $this->setData(QuoteDetailsItemInterface::KEY_DISCOUNT_AMOUNT, $discountAmount);
+        return $this->setData(self::KEY_DISCOUNT_AMOUNT, $discountAmount);
     }
 
     /**
@@ -197,7 +213,7 @@ class ItemDetails extends AbstractExtensibleModel implements QuoteDetailsItemInt
      */
     public function setParentCode($parentCode)
     {
-        return $this->setData(QuoteDetailsItemInterface::KEY_PARENT_CODE, $parentCode);
+        return $this->setData(self::KEY_PARENT_CODE, $parentCode);
     }
 
     /**
@@ -208,7 +224,7 @@ class ItemDetails extends AbstractExtensibleModel implements QuoteDetailsItemInt
      */
     public function setAssociatedItemCode($associatedItemCode)
     {
-        return $this->setData(QuoteDetailsItemInterface::KEY_ASSOCIATED_ITEM_CODE, $associatedItemCode);
+        return $this->setData(self::KEY_ASSOCIATED_ITEM_CODE, $associatedItemCode);
     }
 
     /**
@@ -219,7 +235,7 @@ class ItemDetails extends AbstractExtensibleModel implements QuoteDetailsItemInt
      */
     public function setTaxClassId($taxClassId)
     {
-        return $this->setData(QuoteDetailsItemInterface::KEY_TAX_CLASS_ID, $taxClassId);
+        return $this->setData(self::KEY_TAX_CLASS_ID, $taxClassId);
     }
 
     /**
diff --git a/app/code/Magento/Tax/Model/Sales/Quote/QuoteDetails.php b/app/code/Magento/Tax/Model/Sales/Quote/QuoteDetails.php
index 1ef369ba40d82dfb3655926be7970e003892a152..1569e8496bd0cb9417b6f0609df658f06f21a0ed 100644
--- a/app/code/Magento/Tax/Model/Sales/Quote/QuoteDetails.php
+++ b/app/code/Magento/Tax/Model/Sales/Quote/QuoteDetails.php
@@ -13,12 +13,23 @@ use Magento\Tax\Api\Data\QuoteDetailsInterface;
  */
 class QuoteDetails extends AbstractExtensibleModel implements QuoteDetailsInterface
 {
+    /**#@+
+     * Constants defined for keys of array, makes typos less likely
+     */
+    const KEY_BILLING_ADDRESS        = 'billing_address';
+    const KEY_SHIPPING_ADDRESS       = 'shipping_address';
+    const KEY_CUSTOMER_TAX_CLASS_KEY = 'customer_tax_class_key';
+    const KEY_ITEMS                  = 'items';
+    const KEY_CUSTOMER_TAX_CLASS_ID  = 'customer_tax_class_id';
+    const KEY_CUSTOMER_ID            = 'customer_id';
+    /**#@-*/
+
     /**
      * {@inheritdoc}
      */
     public function getBillingAddress()
     {
-        return $this->getData(QuoteDetailsInterface::KEY_BILLING_ADDRESS);
+        return $this->getData(self::KEY_BILLING_ADDRESS);
     }
 
     /**
@@ -26,7 +37,7 @@ class QuoteDetails extends AbstractExtensibleModel implements QuoteDetailsInterf
      */
     public function getShippingAddress()
     {
-        return $this->getData(QuoteDetailsInterface::KEY_SHIPPING_ADDRESS);
+        return $this->getData(self::KEY_SHIPPING_ADDRESS);
     }
 
     /**
@@ -34,7 +45,7 @@ class QuoteDetails extends AbstractExtensibleModel implements QuoteDetailsInterf
      */
     public function getCustomerTaxClassKey()
     {
-        return $this->getData(QuoteDetailsInterface::KEY_CUSTOMER_TAX_CLASS_KEY);
+        return $this->getData(self::KEY_CUSTOMER_TAX_CLASS_KEY);
     }
 
     /**
@@ -42,7 +53,7 @@ class QuoteDetails extends AbstractExtensibleModel implements QuoteDetailsInterf
      */
     public function getCustomerId()
     {
-        return $this->getData(QuoteDetailsInterface::KEY_CUSTOMER_ID);
+        return $this->getData(self::KEY_CUSTOMER_ID);
     }
 
     /**
@@ -50,7 +61,7 @@ class QuoteDetails extends AbstractExtensibleModel implements QuoteDetailsInterf
      */
     public function getItems()
     {
-        return $this->getData(QuoteDetailsInterface::KEY_ITEMS);
+        return $this->getData(self::KEY_ITEMS);
     }
 
     /**
@@ -58,7 +69,7 @@ class QuoteDetails extends AbstractExtensibleModel implements QuoteDetailsInterf
      */
     public function getCustomerTaxClassId()
     {
-        return $this->getData(QuoteDetailsInterface::CUSTOMER_TAX_CLASS_ID);
+        return $this->getData(self::KEY_CUSTOMER_TAX_CLASS_ID);
     }
 
     /**
@@ -69,7 +80,7 @@ class QuoteDetails extends AbstractExtensibleModel implements QuoteDetailsInterf
      */
     public function setBillingAddress(\Magento\Customer\Api\Data\AddressInterface $billingAddress = null)
     {
-        return $this->setData(QuoteDetailsInterface::KEY_BILLING_ADDRESS, $billingAddress);
+        return $this->setData(self::KEY_BILLING_ADDRESS, $billingAddress);
     }
 
     /**
@@ -80,7 +91,7 @@ class QuoteDetails extends AbstractExtensibleModel implements QuoteDetailsInterf
      */
     public function setShippingAddress(\Magento\Customer\Api\Data\AddressInterface $shippingAddress = null)
     {
-        return $this->setData(QuoteDetailsInterface::KEY_SHIPPING_ADDRESS, $shippingAddress);
+        return $this->setData(self::KEY_SHIPPING_ADDRESS, $shippingAddress);
     }
 
     /**
@@ -91,7 +102,7 @@ class QuoteDetails extends AbstractExtensibleModel implements QuoteDetailsInterf
      */
     public function setCustomerTaxClassKey(\Magento\Tax\Api\Data\TaxClassKeyInterface $customerTaxClassKey = null)
     {
-        return $this->setData(QuoteDetailsInterface::KEY_CUSTOMER_TAX_CLASS_KEY, $customerTaxClassKey);
+        return $this->setData(self::KEY_CUSTOMER_TAX_CLASS_KEY, $customerTaxClassKey);
     }
 
     /**
@@ -102,7 +113,7 @@ class QuoteDetails extends AbstractExtensibleModel implements QuoteDetailsInterf
      */
     public function setCustomerId($customerId)
     {
-        return $this->setData(QuoteDetailsInterface::KEY_CUSTOMER_ID, $customerId);
+        return $this->setData(self::KEY_CUSTOMER_ID, $customerId);
     }
 
     /**
@@ -113,7 +124,7 @@ class QuoteDetails extends AbstractExtensibleModel implements QuoteDetailsInterf
      */
     public function setItems(array $items = null)
     {
-        return $this->setData(QuoteDetailsInterface::KEY_ITEMS, $items);
+        return $this->setData(self::KEY_ITEMS, $items);
     }
 
     /**
@@ -124,7 +135,7 @@ class QuoteDetails extends AbstractExtensibleModel implements QuoteDetailsInterf
      */
     public function setCustomerTaxClassId($customerTaxClassId)
     {
-        return $this->setData(QuoteDetailsInterface::CUSTOMER_TAX_CLASS_ID, $customerTaxClassId);
+        return $this->setData(self::KEY_CUSTOMER_TAX_CLASS_ID, $customerTaxClassId);
     }
 
     /**
diff --git a/app/code/Magento/Tax/Model/TaxCalculation.php b/app/code/Magento/Tax/Model/TaxCalculation.php
index fdbc6cb724bfe1bf27df13375ba11d8ff29af87e..579ee5519899603976a08b1aeb874a59f1f8d774 100644
--- a/app/code/Magento/Tax/Model/TaxCalculation.php
+++ b/app/code/Magento/Tax/Model/TaxCalculation.php
@@ -6,19 +6,19 @@
 
 namespace Magento\Tax\Model;
 
-use Magento\Tax\Api\Data\TaxDetailsInterface;
+use Magento\Tax\Api\TaxCalculationInterface;
+use Magento\Tax\Api\TaxClassManagementInterface;
 use Magento\Tax\Api\Data\TaxDetailsItemInterface;
 use Magento\Tax\Api\Data\QuoteDetailsItemInterface;
 use Magento\Tax\Api\Data\TaxDetailsInterfaceFactory;
 use Magento\Tax\Api\Data\TaxDetailsItemInterfaceFactory;
-use Magento\Tax\Api\Data\AppliedTaxRateInterface;
-use Magento\Tax\Api\Data\AppliedTaxInterface;
-use Magento\Tax\Api\TaxClassManagementInterface;
+use Magento\Tax\Model\Calculation\AbstractCalculator;
 use Magento\Tax\Model\Calculation\CalculatorFactory;
 use Magento\Tax\Model\Config;
-use Magento\Tax\Model\Calculation\AbstractCalculator;
+use Magento\Tax\Model\TaxDetails\AppliedTax;
+use Magento\Tax\Model\TaxDetails\AppliedTaxRate;
+use Magento\Tax\Model\TaxDetails\TaxDetails;
 use Magento\Store\Model\StoreManagerInterface;
-use Magento\Tax\Api\TaxCalculationInterface;
 
 /**
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
@@ -142,11 +142,11 @@ class TaxCalculation implements TaxCalculationInterface
 
         // initial TaxDetails data
         $taxDetailsData = [
-            TaxDetailsInterface::KEY_SUBTOTAL => 0.0,
-            TaxDetailsInterface::KEY_TAX_AMOUNT => 0.0,
-            TaxDetailsInterface::KEY_DISCOUNT_TAX_COMPENSATION_AMOUNT => 0.0,
-            TaxDetailsInterface::KEY_APPLIED_TAXES => [],
-            TaxDetailsInterface::KEY_ITEMS => [],
+            TaxDetails::KEY_SUBTOTAL => 0.0,
+            TaxDetails::KEY_TAX_AMOUNT => 0.0,
+            TaxDetails::KEY_DISCOUNT_TAX_COMPENSATION_AMOUNT => 0.0,
+            TaxDetails::KEY_APPLIED_TAXES => [],
+            TaxDetails::KEY_ITEMS => [],
         ];
         $items = $quoteDetails->getItems();
         if (empty($items)) {
@@ -327,21 +327,21 @@ class TaxCalculation implements TaxCalculationInterface
      */
     protected function aggregateItemData($taxDetailsData, TaxDetailsItemInterface $item)
     {
-        $taxDetailsData[TaxDetailsInterface::KEY_SUBTOTAL]
-            = $taxDetailsData[TaxDetailsInterface::KEY_SUBTOTAL] + $item->getRowTotal();
+        $taxDetailsData[TaxDetails::KEY_SUBTOTAL]
+            = $taxDetailsData[TaxDetails::KEY_SUBTOTAL] + $item->getRowTotal();
 
-        $taxDetailsData[TaxDetailsInterface::KEY_TAX_AMOUNT]
-            = $taxDetailsData[TaxDetailsInterface::KEY_TAX_AMOUNT] + $item->getRowTax();
+        $taxDetailsData[TaxDetails::KEY_TAX_AMOUNT]
+            = $taxDetailsData[TaxDetails::KEY_TAX_AMOUNT] + $item->getRowTax();
 
-        $taxDetailsData[TaxDetailsInterface::KEY_DISCOUNT_TAX_COMPENSATION_AMOUNT] =
-            $taxDetailsData[TaxDetailsInterface::KEY_DISCOUNT_TAX_COMPENSATION_AMOUNT]
+        $taxDetailsData[TaxDetails::KEY_DISCOUNT_TAX_COMPENSATION_AMOUNT] =
+            $taxDetailsData[TaxDetails::KEY_DISCOUNT_TAX_COMPENSATION_AMOUNT]
             + $item->getDiscountTaxCompensationAmount();
 
         $itemAppliedTaxes = $item->getAppliedTaxes();
         if ($itemAppliedTaxes === null) {
             return $taxDetailsData;
         }
-        $appliedTaxes = $taxDetailsData[TaxDetailsInterface::KEY_APPLIED_TAXES];
+        $appliedTaxes = $taxDetailsData[TaxDetails::KEY_APPLIED_TAXES];
         foreach ($itemAppliedTaxes as $taxId => $itemAppliedTax) {
             if (!isset($appliedTaxes[$taxId])) {
                 //convert rate data object to array
@@ -349,23 +349,23 @@ class TaxCalculation implements TaxCalculationInterface
                 $rateDataObjects = $itemAppliedTax->getRates();
                 foreach ($rateDataObjects as $rateDataObject) {
                     $rates[$rateDataObject->getCode()] = [
-                        AppliedTaxRateInterface::KEY_CODE => $rateDataObject->getCode(),
-                        AppliedTaxRateInterface::KEY_TITLE => $rateDataObject->getTitle(),
-                        AppliedTaxRateInterface::KEY_PERCENT => $rateDataObject->getPercent(),
+                        AppliedTaxRate::KEY_CODE => $rateDataObject->getCode(),
+                        AppliedTaxRate::KEY_TITLE => $rateDataObject->getTitle(),
+                        AppliedTaxRate::KEY_PERCENT => $rateDataObject->getPercent(),
                     ];
                 }
                 $appliedTaxes[$taxId] = [
-                    AppliedTaxInterface::KEY_AMOUNT => $itemAppliedTax->getAmount(),
-                    AppliedTaxInterface::KEY_PERCENT => $itemAppliedTax->getPercent(),
-                    AppliedTaxInterface::KEY_RATES => $rates,
-                    AppliedTaxInterface::KEY_TAX_RATE_KEY => $itemAppliedTax->getTaxRateKey(),
+                    AppliedTax::KEY_AMOUNT => $itemAppliedTax->getAmount(),
+                    AppliedTax::KEY_PERCENT => $itemAppliedTax->getPercent(),
+                    AppliedTax::KEY_RATES => $rates,
+                    AppliedTax::KEY_TAX_RATE_KEY => $itemAppliedTax->getTaxRateKey(),
                 ];
             } else {
-                $appliedTaxes[$taxId][AppliedTaxInterface::KEY_AMOUNT] += $itemAppliedTax->getAmount();
+                $appliedTaxes[$taxId][AppliedTax::KEY_AMOUNT] += $itemAppliedTax->getAmount();
             }
         }
 
-        $taxDetailsData[TaxDetailsInterface::KEY_APPLIED_TAXES] = $appliedTaxes;
+        $taxDetailsData[TaxDetails::KEY_APPLIED_TAXES] = $appliedTaxes;
         return $taxDetailsData;
     }
 
diff --git a/app/code/Magento/Tax/Model/TaxClass/Key.php b/app/code/Magento/Tax/Model/TaxClass/Key.php
index 085b018aa88f7ad8ba4ef5a36fea99c31f6ded54..c882d2dae170cfa9589909859f8b0eb995a41d01 100644
--- a/app/code/Magento/Tax/Model/TaxClass/Key.php
+++ b/app/code/Magento/Tax/Model/TaxClass/Key.php
@@ -13,12 +13,19 @@ use Magento\Tax\Api\Data\TaxClassKeyInterface;
  */
 class Key extends AbstractExtensibleModel implements TaxClassKeyInterface
 {
+    /**#@+
+     * Constants defined for keys of array, makes typos less likely
+     */
+    const KEY_TYPE  = 'type';
+    const KEY_VALUE = 'value';
+    /**#@-*/
+
     /**
      * {@inheritdoc}
      */
     public function getType()
     {
-        return $this->getData(TaxClassKeyInterface::KEY_TYPE);
+        return $this->getData(self::KEY_TYPE);
     }
 
     /**
@@ -26,7 +33,7 @@ class Key extends AbstractExtensibleModel implements TaxClassKeyInterface
      */
     public function getValue()
     {
-        return $this->getData(TaxClassKeyInterface::KEY_VALUE);
+        return $this->getData(self::KEY_VALUE);
     }
 
     /**
@@ -37,7 +44,7 @@ class Key extends AbstractExtensibleModel implements TaxClassKeyInterface
      */
     public function setType($type)
     {
-        return $this->setData(TaxClassKeyInterface::KEY_TYPE, $type);
+        return $this->setData(self::KEY_TYPE, $type);
     }
 
     /**
@@ -48,7 +55,7 @@ class Key extends AbstractExtensibleModel implements TaxClassKeyInterface
      */
     public function setValue($value)
     {
-        return $this->setData(TaxClassKeyInterface::KEY_VALUE, $value);
+        return $this->setData(self::KEY_VALUE, $value);
     }
 
     /**
diff --git a/app/code/Magento/Tax/Model/TaxClass/Management.php b/app/code/Magento/Tax/Model/TaxClass/Management.php
index 679a054b62314f379cfbc94ec0b0633a1142c059..eb7871c1086c22efe4e988254490bf02abdebf48 100644
--- a/app/code/Magento/Tax/Model/TaxClass/Management.php
+++ b/app/code/Magento/Tax/Model/TaxClass/Management.php
@@ -9,8 +9,8 @@ namespace Magento\Tax\Model\TaxClass;
 
 use Magento\Framework\Api\FilterBuilder;
 use Magento\Framework\Api\SearchCriteriaBuilder;
-use Magento\Tax\Api\Data\TaxClassInterface;
 use Magento\Tax\Api\Data\TaxClassKeyInterface;
+use Magento\Tax\Model\ClassModel;
 
 class Management implements \Magento\Tax\Api\TaxClassManagementInterface
 {
@@ -61,10 +61,10 @@ class Management implements \Magento\Tax\Api\TaxClassManagementInterface
                     return $taxClassKey->getValue();
                 case TaxClassKeyInterface::TYPE_NAME:
                     $searchCriteria = $this->searchCriteriaBuilder->addFilter(
-                        [$this->filterBuilder->setField(TaxClassInterface::KEY_TYPE)->setValue($taxClassType)->create()]
+                        [$this->filterBuilder->setField(ClassModel::KEY_TYPE)->setValue($taxClassType)->create()]
                     )->addFilter(
                         [
-                            $this->filterBuilder->setField(TaxClassInterface::KEY_NAME)
+                            $this->filterBuilder->setField(ClassModel::KEY_NAME)
                                 ->setValue($taxClassKey->getValue())
                                 ->create(),
                         ]
diff --git a/app/code/Magento/Tax/Model/TaxClass/Repository.php b/app/code/Magento/Tax/Model/TaxClass/Repository.php
index a0fc6fe76d46ec8718a7cccf2af8a44068b73425..01dd656b0d5e51d5b64e22c8fd4d80e937d19e2b 100644
--- a/app/code/Magento/Tax/Model/TaxClass/Repository.php
+++ b/app/code/Magento/Tax/Model/TaxClass/Repository.php
@@ -15,8 +15,8 @@ use Magento\Framework\Api\SortOrder;
 use Magento\Framework\Exception\CouldNotDeleteException;
 use Magento\Framework\Exception\InputException;
 use Magento\Framework\Exception\LocalizedException as ModelException;
-use Magento\Tax\Api\Data\TaxClassInterface;
 use Magento\Tax\Api\TaxClassManagementInterface;
+use Magento\Tax\Model\ClassModel;
 use Magento\Tax\Model\ClassModelRegistry;
 use Magento\Tax\Model\Resource\TaxClass\Collection as TaxClassCollection;
 use Magento\Tax\Model\Resource\TaxClass\CollectionFactory as TaxClassCollectionFactory;
@@ -164,19 +164,19 @@ class Repository implements \Magento\Tax\Api\TaxClassRepositoryInterface
         $exception = new InputException();
 
         if (!\Zend_Validate::is(trim($taxClass->getClassName()), 'NotEmpty')) {
-            $exception->addError(__(InputException::REQUIRED_FIELD, ['fieldName' => TaxClassInterface::KEY_NAME]));
+            $exception->addError(__(InputException::REQUIRED_FIELD, ['fieldName' => ClassModel::KEY_NAME]));
         }
 
         $classType = $taxClass->getClassType();
         if (!\Zend_Validate::is(trim($classType), 'NotEmpty')) {
-            $exception->addError(__(InputException::REQUIRED_FIELD, ['fieldName' => TaxClassInterface::KEY_TYPE]));
+            $exception->addError(__(InputException::REQUIRED_FIELD, ['fieldName' => ClassModel::KEY_TYPE]));
         } elseif ($classType !== TaxClassManagementInterface::TYPE_CUSTOMER
             && $classType !== TaxClassManagementInterface::TYPE_PRODUCT
         ) {
             $exception->addError(
                 __(
                     InputException::INVALID_FIELD_VALUE,
-                    ['fieldName' => TaxClassInterface::KEY_TYPE, 'value' => $classType]
+                    ['fieldName' => ClassModel::KEY_TYPE, 'value' => $classType]
                 )
             );
         }
diff --git a/app/code/Magento/Tax/Model/TaxClass/Source/Customer.php b/app/code/Magento/Tax/Model/TaxClass/Source/Customer.php
index 4a52c81b669fb5a3a13b775ab60686f18ecb5c99..ca0dd21abdd84a2714adf6c8eb26aa89c83584de 100644
--- a/app/code/Magento/Tax/Model/TaxClass/Source/Customer.php
+++ b/app/code/Magento/Tax/Model/TaxClass/Source/Customer.php
@@ -8,7 +8,7 @@ namespace Magento\Tax\Model\TaxClass\Source;
 
 use Magento\Framework\Exception\StateException;
 use Magento\Tax\Api\TaxClassManagementInterface;
-use Magento\Tax\Api\Data\TaxClassInterface as TaxClass;
+use Magento\Tax\Model\ClassModel;
 
 /**
  * Customer tax class source model.
@@ -57,7 +57,7 @@ class Customer extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource
     {
         if (empty($this->_options)) {
             $options = [];
-            $filter = $this->filterBuilder->setField(TaxClass::KEY_TYPE)
+            $filter = $this->filterBuilder->setField(ClassModel::KEY_TYPE)
                 ->setValue(TaxClassManagementInterface::TYPE_CUSTOMER)
                 ->create();
             $searchCriteria = $this->searchCriteriaBuilder->addFilter([$filter])->create();
diff --git a/app/code/Magento/Tax/Model/TaxClass/Source/Product.php b/app/code/Magento/Tax/Model/TaxClass/Source/Product.php
index bf8711f93228abcfec3c8c6836ff0dd3847a4b23..37844ab57076c71cfc5fb8c57010de4db1fe5444 100644
--- a/app/code/Magento/Tax/Model/TaxClass/Source/Product.php
+++ b/app/code/Magento/Tax/Model/TaxClass/Source/Product.php
@@ -7,8 +7,8 @@
 namespace Magento\Tax\Model\TaxClass\Source;
 
 use Magento\Framework\DB\Ddl\Table;
-use Magento\Tax\Api\Data\TaxClassInterface as TaxClass;
 use Magento\Tax\Api\TaxClassManagementInterface;
+use Magento\Tax\Model\ClassModel;
 
 /**
  * Product tax class source model.
@@ -68,7 +68,7 @@ class Product extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource
     {
         if (!$this->_options) {
             $filter = $this->_filterBuilder
-                ->setField(TaxClass::KEY_TYPE)
+                ->setField(ClassModel::KEY_TYPE)
                 ->setValue(TaxClassManagementInterface::TYPE_PRODUCT)
                 ->create();
             $searchCriteria = $this->_searchCriteriaBuilder->addFilter([$filter])->create();
diff --git a/app/code/Magento/Tax/Model/TaxDetails/AppliedTax.php b/app/code/Magento/Tax/Model/TaxDetails/AppliedTax.php
index 79265cacbc0c8615b0989d9deae57cb4ab6ee405..c5857168feddd83a0280449aadd5bc05c831838e 100644
--- a/app/code/Magento/Tax/Model/TaxDetails/AppliedTax.php
+++ b/app/code/Magento/Tax/Model/TaxDetails/AppliedTax.php
@@ -13,12 +13,21 @@ use Magento\Tax\Api\Data\AppliedTaxInterface;
  */
 class AppliedTax extends AbstractExtensibleModel implements AppliedTaxInterface
 {
+    /**#@+
+     * Constants defined for keys of array, makes typos less likely
+     */
+    const KEY_TAX_RATE_KEY = 'tax_rate_key';
+    const KEY_PERCENT      = 'percent';
+    const KEY_AMOUNT       = 'amount';
+    const KEY_RATES        = 'rates';
+    /**#@-*/
+
     /**
      * {@inheritdoc}
      */
     public function getTaxRateKey()
     {
-        return $this->getData(AppliedTaxInterface::KEY_TAX_RATE_KEY);
+        return $this->getData(self::KEY_TAX_RATE_KEY);
     }
 
     /**
@@ -26,7 +35,7 @@ class AppliedTax extends AbstractExtensibleModel implements AppliedTaxInterface
      */
     public function getPercent()
     {
-        return $this->getData(AppliedTaxInterface::KEY_PERCENT);
+        return $this->getData(self::KEY_PERCENT);
     }
 
     /**
@@ -34,7 +43,7 @@ class AppliedTax extends AbstractExtensibleModel implements AppliedTaxInterface
      */
     public function getAmount()
     {
-        return $this->getData(AppliedTaxInterface::KEY_AMOUNT);
+        return $this->getData(self::KEY_AMOUNT);
     }
 
     /**
@@ -42,7 +51,7 @@ class AppliedTax extends AbstractExtensibleModel implements AppliedTaxInterface
      */
     public function getRates()
     {
-        return $this->getData(AppliedTaxInterface::KEY_RATES);
+        return $this->getData(self::KEY_RATES);
     }
 
     /**
@@ -53,7 +62,7 @@ class AppliedTax extends AbstractExtensibleModel implements AppliedTaxInterface
      */
     public function setTaxRateKey($taxRateKey)
     {
-        return $this->setData(AppliedTaxInterface::KEY_TAX_RATE_KEY, $taxRateKey);
+        return $this->setData(self::KEY_TAX_RATE_KEY, $taxRateKey);
     }
 
     /**
@@ -64,7 +73,7 @@ class AppliedTax extends AbstractExtensibleModel implements AppliedTaxInterface
      */
     public function setPercent($percent)
     {
-        return $this->setData(AppliedTaxInterface::KEY_PERCENT, $percent);
+        return $this->setData(self::KEY_PERCENT, $percent);
     }
 
     /**
@@ -75,7 +84,7 @@ class AppliedTax extends AbstractExtensibleModel implements AppliedTaxInterface
      */
     public function setAmount($amount)
     {
-        return $this->setData(AppliedTaxInterface::KEY_AMOUNT, $amount);
+        return $this->setData(self::KEY_AMOUNT, $amount);
     }
 
     /**
@@ -86,7 +95,7 @@ class AppliedTax extends AbstractExtensibleModel implements AppliedTaxInterface
      */
     public function setRates(array $rates = null)
     {
-        return $this->setData(AppliedTaxInterface::KEY_RATES, $rates);
+        return $this->setData(self::KEY_RATES, $rates);
     }
 
     /**
diff --git a/app/code/Magento/Tax/Model/TaxDetails/AppliedTaxRate.php b/app/code/Magento/Tax/Model/TaxDetails/AppliedTaxRate.php
index 8cd44cb70e0e36de4ebe281b05e439e18be8312d..a04aed56a7f4a8b6224f628d9786d98a136821f3 100644
--- a/app/code/Magento/Tax/Model/TaxDetails/AppliedTaxRate.php
+++ b/app/code/Magento/Tax/Model/TaxDetails/AppliedTaxRate.php
@@ -13,12 +13,20 @@ use Magento\Tax\Api\Data\AppliedTaxRateInterface;
  */
 class AppliedTaxRate extends AbstractExtensibleModel implements AppliedTaxRateInterface
 {
+    /**#@+
+     * Constants defined for keys of array, makes typos less likely
+     */
+    const KEY_CODE    = 'code';
+    const KEY_TITLE   = 'title';
+    const KEY_PERCENT = 'percent';
+    /**#@-*/
+
     /**
      * {@inheritdoc}
      */
     public function getCode()
     {
-        return $this->getData(AppliedTaxRateInterface::KEY_CODE);
+        return $this->getData(self::KEY_CODE);
     }
 
     /**
@@ -26,7 +34,7 @@ class AppliedTaxRate extends AbstractExtensibleModel implements AppliedTaxRateIn
      */
     public function getTitle()
     {
-        return $this->getData(AppliedTaxRateInterface::KEY_TITLE);
+        return $this->getData(self::KEY_TITLE);
     }
 
     /**
@@ -34,7 +42,7 @@ class AppliedTaxRate extends AbstractExtensibleModel implements AppliedTaxRateIn
      */
     public function getPercent()
     {
-        return $this->getData(AppliedTaxRateInterface::KEY_PERCENT);
+        return $this->getData(self::KEY_PERCENT);
     }
 
     /**
@@ -45,7 +53,7 @@ class AppliedTaxRate extends AbstractExtensibleModel implements AppliedTaxRateIn
      */
     public function setCode($code)
     {
-        return $this->setData(AppliedTaxRateInterface::KEY_CODE, $code);
+        return $this->setData(self::KEY_CODE, $code);
     }
 
     /**
@@ -56,7 +64,7 @@ class AppliedTaxRate extends AbstractExtensibleModel implements AppliedTaxRateIn
      */
     public function setTitle($title)
     {
-        return $this->setData(AppliedTaxRateInterface::KEY_TITLE, $title);
+        return $this->setData(self::KEY_TITLE, $title);
     }
 
     /**
@@ -67,7 +75,7 @@ class AppliedTaxRate extends AbstractExtensibleModel implements AppliedTaxRateIn
      */
     public function setPercent($percent)
     {
-        return $this->setData(AppliedTaxRateInterface::KEY_PERCENT, $percent);
+        return $this->setData(self::KEY_PERCENT, $percent);
     }
 
     /**
diff --git a/app/code/Magento/Tax/Model/TaxDetails/ItemDetails.php b/app/code/Magento/Tax/Model/TaxDetails/ItemDetails.php
index 9ba71b43dedf1c2bf676436e6a3754e4f168d69f..d4f1628fbdbb8f4921e1162f01e23bd68aa94223 100644
--- a/app/code/Magento/Tax/Model/TaxDetails/ItemDetails.php
+++ b/app/code/Magento/Tax/Model/TaxDetails/ItemDetails.php
@@ -13,12 +13,30 @@ use Magento\Tax\Api\Data\TaxDetailsItemInterface;
  */
 class ItemDetails extends AbstractExtensibleModel implements TaxDetailsItemInterface
 {
+    /**#@+
+     * Constants defined for keys of array, makes typos less likely
+     */
+    const KEY_CODE                 = 'code';
+    const KEY_TYPE                 = 'type';
+    const KEY_TAX_PERCENT          = 'tax_percent';
+    const KEY_PRICE                = 'price';
+    const KEY_PRICE_INCL_TAX       = 'price_incl_tax';
+    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';
+    const KEY_DISCOUNT_AMOUNT      = 'discount_amount';
+    const KEY_APPLIED_TAXES        = 'applied_taxes';
+    const KEY_ASSOCIATED_ITEM_CODE = 'associated_item_code';
+    const KEY_DISCOUNT_TAX_COMPENSATION_AMOUNT = 'discount_tax_compensation_amount';
+    /**#@-*/
+
     /**
      * {@inheritdoc}
      */
     public function getCode()
     {
-        return $this->getData(TaxDetailsItemInterface::KEY_CODE);
+        return $this->getData(self::KEY_CODE);
     }
 
     /**
@@ -26,7 +44,7 @@ class ItemDetails extends AbstractExtensibleModel implements TaxDetailsItemInter
      */
     public function getType()
     {
-        return $this->getData(TaxDetailsItemInterface::KEY_TYPE);
+        return $this->getData(self::KEY_TYPE);
     }
 
     /**
@@ -34,7 +52,7 @@ class ItemDetails extends AbstractExtensibleModel implements TaxDetailsItemInter
      */
     public function getTaxPercent()
     {
-        return $this->getData(TaxDetailsItemInterface::KEY_TAX_PERCENT);
+        return $this->getData(self::KEY_TAX_PERCENT);
     }
 
     /**
@@ -42,7 +60,7 @@ class ItemDetails extends AbstractExtensibleModel implements TaxDetailsItemInter
      */
     public function getPrice()
     {
-        return $this->getData(TaxDetailsItemInterface::KEY_PRICE);
+        return $this->getData(self::KEY_PRICE);
     }
 
     /**
@@ -50,7 +68,7 @@ class ItemDetails extends AbstractExtensibleModel implements TaxDetailsItemInter
      */
     public function getPriceInclTax()
     {
-        return $this->getData(TaxDetailsItemInterface::KEY_PRICE_INCL_TAX);
+        return $this->getData(self::KEY_PRICE_INCL_TAX);
     }
 
     /**
@@ -58,7 +76,7 @@ class ItemDetails extends AbstractExtensibleModel implements TaxDetailsItemInter
      */
     public function getRowTotal()
     {
-        return $this->getData(TaxDetailsItemInterface::KEY_ROW_TOTAL);
+        return $this->getData(self::KEY_ROW_TOTAL);
     }
 
     /**
@@ -66,7 +84,7 @@ class ItemDetails extends AbstractExtensibleModel implements TaxDetailsItemInter
      */
     public function getRowTotalInclTax()
     {
-        return $this->getData(TaxDetailsItemInterface::KEY_ROW_TOTAL_INCL_TAX);
+        return $this->getData(self::KEY_ROW_TOTAL_INCL_TAX);
     }
 
     /**
@@ -74,7 +92,7 @@ class ItemDetails extends AbstractExtensibleModel implements TaxDetailsItemInter
      */
     public function getRowTax()
     {
-        return $this->getData(TaxDetailsItemInterface::KEY_ROW_TAX);
+        return $this->getData(self::KEY_ROW_TAX);
     }
 
     /**
@@ -82,7 +100,7 @@ class ItemDetails extends AbstractExtensibleModel implements TaxDetailsItemInter
      */
     public function getTaxableAmount()
     {
-        return $this->getData(TaxDetailsItemInterface::KEY_TAXABLE_AMOUNT);
+        return $this->getData(self::KEY_TAXABLE_AMOUNT);
     }
 
     /**
@@ -90,7 +108,7 @@ class ItemDetails extends AbstractExtensibleModel implements TaxDetailsItemInter
      */
     public function getDiscountAmount()
     {
-        return $this->getData(TaxDetailsItemInterface::KEY_DISCOUNT_AMOUNT);
+        return $this->getData(self::KEY_DISCOUNT_AMOUNT);
     }
 
     /**
@@ -98,7 +116,7 @@ class ItemDetails extends AbstractExtensibleModel implements TaxDetailsItemInter
      */
     public function getDiscountTaxCompensationAmount()
     {
-        return $this->getData(TaxDetailsItemInterface::KEY_DISCOUNT_TAX_COMPENSATION_AMOUNT);
+        return $this->getData(self::KEY_DISCOUNT_TAX_COMPENSATION_AMOUNT);
     }
 
     /**
@@ -106,7 +124,7 @@ class ItemDetails extends AbstractExtensibleModel implements TaxDetailsItemInter
      */
     public function getAppliedTaxes()
     {
-        return $this->getData(TaxDetailsItemInterface::KEY_APPLIED_TAXES);
+        return $this->getData(self::KEY_APPLIED_TAXES);
     }
 
     /**
@@ -114,7 +132,7 @@ class ItemDetails extends AbstractExtensibleModel implements TaxDetailsItemInter
      */
     public function getAssociatedItemCode()
     {
-        return $this->getData(TaxDetailsItemInterface::KEY_ASSOCIATED_ITEM_CODE);
+        return $this->getData(self::KEY_ASSOCIATED_ITEM_CODE);
     }
 
     /**
@@ -125,7 +143,7 @@ class ItemDetails extends AbstractExtensibleModel implements TaxDetailsItemInter
      */
     public function setCode($code)
     {
-        return $this->setData(TaxDetailsItemInterface::KEY_CODE, $code);
+        return $this->setData(self::KEY_CODE, $code);
     }
 
     /**
@@ -136,7 +154,7 @@ class ItemDetails extends AbstractExtensibleModel implements TaxDetailsItemInter
      */
     public function setType($type)
     {
-        return $this->setData(TaxDetailsItemInterface::KEY_TYPE, $type);
+        return $this->setData(self::KEY_TYPE, $type);
     }
 
     /**
@@ -147,7 +165,7 @@ class ItemDetails extends AbstractExtensibleModel implements TaxDetailsItemInter
      */
     public function setTaxPercent($taxPercent)
     {
-        return $this->setData(TaxDetailsItemInterface::KEY_TAX_PERCENT, $taxPercent);
+        return $this->setData(self::KEY_TAX_PERCENT, $taxPercent);
     }
 
     /**
@@ -158,7 +176,7 @@ class ItemDetails extends AbstractExtensibleModel implements TaxDetailsItemInter
      */
     public function setPrice($price)
     {
-        return $this->setData(TaxDetailsItemInterface::KEY_PRICE, $price);
+        return $this->setData(self::KEY_PRICE, $price);
     }
 
     /**
@@ -169,7 +187,7 @@ class ItemDetails extends AbstractExtensibleModel implements TaxDetailsItemInter
      */
     public function setPriceInclTax($priceInclTax)
     {
-        return $this->setData(TaxDetailsItemInterface::KEY_PRICE_INCL_TAX, $priceInclTax);
+        return $this->setData(self::KEY_PRICE_INCL_TAX, $priceInclTax);
     }
 
     /**
@@ -180,7 +198,7 @@ class ItemDetails extends AbstractExtensibleModel implements TaxDetailsItemInter
      */
     public function setRowTotal($rowTotal)
     {
-        return $this->setData(TaxDetailsItemInterface::KEY_ROW_TOTAL, $rowTotal);
+        return $this->setData(self::KEY_ROW_TOTAL, $rowTotal);
     }
 
     /**
@@ -191,7 +209,7 @@ class ItemDetails extends AbstractExtensibleModel implements TaxDetailsItemInter
      */
     public function setRowTotalInclTax($rowTotalInclTax)
     {
-        return $this->setData(TaxDetailsItemInterface::KEY_ROW_TOTAL_INCL_TAX, $rowTotalInclTax);
+        return $this->setData(self::KEY_ROW_TOTAL_INCL_TAX, $rowTotalInclTax);
     }
 
     /**
@@ -202,7 +220,7 @@ class ItemDetails extends AbstractExtensibleModel implements TaxDetailsItemInter
      */
     public function setRowTax($rowTax)
     {
-        return $this->setData(TaxDetailsItemInterface::KEY_ROW_TAX, $rowTax);
+        return $this->setData(self::KEY_ROW_TAX, $rowTax);
     }
 
     /**
@@ -213,7 +231,7 @@ class ItemDetails extends AbstractExtensibleModel implements TaxDetailsItemInter
      */
     public function setTaxableAmount($taxableAmount)
     {
-        return $this->setData(TaxDetailsItemInterface::KEY_TAXABLE_AMOUNT, $taxableAmount);
+        return $this->setData(self::KEY_TAXABLE_AMOUNT, $taxableAmount);
     }
 
     /**
@@ -224,7 +242,7 @@ class ItemDetails extends AbstractExtensibleModel implements TaxDetailsItemInter
      */
     public function setDiscountAmount($discountAmount)
     {
-        return $this->setData(TaxDetailsItemInterface::KEY_DISCOUNT_AMOUNT, $discountAmount);
+        return $this->setData(self::KEY_DISCOUNT_AMOUNT, $discountAmount);
     }
 
     /**
@@ -236,7 +254,7 @@ class ItemDetails extends AbstractExtensibleModel implements TaxDetailsItemInter
     public function setDiscountTaxCompensationAmount($discountTaxCompensationAmount)
     {
         return $this->setData(
-            TaxDetailsItemInterface::KEY_DISCOUNT_TAX_COMPENSATION_AMOUNT,
+            self::KEY_DISCOUNT_TAX_COMPENSATION_AMOUNT,
             $discountTaxCompensationAmount
         );
     }
@@ -249,7 +267,7 @@ class ItemDetails extends AbstractExtensibleModel implements TaxDetailsItemInter
      */
     public function setAppliedTaxes(array $appliedTaxes = null)
     {
-        return $this->setData(TaxDetailsItemInterface::KEY_APPLIED_TAXES, $appliedTaxes);
+        return $this->setData(self::KEY_APPLIED_TAXES, $appliedTaxes);
     }
 
     /**
@@ -260,7 +278,7 @@ class ItemDetails extends AbstractExtensibleModel implements TaxDetailsItemInter
      */
     public function setAssociatedItemCode($associatedItemCode)
     {
-        return $this->setData(TaxDetailsItemInterface::KEY_ASSOCIATED_ITEM_CODE, $associatedItemCode);
+        return $this->setData(self::KEY_ASSOCIATED_ITEM_CODE, $associatedItemCode);
     }
 
     /**
diff --git a/app/code/Magento/Tax/Model/TaxDetails/TaxDetails.php b/app/code/Magento/Tax/Model/TaxDetails/TaxDetails.php
index 91f1587c8b575ce08e5f52a0196c724f40917a36..721dedffeb29e43cb8433b1222e9e0059e8a4f7a 100644
--- a/app/code/Magento/Tax/Model/TaxDetails/TaxDetails.php
+++ b/app/code/Magento/Tax/Model/TaxDetails/TaxDetails.php
@@ -13,12 +13,22 @@ use Magento\Tax\Api\Data\TaxDetailsInterface;
  */
 class TaxDetails extends AbstractExtensibleModel implements TaxDetailsInterface
 {
+    /**#@+
+     * Constants defined for keys of array, makes typos less likely
+     */
+    const KEY_SUBTOTAL      = 'subtotal';
+    const KEY_TAX_AMOUNT    = 'tax_amount';
+    const KEY_APPLIED_TAXES = 'applied_taxes';
+    const KEY_ITEMS         = 'items';
+    const KEY_DISCOUNT_TAX_COMPENSATION_AMOUNT = 'discount_tax_compensation_amount';
+    /**#@-*/
+
     /**
      * {@inheritdoc}
      */
     public function getSubtotal()
     {
-        return $this->getData(TaxDetailsInterface::KEY_SUBTOTAL);
+        return $this->getData(self::KEY_SUBTOTAL);
     }
 
     /**
@@ -26,7 +36,7 @@ class TaxDetails extends AbstractExtensibleModel implements TaxDetailsInterface
      */
     public function getTaxAmount()
     {
-        return $this->getData(TaxDetailsInterface::KEY_TAX_AMOUNT);
+        return $this->getData(self::KEY_TAX_AMOUNT);
     }
 
     /**
@@ -34,7 +44,7 @@ class TaxDetails extends AbstractExtensibleModel implements TaxDetailsInterface
      */
     public function getDiscountTaxCompensationAmount()
     {
-        return $this->getData(TaxDetailsInterface::KEY_DISCOUNT_TAX_COMPENSATION_AMOUNT);
+        return $this->getData(self::KEY_DISCOUNT_TAX_COMPENSATION_AMOUNT);
     }
 
     /**
@@ -42,7 +52,7 @@ class TaxDetails extends AbstractExtensibleModel implements TaxDetailsInterface
      */
     public function getAppliedTaxes()
     {
-        return $this->getData(TaxDetailsInterface::KEY_APPLIED_TAXES);
+        return $this->getData(self::KEY_APPLIED_TAXES);
     }
 
     /**
@@ -50,7 +60,7 @@ class TaxDetails extends AbstractExtensibleModel implements TaxDetailsInterface
      */
     public function getItems()
     {
-        return $this->getData(TaxDetailsInterface::KEY_ITEMS);
+        return $this->getData(self::KEY_ITEMS);
     }
 
     /**
@@ -61,7 +71,7 @@ class TaxDetails extends AbstractExtensibleModel implements TaxDetailsInterface
      */
     public function setSubtotal($subtotal)
     {
-        return $this->setData(TaxDetailsInterface::KEY_SUBTOTAL, $subtotal);
+        return $this->setData(self::KEY_SUBTOTAL, $subtotal);
     }
 
     /**
@@ -72,7 +82,7 @@ class TaxDetails extends AbstractExtensibleModel implements TaxDetailsInterface
      */
     public function setTaxAmount($taxAmount)
     {
-        return $this->setData(TaxDetailsInterface::KEY_TAX_AMOUNT, $taxAmount);
+        return $this->setData(self::KEY_TAX_AMOUNT, $taxAmount);
     }
 
     /**
@@ -84,7 +94,7 @@ class TaxDetails extends AbstractExtensibleModel implements TaxDetailsInterface
     public function setDiscountTaxCompensationAmount($discountTaxCompensationAmount)
     {
         return $this->setData(
-            TaxDetailsInterface::KEY_DISCOUNT_TAX_COMPENSATION_AMOUNT,
+            self::KEY_DISCOUNT_TAX_COMPENSATION_AMOUNT,
             $discountTaxCompensationAmount
         );
     }
@@ -97,7 +107,7 @@ class TaxDetails extends AbstractExtensibleModel implements TaxDetailsInterface
      */
     public function setAppliedTaxes(array $appliedTaxes = null)
     {
-        return $this->setData(TaxDetailsInterface::KEY_APPLIED_TAXES, $appliedTaxes);
+        return $this->setData(self::KEY_APPLIED_TAXES, $appliedTaxes);
     }
 
     /**
@@ -108,7 +118,7 @@ class TaxDetails extends AbstractExtensibleModel implements TaxDetailsInterface
      */
     public function setItems(array $items = null)
     {
-        return $this->setData(TaxDetailsInterface::KEY_ITEMS, $items);
+        return $this->setData(self::KEY_ITEMS, $items);
     }
 
     /**
diff --git a/app/code/Magento/Tax/Test/Unit/Controller/Adminhtml/Rate/AjaxLoadTest.php b/app/code/Magento/Tax/Test/Unit/Controller/Adminhtml/Rate/AjaxLoadTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..6373e5aa514bf11a2d6174c78e64489bd7d558b0
--- /dev/null
+++ b/app/code/Magento/Tax/Test/Unit/Controller/Adminhtml/Rate/AjaxLoadTest.php
@@ -0,0 +1,238 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Tax\Test\Unit\Controller\Adminhtml\Rate;
+
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+use Magento\Framework\Exception\NoSuchEntityException;
+
+/**
+ * Test for AjaxLoadTest
+ */
+class AjaxLoadTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\App\Request\Http
+     */
+    private $request;
+
+    /**
+     * @var \Magento\Framework\App\Response\Http
+     */
+    private $resultFactory;
+
+    /**
+     * @var \Magento\Tax\Model\Calculation\RateRepository
+     */
+    private $taxRateRepository;
+
+    /*
+     * test setup
+     */
+    public function setUp()
+    {
+        $this->request = $this->getMockBuilder('\Magento\Framework\App\Request\Http')
+            ->disableOriginalConstructor()
+            ->setMethods(['getParam'])
+            ->getMock();
+
+        $this->resultFactory = $this->getMockBuilder('Magento\Framework\Controller\ResultFactory')
+            ->disableOriginalConstructor()
+            ->setMethods(['create'])
+            ->getMock();
+
+        $this->taxRateRepository = $this->getMockBuilder('\Magento\Tax\Model\Calculation\RateRepository')
+            ->disableOriginalConstructor()
+            ->setMethods(['get'])
+            ->getMock();
+    }
+
+    /**
+     * Executes the controller action and asserts non exception logic
+     */
+    public function testExecute()
+    {
+        $taxRateId=1;
+        $returnArray=[
+        'tax_calculation_rate_id' => null,
+                    'tax_country_id' => 'US',
+                    'tax_region_id' => 2,
+                    'tax_postcode' => null,
+                    'code' => 'Tax Rate Code',
+                    'rate' => 7.5,
+                    'zip_is_range'=> 0,
+                    'title[1]' => 'texas',
+                ];
+        $objectManager = new ObjectManager($this);
+        $rateTitles = [$objectManager->getObject(
+            '\Magento\Tax\Model\Calculation\Rate\Title',
+            ['data' => ['store_id' => 1, 'value' => 'texas']]
+        )
+        ];
+        $rateMock = $objectManager->getObject(
+            'Magento\Tax\Model\Calculation\Rate',
+            [
+                'data' =>
+                    [
+                        'tax_country_id' => 'US',
+                        'tax_region_id' => 2,
+                        'tax_postcode' => null,
+                        'rate' => 7.5,
+                        'code' => 'Tax Rate Code',
+                        'titles' => $rateTitles,
+                    ],
+            ]
+        );
+
+        $this->request->expects($this->any())
+            ->method('getParam')
+            ->will($this->returnValue($taxRateId));
+
+        $this->taxRateRepository->expects($this->any())
+            ->method('get')
+            ->with($taxRateId)
+            ->will($this->returnValue($rateMock));
+
+        $taxRateConverter = $this->getMockBuilder('\Magento\Tax\Model\Calculation\Rate\Converter')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $taxRateConverter->expects($this->any())
+            ->method('createArrayFromServiceObject')
+            ->with($rateMock, true)
+            ->willReturn($returnArray);
+
+        $jsonObject= $this->getMockBuilder('Magento\Framework\Controller\Result\Json')
+            ->disableOriginalConstructor()
+            ->setMethods(['setData'])
+            ->getMock();
+
+        $jsonObject->expects($this->once())
+            ->method('setData')
+            ->with(['success' => true, 'error_message' => '', 'result'=>
+                $returnArray,
+            ]);
+
+        $this->resultFactory->expects($this->any())
+            ->method('create')
+            ->with(\Magento\Framework\Controller\ResultFactory::TYPE_JSON)
+            ->willReturn($jsonObject);
+
+        $notification = $objectManager->getObject(
+            'Magento\Tax\Controller\Adminhtml\Rate\AjaxLoad',
+            [
+                'taxRateRepository' => $this->taxRateRepository,
+                'taxRateConverter' => $taxRateConverter,
+                'request' => $this->request,
+                'resultFactory' => $this->resultFactory,
+            ]
+        );
+
+
+        // No exception thrown
+        $this->assertSame($jsonObject, $notification->execute());
+
+    }
+
+    /**
+     * Check if validation throws a localized catched exception in case of incorrect id
+     */
+    public function testExecuteLocalizedException()
+    {
+        $taxRateId=999;
+        $exceptionMessage='No such entity with taxRateId = '.$taxRateId;
+        $noSuchEntityEx= new NoSuchEntityException(__($exceptionMessage));
+
+        $objectManager = new ObjectManager($this);
+
+        $this->request->expects($this->any())
+            ->method('getParam')
+            ->will($this->returnValue($taxRateId));
+
+        $this->taxRateRepository->expects($this->any())
+            ->method('get')
+            ->with($taxRateId)
+            ->willThrowException($noSuchEntityEx);
+
+        $jsonObject= $this->getMockBuilder('Magento\Framework\Controller\Result\Json')
+            ->disableOriginalConstructor()
+            ->setMethods(['setData'])
+            ->getMock();
+
+        $jsonObject->expects($this->once())
+            ->method('setData')
+            ->with([
+                'success' => false,
+                'error_message' => $exceptionMessage,
+            ]);
+
+        $this->resultFactory->expects($this->any())
+            ->method('create')
+            ->with(\Magento\Framework\Controller\ResultFactory::TYPE_JSON)
+            ->willReturn($jsonObject);
+
+        $notification = $objectManager->getObject(
+            'Magento\Tax\Controller\Adminhtml\Rate\AjaxLoad',
+            [
+                'taxRateRepository' => $this->taxRateRepository,
+                'request' => $this->request,
+                'resultFactory' => $this->resultFactory,
+            ]
+        );
+
+        //exception thrown with catch
+        $this->assertSame($jsonObject, $notification->execute());
+    }
+
+    /**
+     * Check if validation throws a localized catched exception in case of incorrect id
+     */
+    public function testExecuteException()
+    {
+        $taxRateId=999;
+        $exceptionMessage=__('An error occurred while loading this tax rate.');
+        $noSuchEntityEx= new \Exception();
+
+        $objectManager = new ObjectManager($this);
+
+        $this->request->expects($this->any())
+            ->method('getParam')
+            ->will($this->returnValue($taxRateId));
+
+        $this->taxRateRepository->expects($this->any())
+            ->method('get')
+            ->with($taxRateId)
+            ->willThrowException($noSuchEntityEx);
+
+        $jsonObject= $this->getMockBuilder('Magento\Framework\Controller\Result\Json')
+            ->disableOriginalConstructor()
+            ->setMethods(['setData'])
+            ->getMock();
+
+        $jsonObject->expects($this->once())
+            ->method('setData')
+            ->with([
+                'success' => false,
+                'error_message' => $exceptionMessage,
+            ]);
+
+        $this->resultFactory->expects($this->any())
+            ->method('create')
+            ->with(\Magento\Framework\Controller\ResultFactory::TYPE_JSON)
+            ->willReturn($jsonObject);
+
+        $notification = $objectManager->getObject(
+            'Magento\Tax\Controller\Adminhtml\Rate\AjaxLoad',
+            [
+                'taxRateRepository' => $this->taxRateRepository,
+                'request' => $this->request,
+                'resultFactory' => $this->resultFactory,
+            ]
+        );
+
+        //exception thrown with catch
+        $this->assertSame($jsonObject, $notification->execute());
+    }
+}
diff --git a/app/code/Magento/Tax/Test/Unit/Controller/Adminhtml/Tax/IgnoreTaxNotificationTest.php b/app/code/Magento/Tax/Test/Unit/Controller/Adminhtml/Tax/IgnoreTaxNotificationTest.php
index 9a649f3d2d5b9ca772e5b3df44d0ed1e69e27757..8714905efc56bc118efd516eb8346ec1e2045ad6 100644
--- a/app/code/Magento/Tax/Test/Unit/Controller/Adminhtml/Tax/IgnoreTaxNotificationTest.php
+++ b/app/code/Magento/Tax/Test/Unit/Controller/Adminhtml/Tax/IgnoreTaxNotificationTest.php
@@ -5,6 +5,7 @@
  */
 namespace Magento\Tax\Test\Unit\Controller\Adminhtml\Tax;
 
+use Magento\Framework\App\Config\ScopeConfigInterface;
 use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
 
 class IgnoreTaxNotificationTest extends \PHPUnit_Framework_TestCase
@@ -19,7 +20,7 @@ class IgnoreTaxNotificationTest extends \PHPUnit_Framework_TestCase
         $cacheTypeList->expects($this->once())
             ->method('cleanType')
             ->with('block_html')
-            ->will($this->returnValue(null));
+            ->willReturn(null);
 
         $request = $this->getMockBuilder('\Magento\Framework\App\Request\Http')
             ->disableOriginalConstructor()
@@ -27,12 +28,23 @@ class IgnoreTaxNotificationTest extends \PHPUnit_Framework_TestCase
             ->getMock();
         $request->expects($this->once())
             ->method('getParam')
-            ->will($this->returnValue('tax'));
+            ->willReturn('tax');
 
-        $response = $this->getMockBuilder('\Magento\Framework\App\Response\Http')
+        $resultRedirect = $this->getMockBuilder('Magento\Backend\Model\View\Result\Redirect')
             ->disableOriginalConstructor()
-            ->setMethods(['setRedirect'])
             ->getMock();
+        $resultRedirect->expects($this->once())
+            ->method('setRefererUrl')
+            ->willReturnSelf();
+
+        $resultFactory = $this->getMockBuilder('Magento\Framework\Controller\ResultFactory')
+            ->disableOriginalConstructor()
+            ->setMethods(['create'])
+            ->getMock();
+        $resultFactory->expects($this->once())
+            ->method('create')
+            ->with(\Magento\Framework\Controller\ResultFactory::TYPE_REDIRECT)
+            ->willReturn($resultRedirect);
 
         $config = $this->getMockBuilder('\Magento\Config\Model\Resource\Config')
             ->disableOriginalConstructor()
@@ -40,8 +52,8 @@ class IgnoreTaxNotificationTest extends \PHPUnit_Framework_TestCase
             ->getMock();
         $config->expects($this->once())
             ->method('saveConfig')
-            ->with('tax/notification/ignore_tax', 1, \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT, 0)
-            ->will($this->returnValue(null));
+            ->with('tax/notification/ignore_tax', 1, ScopeConfigInterface::SCOPE_TYPE_DEFAULT, 0)
+            ->willReturn(null);
 
         $manager = $this->getMockBuilder('\Magento\Framework\ObjectManagerInterface')
             ->disableOriginalConstructor()
@@ -49,7 +61,7 @@ class IgnoreTaxNotificationTest extends \PHPUnit_Framework_TestCase
             ->getMock();
         $manager->expects($this->any())
             ->method('get')
-            ->will($this->returnValue($config));
+            ->willReturn($config);
 
         $notification = $objectManager->getObject(
             'Magento\Tax\Controller\Adminhtml\Tax\IgnoreTaxNotification',
@@ -57,11 +69,11 @@ class IgnoreTaxNotificationTest extends \PHPUnit_Framework_TestCase
                 'objectManager' => $manager,
                 'cacheTypeList' => $cacheTypeList,
                 'request' => $request,
-                'response' => $response
+                'resultFactory' => $resultFactory
             ]
         );
 
         // No exception thrown
-        $notification->execute();
+        $this->assertSame($resultRedirect, $notification->execute());
     }
 }
diff --git a/app/code/Magento/Tax/Test/Unit/Model/Calculation/Rate/ConverterTest.php b/app/code/Magento/Tax/Test/Unit/Model/Calculation/Rate/ConverterTest.php
index 7fa4b63e75e603558c6a26fe028472552f58fd72..dc4dfcf84c4a377205e513c526e15c427018307c 100644
--- a/app/code/Magento/Tax/Test/Unit/Model/Calculation/Rate/ConverterTest.php
+++ b/app/code/Magento/Tax/Test/Unit/Model/Calculation/Rate/ConverterTest.php
@@ -5,7 +5,7 @@
  */
 namespace Magento\Tax\Test\Unit\Model\Calculation\Rate;
 
-use \Magento\Tax\Model\Calculation\Rate\Converter;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
 
 class ConverterTest extends \PHPUnit_Framework_TestCase
 {
@@ -14,9 +14,45 @@ class ConverterTest extends \PHPUnit_Framework_TestCase
      */
     protected $converter;
 
+    /**
+     * @var \Magento\Tax\Api\Data\TaxRateInterfaceFactory
+     */
+    protected $taxRateDataObjectFactory;
+
+    /**
+     * @var \Magento\Tax\Api\Data\TaxRateTitleInterfaceFactory
+     */
+    protected $taxRateTitleDataObjectFactory;
+
+    /**
+     * @var \Magento\Framework\TestFramework\Unit\Helper
+     */
+    protected $objectManager;
+
     public function setUp()
     {
-        $this->converter = new Converter();
+        $this->taxRateDataObjectFactory = $this->getMockBuilder(
+            '\Magento\Tax\Api\Data\TaxRateInterfaceFactory'
+        )
+            ->disableOriginalConstructor()
+            ->setMethods(['create'])
+            ->getMock();
+
+        $this->taxRateTitleDataObjectFactory = $this->getMockBuilder(
+            '\Magento\Tax\Api\Data\TaxRateTitleInterfaceFactory'
+        )
+            ->disableOriginalConstructor()
+            ->setMethods(['create'])
+            ->getMock();
+
+        $this->objectManager = new ObjectManager($this);
+        $this->converter =  $this->objectManager->getObject(
+            'Magento\Tax\Model\Calculation\Rate\Converter',
+            [
+                'taxRateDataObjectFactory' =>  $this->taxRateDataObjectFactory,
+                'taxRateTitleDataObjectFactory' => $this->taxRateTitleDataObjectFactory,
+            ]
+        );
     }
 
     public function testCreateTitlesFromServiceObject()
@@ -39,4 +75,48 @@ class ConverterTest extends \PHPUnit_Framework_TestCase
 
         $this->assertEquals([], $this->converter->createTitleArrayFromServiceObject($taxRateMock));
     }
+
+
+    public function testCreateArrayFromServiceObject()
+    {
+        $taxRateMock = $this->getMock('Magento\Tax\Api\Data\TaxRateInterface');
+        $titlesMock = $this->getMock('Magento\Tax\Api\Data\TaxRateTitleInterface');
+
+        $taxRateMock->expects($this->atLeastOnce())->method('getTitles')->willReturn([$titlesMock]);
+        $titlesMock->expects($this->atLeastOnce())->method('getStoreId')->willReturn(1);
+        $titlesMock->expects($this->atLeastOnce())->method('getValue')->willReturn('Value');
+
+        $this->assertArrayHasKey('title[1]', $this->converter->createArrayFromServiceObject($taxRateMock, true));
+        $this->assertArrayHasKey('title', $this->converter->createArrayFromServiceObject($taxRateMock));
+        $this->assertTrue(is_array($this->converter->createArrayFromServiceObject($taxRateMock)));
+    }
+
+    public function testPopulateTaxRateData()
+    {
+        $rateTitles = [$this->objectManager->getObject(
+            '\Magento\Tax\Model\Calculation\Rate\Title',
+            ['data' => ['store_id' => 1, 'value' => 'texas']]
+        )
+        ];
+        $dataArray=[
+            'tax_country_id' => 'US',
+            'tax_region_id' => 2,
+            'tax_postcode' => null,
+            'rate' => 7.5,
+            'code' => 'Tax Rate Code',
+            'titles' => $rateTitles,
+        ];
+
+        $taxRate = $this->objectManager->getObject(
+            'Magento\Tax\Model\Calculation\Rate',
+            [
+                'data' =>$dataArray,
+            ]
+        );
+
+        $this->taxRateDataObjectFactory->expects($this->once())->method('create')->willReturn($taxRate);
+
+        $this->assertSame($taxRate, $this->converter->populateTaxRateData($dataArray));
+        $this->assertEquals($taxRate->getTitles(), $rateTitles);
+    }
 }
diff --git a/app/code/Magento/Tax/Test/Unit/Model/TaxCalculationTest.php b/app/code/Magento/Tax/Test/Unit/Model/TaxCalculationTest.php
index f4bd04f1adf82bf8c77346c6ead678e85bb99f2c..d88ea2756c2e95330fc1a520c2d2a42c8744b259 100644
--- a/app/code/Magento/Tax/Test/Unit/Model/TaxCalculationTest.php
+++ b/app/code/Magento/Tax/Test/Unit/Model/TaxCalculationTest.php
@@ -199,11 +199,11 @@ class TaxCalculationTest extends \PHPUnit_Framework_TestCase
         $customerId = 100;
         $taxClassId = 200;
         $taxDetailsData = [
-            \Magento\Tax\Api\Data\TaxDetailsInterface::KEY_SUBTOTAL => 0.0,
-            \Magento\Tax\Api\Data\TaxDetailsInterface::KEY_TAX_AMOUNT => 0.0,
-            \Magento\Tax\Api\Data\TaxDetailsInterface::KEY_DISCOUNT_TAX_COMPENSATION_AMOUNT => 0.0,
-            \Magento\Tax\Api\Data\TaxDetailsInterface::KEY_APPLIED_TAXES => [],
-            \Magento\Tax\Api\Data\TaxDetailsInterface::KEY_ITEMS => [],
+            \Magento\Tax\Model\TaxDetails\TaxDetails::KEY_SUBTOTAL => 0.0,
+            \Magento\Tax\Model\TaxDetails\TaxDetails::KEY_TAX_AMOUNT => 0.0,
+            \Magento\Tax\Model\TaxDetails\TaxDetails::KEY_DISCOUNT_TAX_COMPENSATION_AMOUNT => 0.0,
+            \Magento\Tax\Model\TaxDetails\TaxDetails::KEY_APPLIED_TAXES => [],
+            \Magento\Tax\Model\TaxDetails\TaxDetails::KEY_ITEMS => [],
         ];
 
         $quoteDetailsMock = $this->getMock('\Magento\Tax\Api\Data\QuoteDetailsInterface');
diff --git a/app/code/Magento/Tax/Test/Unit/Model/TaxClass/ManagementTest.php b/app/code/Magento/Tax/Test/Unit/Model/TaxClass/ManagementTest.php
index 3ceefb565192b79193555b490f15d159f414024b..de391779d3ec915a2796f3404b84206c024cbdbb 100644
--- a/app/code/Magento/Tax/Test/Unit/Model/TaxClass/ManagementTest.php
+++ b/app/code/Magento/Tax/Test/Unit/Model/TaxClass/ManagementTest.php
@@ -79,8 +79,8 @@ class ManagementTest extends \PHPUnit_Framework_TestCase
             ->method('setField')
             ->with(
                 $this->logicalOr(
-                    \Magento\Tax\Api\Data\TaxClassInterface::KEY_TYPE,
-                    \Magento\Tax\Api\Data\TaxClassInterface::KEY_NAME
+                    \Magento\Tax\Model\ClassModel::KEY_TYPE,
+                    \Magento\Tax\Model\ClassModel::KEY_NAME
                 )
             )->willReturnSelf();
 
diff --git a/app/code/Magento/Tax/Test/Unit/Model/TaxClass/Source/CustomerTest.php b/app/code/Magento/Tax/Test/Unit/Model/TaxClass/Source/CustomerTest.php
index 6adec4612fe7b22e96f97bba7dd73119d4a4449c..c36618f8faf5c2a7cdc68b9aab3a16fbe274a5d9 100644
--- a/app/code/Magento/Tax/Test/Unit/Model/TaxClass/Source/CustomerTest.php
+++ b/app/code/Magento/Tax/Test/Unit/Model/TaxClass/Source/CustomerTest.php
@@ -120,7 +120,7 @@ class CustomerTest extends \PHPUnit_Framework_TestCase
 
         $this->filterBuilderMock->expects($this->once())
             ->method('setField')
-            ->with(\Magento\Tax\Api\Data\TaxClassInterface::KEY_TYPE)
+            ->with(\Magento\Tax\Model\ClassModel::KEY_TYPE)
             ->willReturnSelf();
         $this->filterBuilderMock->expects($this->once())
             ->method('setValue')
diff --git a/app/code/Magento/Tax/composer.json b/app/code/Magento/Tax/composer.json
index 27b9422635e75187471b290bb89d920fa9ccb1c5..dd35c3d1f65c9f9890e939efa1acbc2c5022fb64 100644
--- a/app/code/Magento/Tax/composer.json
+++ b/app/code/Magento/Tax/composer.json
@@ -3,23 +3,23 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-config": "0.74.0-beta6",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/module-customer": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-directory": "0.74.0-beta6",
-        "magento/module-checkout": "0.74.0-beta6",
-        "magento/module-shipping": "0.74.0-beta6",
-        "magento/module-eav": "0.74.0-beta6",
-        "magento/module-sales": "0.74.0-beta6",
-        "magento/module-reports": "0.74.0-beta6",
-        "magento/module-quote": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-config": "0.74.0-beta7",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/module-customer": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-directory": "0.74.0-beta7",
+        "magento/module-checkout": "0.74.0-beta7",
+        "magento/module-shipping": "0.74.0-beta7",
+        "magento/module-eav": "0.74.0-beta7",
+        "magento/module-sales": "0.74.0-beta7",
+        "magento/module-reports": "0.74.0-beta7",
+        "magento/module-quote": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Tax/view/adminhtml/templates/rule/edit.phtml b/app/code/Magento/Tax/view/adminhtml/templates/rule/edit.phtml
index e1941d06d1d4973744aa9e6cc415e282cc799780..4861e4b3bdc539fe555e6eefa3eaad39a489ecdb 100644
--- a/app/code/Magento/Tax/view/adminhtml/templates/rule/edit.phtml
+++ b/app/code/Magento/Tax/view/adminhtml/templates/rule/edit.phtml
@@ -73,16 +73,33 @@ require([
                 id = select.find('option').eq(index).attr('value'),
                 item;
 
-            for(var i = 0, c = taxRateCollection.length; i < c; i++) {
-                if (taxRateCollection[i].tax_calculation_rate_id == id) {
-                    item = taxRateCollection[i];
-                    break;
-                }
-            }
-            item.itemElement = that.prev();
-            $('#tax-rate-form')
-                    .dialogRates({itemRate: item})
-                    .dialogRates('open');
+            $('body').trigger('processStart')
+            $.ajax({
+                type: "POST",
+                data: {id:id},
+                url: '<?php echo $block->getTaxRateLoadUrl()?>',
+                success: function(result, status) {
+                    $('body').trigger('processStop');
+                    if (result.success) {
+                        item=result.result;
+                        item.itemElement = that.prev();
+                        $('#tax-rate-form')
+                            .dialogRates({itemRate: item})
+                            .dialogRates('open');
+
+                    } else {
+                        if (result.error_message)
+                            alert(result.error_message);
+                        else
+                            alert('<?php echo __('An error occurred'); ?>');
+                    }
+                },
+                error: function () {
+                    $('body').trigger('processStop');
+                    alert('<?php echo __('An error occurred'); ?>');
+                },
+                dataType: "json"
+            });
         };
 
         TaxRateEditableMultiselect.prototype.init = function () {
@@ -142,6 +159,7 @@ require([
                                 index = that.parent().index(),
                                 select = that.closest('.mselect-list').prev();
 
+                        $('body').trigger('processStart')
                         var ajaxOptions = {
                             type: 'POST',
                             data: {
@@ -151,12 +169,20 @@ require([
                             dataType: 'json',
                             url: '<?php echo $block->getTaxRateDeleteUrl()?>',
                             success: function(result, status) {
+                                $('body').trigger('processStop');
                                 if (result.success) {
                                     that.parent().remove();
                                     select.find('option').eq(index).remove();
                                 } else {
-                                    alert(result.error_message);
+                                    if (result.error_message)
+                                        alert(result.error_message);
+                                    else
+                                        alert('<?php echo __('An error occurred'); ?>');
                                 }
+                            },
+                            error: function () {
+                                $('body').trigger('processStop');
+                                alert('<?php echo __('An error occurred'); ?>');
                             }
                         };
                         $.ajax(ajaxOptions);
@@ -215,13 +241,15 @@ require([
                         if (!taxRateFormElement.validation().valid()) {
                             return;
                         }
-
+                        $('.tax-rate-popup').trigger('processStart');
+                        $('.loading-mask').css('z-index','1004');
                         var ajaxOptions = {
                             type: 'POST',
                             data: itemRateData,
                             dataType: 'json',
                             url: '<?php echo $block->getTaxRateSaveUrl()?>',
                             success: function(result, status) {
+                                $('body').trigger('processStop');
                                 if (result.success) {
                                     itemRate.code = result.code;
                                     if (itemRate.tax_calculation_rate_id) {
@@ -238,10 +266,16 @@ require([
                                             .val(itemRate.tax_calculation_rate_id);
                                     }
                                     taxRateForm.dialogRates("close");
-                                    taxRateCollection.push(itemRate);
                                 } else {
-                                    alert(result.error_message);
+                                    if (result.error_message)
+                                        alert(result.error_message);
+                                    else
+                                        alert('<?php echo __('An error occurred'); ?>');
                                 }
+                            },
+                            error: function () {
+                                $('body').trigger('processStop');
+                                alert('<?php echo __('An error occurred'); ?>');
                             }
                         };
                         $.ajax(ajaxOptions);
@@ -256,6 +290,7 @@ require([
                     }
                 }]
             });
+            $('.grid-loading-mask').hide();
         }
     };
 
diff --git a/app/code/Magento/Tax/view/adminhtml/templates/rule/rate/form.phtml b/app/code/Magento/Tax/view/adminhtml/templates/rule/rate/form.phtml
index eae01d9d0b302c71017afb3571349eb82bcc6043..d5c0d8aee3b6a8f84af22f3fd90f2c2afde1f0f5 100644
--- a/app/code/Magento/Tax/view/adminhtml/templates/rule/rate/form.phtml
+++ b/app/code/Magento/Tax/view/adminhtml/templates/rule/rate/form.phtml
@@ -5,14 +5,13 @@
  */
 /* @var $block \Magento\Tax\Block\Adminhtml\Rate\Form */
 ?>
+
+<div data-role="spinner" class="grid-loading-mask">
+    <div class="grid-loader"></div>
+</div>
+
 <div class="form-inline" id="<?php echo $block->getNameInLayout() ?>" style="display:none">
     <?php echo $block->getFormHtml();?>
     <?php echo $block->getChildHtml('form_after');?>
 </div>
 
-<script>
-
-
-    var taxRateCollection = <?php echo json_encode($block->getRateCollection());?>;
-
-</script>
diff --git a/app/code/Magento/TaxImportExport/Controller/Adminhtml/Rate/ExportCsv.php b/app/code/Magento/TaxImportExport/Controller/Adminhtml/Rate/ExportCsv.php
index c49fc0c8e92594c5db3669c027bf282053fd4293..9f6f1cb8e6beeb2f860b824759c3a019cb1612eb 100644
--- a/app/code/Magento/TaxImportExport/Controller/Adminhtml/Rate/ExportCsv.php
+++ b/app/code/Magento/TaxImportExport/Controller/Adminhtml/Rate/ExportCsv.php
@@ -1,6 +1,5 @@
 <?php
 /**
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
@@ -8,6 +7,7 @@ namespace Magento\TaxImportExport\Controller\Adminhtml\Rate;
 
 use Magento\Framework\App\ResponseInterface;
 use Magento\Framework\App\Filesystem\DirectoryList;
+use Magento\Framework\Controller\ResultFactory;
 
 class ExportCsv extends \Magento\TaxImportExport\Controller\Adminhtml\Rate
 {
@@ -18,8 +18,10 @@ class ExportCsv extends \Magento\TaxImportExport\Controller\Adminhtml\Rate
      */
     public function execute()
     {
-        $this->_view->loadLayout(false);
-        $content = $this->_view->getLayout()->getChildBlock('adminhtml.tax.rate.grid', 'grid.export');
+        /** @var \Magento\Framework\View\Result\Layout $resultLayout */
+        $resultLayout = $this->resultFactory->create(ResultFactory::TYPE_LAYOUT);
+        $content = $resultLayout->getLayout()->getChildBlock('adminhtml.tax.rate.grid', 'grid.export');
+
         return $this->fileFactory->create(
             'rates.csv',
             $content->getCsvFile(),
diff --git a/app/code/Magento/TaxImportExport/Controller/Adminhtml/Rate/ExportPost.php b/app/code/Magento/TaxImportExport/Controller/Adminhtml/Rate/ExportPost.php
index f698f7cbe655353dda0a808d032fa58f9f7e5b2a..1d5685802882b5ed3703222f7318511712493605 100644
--- a/app/code/Magento/TaxImportExport/Controller/Adminhtml/Rate/ExportPost.php
+++ b/app/code/Magento/TaxImportExport/Controller/Adminhtml/Rate/ExportPost.php
@@ -1,6 +1,5 @@
 <?php
 /**
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
@@ -12,7 +11,7 @@ use Magento\Framework\App\Filesystem\DirectoryList;
 class ExportPost extends \Magento\TaxImportExport\Controller\Adminhtml\Rate
 {
     /**
-     * export action from import/export tax
+     * Export action from import/export tax
      *
      * @return ResponseInterface
      */
@@ -82,7 +81,6 @@ class ExportPost extends \Magento\TaxImportExport\Controller\Adminhtml\Rate
 
             $content .= $rate->toString($template) . "\n";
         }
-        $this->_view->loadLayout();
         return $this->fileFactory->create('tax_rates.csv', $content, DirectoryList::VAR_DIR);
     }
 }
diff --git a/app/code/Magento/TaxImportExport/Controller/Adminhtml/Rate/ExportXml.php b/app/code/Magento/TaxImportExport/Controller/Adminhtml/Rate/ExportXml.php
index 0ec4688e5d52e2bff1b45e3263fd3b14b8e5e3f5..38fc277576cc673254f8a0fc2dfe8d47439fa7a6 100644
--- a/app/code/Magento/TaxImportExport/Controller/Adminhtml/Rate/ExportXml.php
+++ b/app/code/Magento/TaxImportExport/Controller/Adminhtml/Rate/ExportXml.php
@@ -1,6 +1,5 @@
 <?php
 /**
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
@@ -8,6 +7,7 @@ namespace Magento\TaxImportExport\Controller\Adminhtml\Rate;
 
 use Magento\Framework\App\ResponseInterface;
 use Magento\Framework\App\Filesystem\DirectoryList;
+use Magento\Framework\Controller\ResultFactory;
 
 class ExportXml extends \Magento\TaxImportExport\Controller\Adminhtml\Rate
 {
@@ -18,8 +18,10 @@ class ExportXml extends \Magento\TaxImportExport\Controller\Adminhtml\Rate
      */
     public function execute()
     {
-        $this->_view->loadLayout(false);
-        $content = $this->_view->getLayout()->getChildBlock('adminhtml.tax.rate.grid', 'grid.export');
+        /** @var \Magento\Framework\View\Result\Layout $resultLayout */
+        $resultLayout = $this->resultFactory->create(ResultFactory::TYPE_LAYOUT);
+        $content = $resultLayout->getLayout()->getChildBlock('adminhtml.tax.rate.grid', 'grid.export');
+
         return $this->fileFactory->create(
             'rates.xml',
             $content->getExcelFile(),
diff --git a/app/code/Magento/TaxImportExport/Controller/Adminhtml/Rate/ImportExport.php b/app/code/Magento/TaxImportExport/Controller/Adminhtml/Rate/ImportExport.php
index ca34dd5197a7e941692bf263224bf094f08066ab..5ba0b3e87da0e7727e89aa3747d34916e2d0123a 100644
--- a/app/code/Magento/TaxImportExport/Controller/Adminhtml/Rate/ImportExport.php
+++ b/app/code/Magento/TaxImportExport/Controller/Adminhtml/Rate/ImportExport.php
@@ -1,30 +1,33 @@
 <?php
 /**
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
 namespace Magento\TaxImportExport\Controller\Adminhtml\Rate;
 
+use Magento\Framework\Controller\ResultFactory;
+
 class ImportExport extends \Magento\TaxImportExport\Controller\Adminhtml\Rate
 {
     /**
      * Import and export Page
      *
-     * @return void
+     * @return \Magento\Backend\Model\View\Result\Page
      */
     public function execute()
     {
-        $this->_view->loadLayout();
-        $this->_setActiveMenu(
-            'Magento_TaxImportExport::system_convert_tax'
-        )->_addContent(
-            $this->_view->getLayout()->createBlock('Magento\TaxImportExport\Block\Adminhtml\Rate\ImportExportHeader')
-        )->_addContent(
-            $this->_view->getLayout()->createBlock('Magento\TaxImportExport\Block\Adminhtml\Rate\ImportExport')
+        /** @var \Magento\Backend\Model\View\Result\Page $resultPage */
+        $resultPage = $this->resultFactory->create(ResultFactory::TYPE_PAGE);
+
+        $resultPage->setActiveMenu('Magento_TaxImportExport::system_convert_tax');
+        $resultPage->addContent(
+            $resultPage->getLayout()->createBlock('Magento\TaxImportExport\Block\Adminhtml\Rate\ImportExportHeader')
+        );
+        $resultPage->addContent(
+            $resultPage->getLayout()->createBlock('Magento\TaxImportExport\Block\Adminhtml\Rate\ImportExport')
         );
-        $this->_view->getPage()->getConfig()->getTitle()->prepend(__('Tax Zones and Rates'));
-        $this->_view->getPage()->getConfig()->getTitle()->prepend(__('Import and Export Tax Rates'));
-        $this->_view->renderLayout();
+        $resultPage->getConfig()->getTitle()->prepend(__('Tax Zones and Rates'));
+        $resultPage->getConfig()->getTitle()->prepend(__('Import and Export Tax Rates'));
+        return $resultPage;
     }
 }
diff --git a/app/code/Magento/TaxImportExport/Controller/Adminhtml/Rate/ImportPost.php b/app/code/Magento/TaxImportExport/Controller/Adminhtml/Rate/ImportPost.php
index d072f6b82b28acb85e661f9b30776509601eaf92..663a0183b1e86cba8e888c9a9b194e24e99c9519 100644
--- a/app/code/Magento/TaxImportExport/Controller/Adminhtml/Rate/ImportPost.php
+++ b/app/code/Magento/TaxImportExport/Controller/Adminhtml/Rate/ImportPost.php
@@ -1,17 +1,18 @@
 <?php
 /**
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
 namespace Magento\TaxImportExport\Controller\Adminhtml\Rate;
 
+use Magento\Framework\Controller\ResultFactory;
+
 class ImportPost extends \Magento\TaxImportExport\Controller\Adminhtml\Rate
 {
     /**
      * import action from import/export tax
      *
-     * @return void
+     * @return \Magento\Backend\Model\View\Result\Redirect
      */
     public function execute()
     {
@@ -30,6 +31,9 @@ class ImportPost extends \Magento\TaxImportExport\Controller\Adminhtml\Rate
         } else {
             $this->messageManager->addError(__('Invalid file upload attempt'));
         }
-        $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($this->getUrl('*')));
+        /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
+        $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
+        $resultRedirect->setUrl($this->_redirect->getRedirectUrl());
+        return $resultRedirect;
     }
 }
diff --git a/app/code/Magento/TaxImportExport/composer.json b/app/code/Magento/TaxImportExport/composer.json
index 334b8652a6d74ed73e037f5d001b62026444bac6..fd4d50bebb33888f1c8593d8772cca8af776b430 100644
--- a/app/code/Magento/TaxImportExport/composer.json
+++ b/app/code/Magento/TaxImportExport/composer.json
@@ -3,15 +3,15 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-tax": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-directory": "0.74.0-beta6",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-tax": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-directory": "0.74.0-beta7",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Theme/Model/Config.php b/app/code/Magento/Theme/Model/Config.php
index 5993e9bf010d5586384e03bdc4df50010f882547..39332cc9a0b7b7705db033cb7996e0fd3c482e90 100644
--- a/app/code/Magento/Theme/Model/Config.php
+++ b/app/code/Magento/Theme/Model/Config.php
@@ -9,6 +9,8 @@
  */
 namespace Magento\Theme\Model;
 
+use Magento\Framework\App\Config\ScopeConfigInterface;
+
 class Config
 {
     /**
@@ -173,7 +175,7 @@ class Config
     protected function _assignThemeToDefaultScope($themeId, &$isReassigned)
     {
         $configPath = \Magento\Framework\View\DesignInterface::XML_PATH_THEME_ID;
-        $this->_configWriter->save($configPath, $themeId, \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT);
+        $this->_configWriter->save($configPath, $themeId, ScopeConfigInterface::SCOPE_TYPE_DEFAULT);
         $isReassigned = true;
         return $this;
     }
diff --git a/app/code/Magento/Theme/Model/View/Design.php b/app/code/Magento/Theme/Model/View/Design.php
index f839d6ba900f71e2998634aa9e36776bcd863105..f0cf795f6b4482b9c8ac59bc444e62f4af24f14c 100644
--- a/app/code/Magento/Theme/Model/View/Design.php
+++ b/app/code/Magento/Theme/Model/View/Design.php
@@ -6,6 +6,8 @@
 
 namespace Magento\Theme\Model\View;
 
+use Magento\Framework\App\Config\ScopeConfigInterface;
+
 /**
  * Keeps design settings for current request
  */
@@ -167,7 +169,7 @@ class Design implements \Magento\Framework\View\DesignInterface
             if ($this->_storeManager->isSingleStoreMode()) {
                 $theme = $this->_scopeConfig->getValue(
                     self::XML_PATH_THEME_ID,
-                    \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT
+                    ScopeConfigInterface::SCOPE_TYPE_DEFAULT
                 );
             } else {
                 $theme = (string) $this->_scopeConfig->getValue(
diff --git a/app/code/Magento/Theme/composer.json b/app/code/Magento/Theme/composer.json
index cb64d49d6d2dae6c61f64b767b8fa2f2a895544f..fd23ba6ec42b957d3ff80683883ca990f4d9e14c 100644
--- a/app/code/Magento/Theme/composer.json
+++ b/app/code/Magento/Theme/composer.json
@@ -3,23 +3,23 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-customer": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-cms": "0.74.0-beta6",
-        "magento/module-eav": "0.74.0-beta6",
-        "magento/module-widget": "0.74.0-beta6",
-        "magento/module-config": "0.74.0-beta6",
-        "magento/module-media-storage": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
-        "magento/module-require-js": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-customer": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-cms": "0.74.0-beta7",
+        "magento/module-eav": "0.74.0-beta7",
+        "magento/module-widget": "0.74.0-beta7",
+        "magento/module-config": "0.74.0-beta7",
+        "magento/module-media-storage": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
+        "magento/module-require-js": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "suggest": {
-        "magento/module-translation": "0.74.0-beta6"
+        "magento/module-translation": "0.74.0-beta7"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Theme/view/adminhtml/requirejs-config.js b/app/code/Magento/Theme/view/adminhtml/requirejs-config.js
index 1c0d89ba473ef4811fe74cd4426863369b99dea8..0cc7098574c9d120f5235644bdf74ded7d9c82b2 100644
--- a/app/code/Magento/Theme/view/adminhtml/requirejs-config.js
+++ b/app/code/Magento/Theme/view/adminhtml/requirejs-config.js
@@ -5,6 +5,9 @@
 
 var config = {
     "shim": {
+        "extjs/ext-tree": [
+            "prototype"
+        ],
         "extjs/ext-tree-checkbox": [
             "extjs/ext-tree",
             "extjs/defaults"
@@ -46,7 +49,8 @@ var config = {
     },
     "deps": [
         "js/theme",
-        "mage/backend/bootstrap"
+        "mage/backend/bootstrap",
+        "mage/adminhtml/globals"
     ],
     "paths": {
         "jquery/ui": "jquery/jquery-ui-1.9.2"
diff --git a/app/code/Magento/Theme/view/base/requirejs-config.js b/app/code/Magento/Theme/view/base/requirejs-config.js
index 637568a9c357ce6fe69cc80017903ec2e6e6e5a8..58dbd2b841a664e48e1cf98ba8d6bf73a5d40189 100644
--- a/app/code/Magento/Theme/view/base/requirejs-config.js
+++ b/app/code/Magento/Theme/view/base/requirejs-config.js
@@ -5,6 +5,11 @@
 
 var config = {
     "waitSeconds": 0,
+    "map": {
+        "*": {
+            "mageUtils": "mage/utils/main"
+        }
+    },
     "shim": {
         "jquery/jquery-migrate": ["jquery"],
         "jquery/jquery.hashchange": ["jquery", "jquery/jquery-migrate"],
diff --git a/app/code/Magento/Translation/composer.json b/app/code/Magento/Translation/composer.json
index 4b817066e92d7a9cccc5efbc1d2909409c383f0a..4a91a1055361628c26e0dd6c961f26925cc699c2 100644
--- a/app/code/Magento/Translation/composer.json
+++ b/app/code/Magento/Translation/composer.json
@@ -3,15 +3,15 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-developer": "0.74.0-beta6",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-theme": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-developer": "0.74.0-beta7",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-theme": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Ui/Component/AbstractComponent.php b/app/code/Magento/Ui/Component/AbstractComponent.php
new file mode 100644
index 0000000000000000000000000000000000000000..152b025cfc003da954e17ad9688db719d213cb37
--- /dev/null
+++ b/app/code/Magento/Ui/Component/AbstractComponent.php
@@ -0,0 +1,261 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\Component;
+
+use Magento\Framework\Object;
+use Magento\Framework\View\Element\UiComponentInterface;
+use Magento\Framework\View\Element\UiComponent\ContextInterface;
+use Magento\Framework\View\Element\UiComponent\JsConfigInterface;
+use Magento\Framework\View\Element\UiComponent\DataSourceInterface;
+
+/**
+ * Abstract class AbstractComponent
+ * @SuppressWarnings(PHPMD.NumberOfChildren)
+ */
+abstract class AbstractComponent extends Object implements UiComponentInterface, JsConfigInterface
+{
+    /**
+     * Render context
+     *
+     * @var ContextInterface
+     */
+    protected $context;
+
+    /**
+     * @var UiComponentInterface[]
+     */
+    protected $components;
+
+    /**
+     * @var array
+     */
+    protected $componentData = [];
+
+    /**
+     * Constructor
+     *
+     * @param ContextInterface $context
+     * @param UiComponentInterface[] $components
+     * @param array $data
+     */
+    public function __construct(
+        ContextInterface $context,
+        array $components = [],
+        array $data = []
+    ) {
+        $this->context = $context;
+        $this->components = $components;
+        parent::__construct($data);
+    }
+
+    /**
+     * Get component context
+     *
+     * @return ContextInterface
+     */
+    public function getContext()
+    {
+        return $this->context;
+    }
+
+    /**
+     * Prepare component configuration
+     *
+     * @return void
+     */
+    public function prepare()
+    {
+        //
+    }
+
+    /**
+     * Produce and return block's html output
+     *
+     * @return string
+     */
+    public function toHtml()
+    {
+        $this->render();
+    }
+
+    /**
+     * Render component
+     *
+     * @return string
+     */
+    public function render()
+    {
+        $result = $this->getContext()->getRenderEngine()->render($this, $this->getTemplate());
+        return $result;
+    }
+
+    /**
+     * Get component name
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return $this->getData('name');
+    }
+
+    /**
+     * Add component
+     *
+     * @param string $name
+     * @param UiComponentInterface $component
+     * @return void
+     */
+    public function addComponent($name, UiComponentInterface $component)
+    {
+        $this->components[$name] = $component;
+    }
+
+    /**
+     * @param string $name
+     * @return UiComponentInterface
+     */
+    public function getComponent($name)
+    {
+        return isset($this->components[$name]) ? $this->components[$name] : null;
+    }
+
+    /**
+     * Get components
+     *
+     * @return UiComponentInterface[]
+     */
+    public function getChildComponents()
+    {
+        return $this->components;
+    }
+
+    /**
+     * Get template
+     *
+     * @return string
+     */
+    public function getTemplate()
+    {
+        return $this->getData('template') . '.xhtml';
+    }
+
+    /**
+     * Render child component
+     *
+     * @param string $name
+     * @return string
+     */
+    public function renderChildComponent($name)
+    {
+        $result = null;
+        if (isset($this->components[$name])) {
+            $result = $this->components[$name]->render();
+        }
+        return $result;
+    }
+
+    /**
+     * Component data setter
+     *
+     * @param string|array $key
+     * @param mixed $value
+     * @return void
+     */
+    public function setData($key, $value = null)
+    {
+        parent::setData($key, $value);
+    }
+
+    /**
+     * Component data getter
+     *
+     * @param string $key
+     * @param string|int $index
+     * @return mixed
+     */
+    public function getData($key = '', $index = null)
+    {
+        return parent::getData($key, $index);
+    }
+
+    /**
+     * Set component configuration
+     *
+     * @return void
+     */
+    protected function prepareConfiguration()
+    {
+        $config = $this->getDefaultConfiguration();
+        if ($this->hasData('config')) {
+            $config = array_replace_recursive($config, $this->getData('config'));
+        }
+
+        $this->setData('config', $config);
+    }
+
+    /**
+     * Get default parameters
+     *
+     * @return array
+     */
+    protected function getDefaultConfiguration()
+    {
+        return [];
+    }
+
+    /**
+     * Get JS configuration
+     *
+     * @param UiComponentInterface $component
+     * @param null|string $extends
+     * @return array
+     */
+    protected function getConfiguration(UiComponentInterface $component, $extends = null)
+    {
+        $jsConfig = (array) $component->getData('js_config');
+        if (isset($jsConfig['extends'])) {
+            return $jsConfig;
+        } else if (null !== $extends) {
+            $jsConfig['extends'] = $extends;
+        } else {
+            $jsConfig['extends'] = $component->getContext()->getNamespace();
+        }
+
+        return $jsConfig;
+    }
+
+    /**
+     * Get JS config
+     *
+     * @return array|string
+     */
+    public function getJsConfig()
+    {
+        return (array) $this->getData('config');
+    }
+
+    /**
+     * @return array
+     */
+    public function getDataSourceData()
+    {
+        $dataSources = [];
+        foreach ($this->getChildComponents() as $component) {
+            if ($component instanceof DataSourceInterface) {
+                $dataSources[] = [
+                    'type' => $component->getComponentName(),
+                    'name' => $component->getName(),
+                    'dataScope' => $component->getContext()->getNamespace(),
+                    'config' => [
+                        'data' => $component->getDataProvider()->getData()
+                    ]
+                ];
+            }
+        }
+        return $dataSources;
+    }
+}
diff --git a/app/code/Magento/Ui/Component/AbstractView.php b/app/code/Magento/Ui/Component/AbstractView.php
deleted file mode 100644
index e67d0e1ff40ee6b3182c77bebb844c143fa8a84c..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/Component/AbstractView.php
+++ /dev/null
@@ -1,375 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\Component;
-
-use Magento\Framework\View\Asset\Repository;
-use Magento\Framework\View\Element\Template;
-use Magento\Framework\View\Element\Template\Context as TemplateContext;
-use Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface;
-use Magento\Framework\View\Element\UiComponent\ConfigFactory;
-use Magento\Framework\View\Element\UiComponent\ConfigInterface;
-use Magento\Framework\View\Element\UiComponent\Context;
-use Magento\Framework\View\Element\UiComponentInterface;
-use Magento\Ui\ContentType\ContentTypeFactory;
-use Magento\Ui\DataProvider\Factory as DataProviderFactory;
-use Magento\Ui\DataProvider\Manager;
-
-/**
- * Abstract class AbstractView
- * @SuppressWarnings(PHPMD.NumberOfChildren)
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
- */
-abstract class AbstractView extends Template implements UiComponentInterface
-{
-    /**
-     * Config builder
-     *
-     * @var ConfigBuilderInterface
-     */
-    protected $configBuilder;
-
-    /**
-     * View configuration data
-     *
-     * @var ConfigInterface
-     */
-    protected $config;
-
-    /**
-     * Render context
-     *
-     * @var Context
-     */
-    protected $renderContext;
-
-    /**
-     * Config factory
-     *
-     * @var ConfigFactory
-     */
-    protected $configFactory;
-
-    /**
-     * Content type factory
-     *
-     * @var ContentTypeFactory
-     */
-    protected $contentTypeFactory;
-
-    /**
-     * Asset service
-     *
-     * @var Repository
-     */
-    protected $assetRepo;
-
-    /**
-     * Data provider factory
-     *
-     * @var DataProviderFactory
-     */
-    protected $dataProviderFactory;
-
-    /**
-     * @var \Magento\Ui\DataProvider\Manager
-     */
-    protected $dataManager;
-
-    /**
-     * Elements for the render
-     *
-     * @var ElementRendererInterface[]
-     */
-    protected $elements = [];
-
-    /**
-     * Constructor
-     *
-     * @param TemplateContext $context
-     * @param Context $renderContext
-     * @param ContentTypeFactory $contentTypeFactory
-     * @param ConfigFactory $configFactory
-     * @param ConfigBuilderInterface $configBuilder
-     * @param DataProviderFactory $dataProviderFactory
-     * @param Manager $dataProviderManager
-     * @param array $data
-     */
-    public function __construct(
-        TemplateContext $context,
-        Context $renderContext,
-        ContentTypeFactory $contentTypeFactory,
-        ConfigFactory $configFactory,
-        ConfigBuilderInterface $configBuilder,
-        DataProviderFactory $dataProviderFactory,
-        Manager $dataProviderManager,
-        array $data = []
-    ) {
-        $this->renderContext = $renderContext;
-        $this->contentTypeFactory = $contentTypeFactory;
-        $this->assetRepo = $context->getAssetRepository();
-        $this->configFactory = $configFactory;
-        $this->configBuilder = $configBuilder;
-        $this->dataProviderFactory = $dataProviderFactory;
-        $this->dataManager = $dataProviderManager;
-        parent::__construct($context, $data);
-    }
-
-    /**
-     * Update data
-     *
-     * @param array $data
-     * @return void
-     */
-    public function update(array $data = [])
-    {
-        if (!empty($data)) {
-            $this->_data = array_merge_recursive($this->_data, $data);
-        }
-    }
-
-    /**
-     * Prepare component data
-     *
-     * @return void
-     */
-    public function prepare()
-    {
-        //
-    }
-
-    /**
-     * Render content
-     *
-     * @param array $data
-     * @return string
-     */
-    public function render(array $data = [])
-    {
-        $prevData = $this->getData();
-        $this->update($data);
-
-        $renderResult = $this->contentTypeFactory->get($this->renderContext->getAcceptType())
-            ->render($this, $this->getContentTemplate());
-
-        $this->setData($prevData);
-
-        return $renderResult;
-    }
-
-    /**
-     * Render label
-     *
-     * @return mixed|string
-     */
-    public function renderLabel()
-    {
-        return $this->contentTypeFactory->get($this->renderContext->getAcceptType())
-            ->render($this, $this->getLabelTemplate());
-    }
-
-    /**
-     * Render element
-     *
-     * @param string $elementName
-     * @param array $arguments
-     * @return mixed|string
-     */
-    public function renderElement($elementName, array $arguments)
-    {
-        $element = $this->renderContext->getRender()->getUiElementView($elementName);
-        $result = $element->render($arguments);
-        return $result;
-    }
-
-    /**
-     * Render component label
-     *
-     * @param string $elementName
-     * @param array $arguments
-     * @return string
-     */
-    public function renderElementLabel($elementName, array $arguments)
-    {
-        $element = $this->renderContext->getRender()->getUiElementView($elementName);
-        $prevData = $element->getData();
-        $element->update($arguments);
-        $result = $element->renderLabel();
-        $element->setData($prevData);
-        return $result;
-    }
-
-    /**
-     * Shortcut for rendering as HTML
-     * (used for backward compatibility with standard rendering mechanism via layout interface)
-     *
-     * @return string
-     */
-    public function toHtml()
-    {
-        return $this->render();
-    }
-
-    /**
-     * Getting label template
-     *
-     * @return string|false
-     */
-    public function getLabelTemplate()
-    {
-        return 'Magento_Ui::label/default.phtml';
-    }
-
-    /**
-     * Getting content template
-     *
-     * @return string|false
-     */
-    public function getContentTemplate()
-    {
-        return $this->getData('content_template');
-    }
-
-    /**
-     * Get Layout Node
-     *
-     * @param string $fullName
-     * @param mixed $default
-     * @return array
-     */
-    public function getLayoutElement($fullName, $default = null)
-    {
-        return $this->renderContext->getStorage()->getLayoutNode($fullName, $default);
-    }
-
-    /**
-     * Get name component instance
-     *
-     * @return string
-     */
-    public function getName()
-    {
-        return $this->config->getName();
-    }
-
-    /**
-     * Get parent name component instance
-     *
-     * @return string
-     */
-    public function getParentName()
-    {
-        return $this->config->getParentName();
-    }
-
-    /**
-     * Get configuration builder
-     *
-     * @return ConfigBuilderInterface
-     */
-    public function getConfigBuilder()
-    {
-        return $this->configBuilder;
-    }
-
-    /**
-     * Set component configuration
-     *
-     * @param null $configData
-     * @param null $name
-     * @param null $parentName
-     * @return void
-     */
-    public function prepareConfiguration($configData = null, $name = null, $parentName = null)
-    {
-        $arguments = [];
-        $arguments['name'] = $name ?: $this->renderContext->getNamespace() . '_' . $this->getNameInLayout();
-        $arguments['parentName'] = $parentName ?: $this->renderContext->getNamespace();
-        if ($configData) {
-            $arguments['configuration'] = $configData;
-        }
-        $this->config = $this->configFactory->create($arguments);
-        $this->renderContext->getStorage()->addComponentsData($this->config);
-    }
-
-    /**
-     * Get component configuration
-     *
-     * @return ConfigInterface
-     */
-    public function getConfig()
-    {
-        return $this->config;
-    }
-
-    /**
-     * Get render context
-     *
-     * @return Context
-     */
-    public function getRenderContext()
-    {
-        return $this->renderContext;
-    }
-
-    /**
-     * Get elements to the render
-     *
-     * @return ElementRendererInterface[]
-     */
-    public function getElements()
-    {
-        return $this->elements;
-    }
-
-    /**
-     * Set elements for the render
-     *
-     * @param ElementRendererInterface[] $elements
-     * @return mixed|void
-     */
-    public function setElements(array $elements)
-    {
-        $this->elements = $elements;
-    }
-
-    /**
-     * Get default parameters
-     *
-     * @return array
-     */
-    protected function getDefaultConfiguration()
-    {
-        return [];
-    }
-
-    /**
-     * Get render engine
-     *
-     * @return \Magento\Ui\ContentType\ContentTypeInterface
-     */
-    protected function getRenderEngine()
-    {
-        return $this->contentTypeFactory->get($this->renderContext->getAcceptType());
-    }
-
-    /**
-     * Create data provider
-     *
-     * @return void
-     */
-    protected function createDataProviders()
-    {
-        if ($this->hasData('data_provider_pool')) {
-            foreach ($this->getData('data_provider_pool') as $name => $config) {
-                $arguments = empty($config['arguments']) ? [] : $config['arguments'];
-                $arguments['params'] = $this->renderContext->getRequestParams();
-
-                $dataProvider = $this->dataProviderFactory->create($config['class'], $arguments);
-                $this->renderContext->getStorage()->addDataProvider($name, $dataProvider);
-            }
-        }
-    }
-}
diff --git a/app/code/Magento/Ui/Component/Container.php b/app/code/Magento/Ui/Component/Container.php
new file mode 100644
index 0000000000000000000000000000000000000000..84e86a9fd58cafb876e9b41fbf46dc6405896fee
--- /dev/null
+++ b/app/code/Magento/Ui/Component/Container.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\Component;
+
+/**
+ * Class Container
+ */
+class Container extends AbstractComponent
+{
+    const NAME = 'container';
+
+    /**
+     * Get component name
+     *
+     * @return string
+     */
+    public function getComponentName()
+    {
+        $type = $this->getData('type');
+        return static::NAME . (!empty($type) ? '.' . $type : '');
+    }
+
+    /**
+     * Register component
+     *
+     * @return void
+     */
+    public function prepare()
+    {
+        parent::prepare();
+
+        $jsConfig = $this->getConfiguration($this);
+        $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig);
+    }
+}
diff --git a/app/code/Magento/Ui/Component/Container/Content.php b/app/code/Magento/Ui/Component/Container/Content.php
deleted file mode 100644
index 94c43012e2eac05b4bfae9422461a0be23d1017a..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/Component/Container/Content.php
+++ /dev/null
@@ -1,29 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\Component\Container;
-
-use Magento\Ui\Component\AbstractView;
-
-/**
- * Class Content
- */
-class Content extends AbstractView
-{
-    /**
-     * Prepare component data
-     *
-     * @return $this|void
-     */
-    public function prepare()
-    {
-        $configData = $this->getDefaultConfiguration();
-        if ($this->hasData('config')) {
-            $configData = array_merge($configData, $this->getData('config'));
-        }
-
-        $this->prepareConfiguration($configData);
-    }
-}
diff --git a/app/code/Magento/Ui/Component/Control/Action.php b/app/code/Magento/Ui/Component/Control/Action.php
index 5021b8f7c481789233e9135655101b9e08a597e8..8f19a3b84e739d254e66da779aa1443701d66a60 100644
--- a/app/code/Magento/Ui/Component/Control/Action.php
+++ b/app/code/Magento/Ui/Component/Control/Action.php
@@ -5,11 +5,23 @@
  */
 namespace Magento\Ui\Component\Control;
 
-use Magento\Ui\Component\AbstractView;
+use Magento\Ui\Component\AbstractComponent;
+use Magento\Framework\View\Element\UiComponent\Control\ControlInterface;
 
 /**
  * Class Action
  */
-class Action extends AbstractView implements ControlInterface
+class Action extends AbstractComponent implements ControlInterface
 {
+    const NAME = 'action';
+
+    /**
+     * Get component name
+     *
+     * @return string
+     */
+    public function getComponentName()
+    {
+        return static::NAME;
+    }
 }
diff --git a/app/code/Magento/Ui/Component/Control/ActionPool.php b/app/code/Magento/Ui/Component/Control/ActionPool.php
index 97f5afdba9ed14cf1135cbd2f3e95caa436c764a..74f327fec1531089563d850815d93ad1bdbfc351 100644
--- a/app/code/Magento/Ui/Component/Control/ActionPool.php
+++ b/app/code/Magento/Ui/Component/Control/ActionPool.php
@@ -5,8 +5,11 @@
  */
 namespace Magento\Ui\Component\Control;
 
+use Magento\Framework\View\Element\AbstractBlock;
+use Magento\Framework\View\Element\BlockInterface;
 use Magento\Framework\View\Element\UiComponent\Context;
 use Magento\Framework\View\Element\UiComponentInterface;
+use Magento\Framework\View\Element\UiComponent\Control\ActionPoolInterface;
 
 /**
  * Class ActionPool
@@ -40,7 +43,7 @@ class ActionPool implements ActionPoolInterface
     protected $itemFactory;
 
     /**
-     * @var \Magento\Framework\View\Element\AbstractBlock
+     * @var AbstractBlock
      */
     protected $toolbarBlock;
 
@@ -54,8 +57,18 @@ class ActionPool implements ActionPoolInterface
     {
         $this->context = $context;
         $this->itemFactory = $itemFactory;
-        $this->toolbarBlock = $this->context->getPageLayout()
-            ? $this->context->getPageLayout()->getBlock(static::ACTIONS_PAGE_TOOLBAR) : false;
+    }
+
+    /**
+     * Get toolbar block
+     *
+     * @return bool|BlockInterface
+     */
+    public function getToolbar()
+    {
+        return $this->context->getPageLayout()
+            ? $this->context->getPageLayout()->getBlock(static::ACTIONS_PAGE_TOOLBAR)
+            : false;
     }
 
     /**
@@ -63,18 +76,19 @@ class ActionPool implements ActionPoolInterface
      *
      * @param string $key
      * @param array $data
-     * @param UiComponentInterface $view
+     * @param UiComponentInterface $component
      * @return void
      */
-    public function add($key, array $data, UiComponentInterface $view)
+    public function add($key, array $data, UiComponentInterface $component)
     {
         $data['id'] = isset($data['id']) ? $data['id'] : $key;
 
-        if ($this->toolbarBlock !== false) {
+        $toolbar = $this->getToolbar();
+        if ($toolbar !== false) {
             $this->items[$key] = $this->itemFactory->create();
             $this->items[$key]->setData($data);
-            $container = $this->createContainer($key, $view);
-            $this->toolbarBlock->setChild($key, $container);
+            $container = $this->createContainer($key, $component);
+            $toolbar->setChild($key, $container);
         }
     }
 
@@ -108,7 +122,7 @@ class ActionPool implements ActionPoolInterface
      *
      * @param string $key
      * @param UiComponentInterface $view
-     * @return \Magento\Ui\Component\Control\Container
+     * @return Container
      */
     protected function createContainer($key, UiComponentInterface $view)
     {
@@ -122,6 +136,7 @@ class ActionPool implements ActionPoolInterface
                 ]
             ]
         );
+
         return $container;
     }
 }
diff --git a/app/code/Magento/Ui/Component/Control/Button.php b/app/code/Magento/Ui/Component/Control/Button.php
index 51c839b14b2a8dc0592503a6df0619205e682e61..404bbf04bd4484287cdaa4dc63291242792b93ad 100644
--- a/app/code/Magento/Ui/Component/Control/Button.php
+++ b/app/code/Magento/Ui/Component/Control/Button.php
@@ -6,11 +6,12 @@
 namespace Magento\Ui\Component\Control;
 
 use Magento\Framework\View\Element\Template;
+use Magento\Framework\View\Element\UiComponent\Control\ControlInterface;
 
 /**
  * Class Button
  */
-class Button extends Template
+class Button extends Template implements ControlInterface
 {
     /**
      * Define block template
@@ -72,7 +73,7 @@ class Button extends Template
         } else {
             $url = $this->hasData('url') ? $this->getData('url') : $this->getUrl();
             if (!empty($url)) {
-                return sprintf("setLocation('%s');", $url);
+                return sprintf("location.href = '%s';", $url);
             }
 
             return null;
diff --git a/app/code/Magento/Ui/Component/Control/Container.php b/app/code/Magento/Ui/Component/Control/Container.php
index b4da5f6740eeddc3cc4a7c54b0c17c30eccf709f..2873e2618a168279d231b701a7007afec8de96ca 100644
--- a/app/code/Magento/Ui/Component/Control/Container.php
+++ b/app/code/Magento/Ui/Component/Control/Container.php
@@ -6,6 +6,7 @@
 namespace Magento\Ui\Component\Control;
 
 use Magento\Framework\View\Element\AbstractBlock;
+use Magento\Framework\View\Element\UiComponent\Control\ControlInterface;
 
 /**
  * Class Container
@@ -15,19 +16,19 @@ class Container extends AbstractBlock
     /**
      * Default button class
      */
-    const DEFAULT_BUTTON = 'Magento\Ui\Component\Control\Button';
+    const DEFAULT_CONTROL = 'Magento\Ui\Component\Control\Button';
 
     /**
      * Create button renderer
      *
      * @param string $blockName
      * @param string $blockClassName
-     * @return \Magento\Ui\Component\Control\Button
+     * @return ControlInterface
      */
     protected function createButton($blockName, $blockClassName = null)
     {
         if (null === $blockClassName) {
-            $blockClassName = static::DEFAULT_BUTTON;
+            $blockClassName = static::DEFAULT_CONTROL;
         }
 
         return $this->getLayout()->createBlock($blockClassName, $blockName);
@@ -40,7 +41,7 @@ class Container extends AbstractBlock
      */
     protected function _toHtml()
     {
-        /** @var \Magento\Ui\Component\Control\Item $item */
+        /** @var Item $item */
         $item = $this->getButtonItem();
         $data = $item->getData();
 
diff --git a/app/code/Magento/Ui/Component/Control/ControlInterface.php b/app/code/Magento/Ui/Component/Control/ControlInterface.php
deleted file mode 100644
index 6949ff096573b1045cccae62f42fd9e37e78e42a..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/Component/Control/ControlInterface.php
+++ /dev/null
@@ -1,16 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\Component\Control;
-
-use Magento\Framework\View\Element\UiComponentInterface;
-
-/**
- * Interface ControlInterface
- */
-interface ControlInterface extends UiComponentInterface
-{
-    //
-}
diff --git a/app/code/Magento/Ui/Component/Control/Link.php b/app/code/Magento/Ui/Component/Control/Link.php
index cdc3c166322a00249d6abd9f4d368246460e164b..ce99dc5064789af0ae33309505f9d9a4c469458f 100644
--- a/app/code/Magento/Ui/Component/Control/Link.php
+++ b/app/code/Magento/Ui/Component/Control/Link.php
@@ -5,12 +5,23 @@
  */
 namespace Magento\Ui\Component\Control;
 
-use Magento\Ui\Component\AbstractView;
+use Magento\Ui\Component\AbstractComponent;
+use Magento\Framework\View\Element\UiComponent\Control\ControlInterface;
 
 /**
  * Class Link
  */
-class Link extends AbstractView implements ControlInterface
+class Link extends AbstractComponent implements ControlInterface
 {
-    //
+    const NAME = 'link';
+
+    /**
+     * Get component name
+     *
+     * @return string
+     */
+    public function getComponentName()
+    {
+        return static::NAME;
+    }
 }
diff --git a/app/code/Magento/Ui/Component/DataSource.php b/app/code/Magento/Ui/Component/DataSource.php
new file mode 100644
index 0000000000000000000000000000000000000000..5f50643d73628e55cf5879094b277b1ee019f8b6
--- /dev/null
+++ b/app/code/Magento/Ui/Component/DataSource.php
@@ -0,0 +1,80 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\Component;
+
+use Magento\Framework\View\Element\UiComponent\ContextInterface;
+use Magento\Framework\View\Element\UiComponent\DataSourceInterface;
+use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface;
+
+/**
+ * Class DataSource
+ */
+class DataSource extends AbstractComponent implements DataSourceInterface
+{
+    const NAME = 'dataSource';
+
+    /**
+     * @var DataProviderInterface
+     */
+    protected $dataProvider;
+
+    /**
+     * Constructor
+     *
+     * @param ContextInterface $context
+     * @param DataProviderInterface $dataProvider
+     * @param array $components
+     * @param array $data
+     */
+    public function __construct(
+        ContextInterface $context,
+        DataProviderInterface $dataProvider,
+        array $components = [],
+        array $data = []
+    ) {
+        $this->dataProvider = $dataProvider;
+        $context->setDataProvider($dataProvider);
+        parent::__construct($context, $components, $data);
+    }
+
+    /**
+     * Get component name
+     *
+     * @return string
+     */
+    public function getComponentName()
+    {
+        return static::NAME;
+    }
+
+    /**
+     * Prepare component configuration
+     *
+     * @return void
+     */
+    public function prepare()
+    {
+        parent::prepare();
+
+        $config = $this->getData('config');
+        if (isset($config['update_url'])) {
+            $config['update_url'] = $this->getContext()->getUrl($config['update_url']);
+            $this->setData('config', $config);
+        }
+
+        $jsConfig = $this->getConfiguration($this);
+        unset($jsConfig['extends']);
+        $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig);
+    }
+
+    /**
+     * @return DataProviderInterface
+     */
+    public function getDataProvider()
+    {
+        return $this->dataProvider;
+    }
+}
diff --git a/app/code/Magento/Ui/Component/ElementRenderer.php b/app/code/Magento/Ui/Component/ElementRenderer.php
deleted file mode 100644
index 3d3e2857aa61b447c97b82a24c209e79afa9c7a3..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/Component/ElementRenderer.php
+++ /dev/null
@@ -1,50 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\Component;
-
-use Magento\Framework\View\Element\UiComponentInterface;
-
-/**
- * Class ElementRenderer
- */
-class ElementRenderer implements ElementRendererInterface
-{
-    /**
-     * Ui component
-     *
-     * @var UiComponentInterface
-     */
-    protected $element;
-
-    /**
-     * Data to render
-     *
-     * @var array
-     */
-    protected $data;
-
-    /**
-     * Constructor
-     *
-     * @param UiComponentInterface $element
-     * @param array $data
-     */
-    public function __construct(UiComponentInterface $element, array $data)
-    {
-        $this->element = $element;
-        $this->data = $data;
-    }
-
-    /**
-     * Render element
-     *
-     * @return string
-     */
-    public function render()
-    {
-        return $this->element->render($this->data);
-    }
-}
diff --git a/app/code/Magento/Ui/Component/ElementRendererBuilder.php b/app/code/Magento/Ui/Component/ElementRendererBuilder.php
deleted file mode 100644
index 4672866fc6299fa081258443d9bc149a4e2a733e..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/Component/ElementRendererBuilder.php
+++ /dev/null
@@ -1,51 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\Component;
-
-use Magento\Framework\ObjectManagerInterface;
-use Magento\Framework\View\Element\UiComponentInterface;
-
-/**
- * Class ElementRendererBuilder
- */
-class ElementRendererBuilder
-{
-    /**
-     * Object manager
-     *
-     * @var ObjectManagerInterface
-     */
-    protected $objectManager;
-
-    /**
-     * Instance class name
-     *
-     * @var string
-     */
-    protected $instanceClass = 'Magento\Ui\Component\ElementRenderer';
-
-    /**
-     * Constructor
-     *
-     * @param ObjectManagerInterface $objectManager
-     */
-    public function __construct(ObjectManagerInterface $objectManager)
-    {
-        $this->objectManager = $objectManager;
-    }
-
-    /**
-     * Create element to the render
-     *
-     * @param UiComponentInterface $element
-     * @param array $renderData
-     * @return ElementRendererInterface
-     */
-    public function create(UiComponentInterface $element, array $renderData)
-    {
-        return $this->objectManager->create($this->instanceClass, ['element' => $element, 'data' => $renderData]);
-    }
-}
diff --git a/app/code/Magento/Ui/Component/ElementRendererInterface.php b/app/code/Magento/Ui/Component/ElementRendererInterface.php
deleted file mode 100644
index 2cffde7c864654a4d2618b43af648084eed71127..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/Component/ElementRendererInterface.php
+++ /dev/null
@@ -1,19 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\Component;
-
-/**
- * Interface ElementRendererInterface
- */
-interface ElementRendererInterface
-{
-    /**
-     * Render element
-     *
-     * @return string
-     */
-    public function render();
-}
diff --git a/app/code/Magento/Ui/Component/Filter/FilterAbstract.php b/app/code/Magento/Ui/Component/Filter/FilterAbstract.php
deleted file mode 100644
index 0da2dc77f3ea2631b28e9bd16e958e9f426af660..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/Component/Filter/FilterAbstract.php
+++ /dev/null
@@ -1,97 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\Component\Filter;
-
-use Magento\Framework\View\Element\Template\Context as TemplateContext;
-use Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface;
-use Magento\Framework\View\Element\UiComponent\ConfigFactory;
-use Magento\Framework\View\Element\UiComponent\Context;
-use Magento\Ui\Component\AbstractView;
-use Magento\Ui\Component\Filter\FilterPool as FilterPoolProvider;
-use Magento\Ui\ContentType\ContentTypeFactory;
-use Magento\Ui\DataProvider\Factory as DataProviderFactory;
-use Magento\Ui\DataProvider\Manager;
-
-/**
- * Class Filter
- */
-abstract class FilterAbstract extends AbstractView implements FilterInterface
-{
-    /**
-     * Filter variable name
-     */
-    const FILTER_VAR = 'filter';
-
-    /**
-     * Filters pool
-     *
-     * @var FilterPoolProvider
-     */
-    protected $filterPool;
-
-    /**
-     * Constructor
-     *
-     * @param TemplateContext $context
-     * @param Context $renderContext
-     * @param ContentTypeFactory $contentTypeFactory
-     * @param ConfigFactory $configFactory
-     * @param ConfigBuilderInterface $configBuilder
-     * @param FilterPoolProvider $filterPool
-     * @param DataProviderFactory $dataProviderFactory
-     * @param Manager $dataProviderManager
-     * @param array $data
-     */
-    public function __construct(
-        TemplateContext $context,
-        Context $renderContext,
-        ContentTypeFactory $contentTypeFactory,
-        ConfigFactory $configFactory,
-        ConfigBuilderInterface $configBuilder,
-        DataProviderFactory $dataProviderFactory,
-        Manager $dataProviderManager,
-        FilterPoolProvider $filterPool,
-        array $data = []
-    ) {
-        $this->filterPool = $filterPool;
-        parent::__construct(
-            $context,
-            $renderContext,
-            $contentTypeFactory,
-            $configFactory,
-            $configBuilder,
-            $dataProviderFactory,
-            $dataProviderManager,
-            $data
-        );
-    }
-
-    /**
-     * Prepare component data
-     *
-     * @return void
-     */
-    public function prepare()
-    {
-        $configData = $this->getDefaultConfiguration();
-        if ($this->hasData('config')) {
-            $configData = array_merge($configData, $this->getData('config'));
-        }
-
-        $this->prepareConfiguration($configData);
-    }
-
-    /**
-     * Get condition by data type
-     *
-     * @param string|array $value
-     * @return array|null
-     */
-    public function getCondition($value)
-    {
-        return $value;
-    }
-}
diff --git a/app/code/Magento/Ui/Component/Filter/FilterInterface.php b/app/code/Magento/Ui/Component/Filter/FilterInterface.php
deleted file mode 100644
index aa1ccfe73e37b2568da3ea5e841be2aec6a89afe..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/Component/Filter/FilterInterface.php
+++ /dev/null
@@ -1,21 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\Component\Filter;
-
-
-/**
- * Interface FilterInterface
- */
-interface FilterInterface
-{
-    /**
-     * Get condition by data type
-     *
-     * @param string|array $value
-     * @return array|null
-     */
-    public function getCondition($value);
-}
diff --git a/app/code/Magento/Ui/Component/Filter/FilterPool.php b/app/code/Magento/Ui/Component/Filter/FilterPool.php
deleted file mode 100644
index 40d15a2c69d524a874fa9703df4db6e27c8dae20..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/Component/Filter/FilterPool.php
+++ /dev/null
@@ -1,64 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\Component\Filter;
-
-use Magento\Framework\ObjectManagerInterface;
-
-/**
- * Class FilterPool
- */
-class FilterPool
-{
-    /**
-     * Filter types
-     *
-     * @var array
-     */
-    protected $filterTypes = [];
-
-    /**
-     * Filters poll
-     *
-     * @var FilterInterface[]
-     */
-    protected $filters = [];
-
-    /**
-     * @var ObjectManagerInterface
-     */
-    protected $objectManager;
-
-    /**
-     * Constructor
-     *
-     * @param ObjectManagerInterface $objectManager
-     * @param array $filters
-     */
-    public function __construct(ObjectManagerInterface $objectManager, array $filters = [])
-    {
-        $this->objectManager = $objectManager;
-        $this->filterTypes = $filters;
-    }
-
-    /**
-     * Get filter by type
-     *
-     * @param string $filterName
-     * @return FilterInterface
-     * @throws \InvalidArgumentException
-     */
-    public function getFilter($filterName)
-    {
-        if (!isset($this->filters[$filterName])) {
-            if (!isset($this->filterTypes[$filterName])) {
-                throw new \InvalidArgumentException(sprintf('Unknown filter type "%s"', $filterName));
-            }
-            $this->filters[$filterName] = $this->objectManager->create($this->filterTypes[$filterName]);
-        }
-
-        return $this->filters[$filterName];
-    }
-}
diff --git a/app/code/Magento/Ui/Component/Filter/Type/Date.php b/app/code/Magento/Ui/Component/Filter/Type/Date.php
deleted file mode 100644
index 90b7e16a4aeeb16e7d70fa2a4da2663a0f4df92e..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/Component/Filter/Type/Date.php
+++ /dev/null
@@ -1,146 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\Component\Filter\Type;
-
-use Magento\Framework\Locale\ResolverInterface;
-use Magento\Framework\View\Element\Template\Context as TemplateContext;
-use Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface;
-use Magento\Framework\View\Element\UiComponent\ConfigFactory;
-use Magento\Framework\View\Element\UiComponent\Context;
-use Magento\Ui\Component\Filter\FilterAbstract;
-use Magento\Ui\Component\Filter\FilterPool;
-use Magento\Ui\ContentType\ContentTypeFactory;
-use Magento\Ui\DataProvider\Factory as DataProviderFactory;
-use Magento\Ui\DataProvider\Manager;
-
-/**
- * Class Date
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
- */
-class Date extends FilterAbstract
-{
-    /**
-     * Timezone library
-     *
-     * @var \Magento\Framework\Stdlib\DateTime\TimezoneInterface
-     */
-    protected $localeDate;
-
-    /**
-     * Scope config
-     *
-     * @var \Magento\Framework\App\Config\ScopeConfigInterface
-     */
-    protected $scopeConfig;
-
-    /**
-     * Locale resolver
-     *
-     * @var \Magento\Framework\Locale\ResolverInterface
-     */
-    protected $localeResolver;
-
-    /**
-     * Constructor
-     *
-     * @param TemplateContext $context
-     * @param Context $renderContext
-     * @param ContentTypeFactory $contentTypeFactory
-     * @param ConfigFactory $configFactory
-     * @param ConfigBuilderInterface $configBuilder
-     * @param DataProviderFactory $dataProviderFactory
-     * @param Manager $dataProviderManager
-     * @param FilterPool $filterPool
-     * @param ResolverInterface $localeResolver
-     * @param array $data
-     * @SuppressWarnings(PHPMD.ExcessiveParameterList)
-     */
-    public function __construct(
-        TemplateContext $context,
-        Context $renderContext,
-        ContentTypeFactory $contentTypeFactory,
-        ConfigFactory $configFactory,
-        ConfigBuilderInterface $configBuilder,
-        DataProviderFactory $dataProviderFactory,
-        Manager $dataProviderManager,
-        FilterPool $filterPool,
-        ResolverInterface $localeResolver,
-        array $data = []
-    ) {
-        $this->localeDate = $context->getLocaleDate();
-        $this->scopeConfig = $context->getScopeConfig();
-        $this->localeResolver = $localeResolver;
-        parent::__construct(
-            $context,
-            $renderContext,
-            $contentTypeFactory,
-            $configFactory,
-            $configBuilder,
-            $dataProviderFactory,
-            $dataProviderManager,
-            $filterPool,
-            $data
-        );
-    }
-
-    /**
-     * Get condition by data type
-     *
-     * @param string|array $value
-     * @return array|null
-     */
-    public function getCondition($value)
-    {
-        return $this->convertValue($value);
-    }
-
-    /**
-     * Convert value
-     *
-     * @param array|string $value
-     * @return array|null
-     */
-    protected function convertValue($value)
-    {
-        if (!empty($value['from']) || !empty($value['to'])) {
-            $locale = $this->localeResolver->getLocale();
-            if (!empty($value['from'])) {
-                $value['orig_from'] = $value['from'];
-                $value['from'] = $this->convertDate(strtotime($value['from']), $locale);
-            }
-            if (!empty($value['to'])) {
-                $value['orig_to'] = $value['to'];
-                $value['to'] = $this->convertDate(strtotime($value['to']), $locale);
-            }
-            $value['datetime'] = true;
-            $value['locale'] = $this->localeResolver->getLocale();
-        } else {
-            $value = null;
-        }
-
-        return $value;
-    }
-
-    /**
-     * Convert given date to default (UTC) timezone
-     *
-     * @param int $date
-     * @param string $locale
-     * @return \DateTime|null
-     */
-    protected function convertDate($date, $locale)
-    {
-        try {
-            $dateObj = $this->localeDate->date(new \DateTime($date), $locale, false);
-            $dateObj->setTime(0, 0, 0);
-            //convert store date to default date in UTC timezone without DST
-            $dateObj->setTimezone(new \DateTimeZone('UTC'));
-            return $dateObj;
-        } catch (\Exception $e) {
-            return null;
-        }
-    }
-}
diff --git a/app/code/Magento/Ui/Component/Filter/Type/Input.php b/app/code/Magento/Ui/Component/Filter/Type/Input.php
deleted file mode 100644
index 214ae8e8a671c980590352b14943a426887b9799..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/Component/Filter/Type/Input.php
+++ /dev/null
@@ -1,30 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\Component\Filter\Type;
-
-use Magento\Ui\Component\Filter\FilterAbstract;
-
-/**
- * Class Input
- */
-class Input extends FilterAbstract
-{
-    /**
-     * Get condition by data type
-     *
-     * @param string|array $value
-     * @return array|null
-     */
-    public function getCondition($value)
-    {
-        $condition = null;
-        if (!empty($value) || is_numeric($value)) {
-            $condition = ['like' => sprintf('%%%s%%', $value)];
-        }
-
-        return $condition;
-    }
-}
diff --git a/app/code/Magento/Ui/Component/Filter/Type/Range.php b/app/code/Magento/Ui/Component/Filter/Type/Range.php
deleted file mode 100644
index 25583f994f40007f45e654575471e2b9889a4641..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/Component/Filter/Type/Range.php
+++ /dev/null
@@ -1,38 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\Component\Filter\Type;
-
-use Magento\Ui\Component\Filter\FilterAbstract;
-
-/**
- * Class Range
- */
-class Range extends FilterAbstract
-{
-    /**
-     * Get condition by data type
-     *
-     * @param array|string $value
-     * @return array|null
-     */
-    public function getCondition($value)
-    {
-        if (!empty($value['from']) || !empty($value['to'])) {
-            if (isset($value['from']) && empty($value['from']) && $value['from'] !== '0') {
-                $value['orig_from'] = $value['from'];
-                $value['from'] = null;
-            }
-            if (isset($value['to']) && empty($value['to']) && $value['to'] !== '0') {
-                $value['orig_to'] = $value['to'];
-                $value['to'] = null;
-            }
-        } else {
-            $value = null;
-        }
-
-        return $value;
-    }
-}
diff --git a/app/code/Magento/Ui/Component/Filter/Type/Select.php b/app/code/Magento/Ui/Component/Filter/Type/Select.php
deleted file mode 100644
index 309049fef60012b1f86d7094f8b3211ee378e84b..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/Component/Filter/Type/Select.php
+++ /dev/null
@@ -1,30 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\Component\Filter\Type;
-
-use Magento\Ui\Component\Filter\FilterAbstract;
-
-/**
- * Class Select
- */
-class Select extends FilterAbstract
-{
-    /**
-     * Get condition by data type
-     *
-     * @param string|array $value
-     * @return array|null
-     */
-    public function getCondition($value)
-    {
-        $condition = null;
-        if (!empty($value) || is_numeric($value)) {
-            $condition = ['eq' => $value];
-        }
-
-        return $condition;
-    }
-}
diff --git a/app/code/Magento/Ui/Component/Filter/Type/Store.php b/app/code/Magento/Ui/Component/Filter/Type/Store.php
deleted file mode 100644
index aa0495336a281bb632eeffea466e9758665559ee..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/Component/Filter/Type/Store.php
+++ /dev/null
@@ -1,15 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\Component\Filter\Type;
-
-use Magento\Ui\Component\Filter\FilterAbstract;
-
-/**
- * Class Store
- */
-class Store extends FilterAbstract
-{
-}
diff --git a/app/code/Magento/Ui/Component/FilterPool.php b/app/code/Magento/Ui/Component/FilterPool.php
deleted file mode 100644
index fae9e248d58ab64d3efd2c5355a4dd4b6517524d..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/Component/FilterPool.php
+++ /dev/null
@@ -1,193 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\Component;
-
-use Magento\Framework\View\Element\Template\Context as TemplateContext;
-use Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface;
-use Magento\Framework\View\Element\UiComponent\ConfigFactory;
-use Magento\Framework\View\Element\UiComponent\Context;
-use Magento\Ui\Component\Filter\FilterAbstract;
-use Magento\Ui\Component\Filter\FilterPool as FilterPoolProvider;
-use Magento\Ui\ContentType\ContentTypeFactory;
-use Magento\Ui\DataProvider\Factory as DataProviderFactory;
-use Magento\Ui\DataProvider\Manager;
-
-/**
- * Class FilterPool
- */
-class FilterPool extends AbstractView
-{
-    /**
-     * Filters pool
-     *
-     * @var FilterPoolProvider
-     */
-    protected $filterPoolProvider;
-
-    /**
-     * Constructor
-     *
-     * @param TemplateContext $context
-     * @param Context $renderContext
-     * @param ContentTypeFactory $contentTypeFactory
-     * @param ConfigFactory $configFactory
-     * @param ConfigBuilderInterface $configBuilder
-     * @param DataProviderFactory $dataProviderFactory
-     * @param Manager $dataProviderManager
-     * @param FilterPoolProvider $filterPoolProvider
-     * @param array $data
-     */
-    public function __construct(
-        TemplateContext $context,
-        Context $renderContext,
-        ContentTypeFactory $contentTypeFactory,
-        ConfigFactory $configFactory,
-        ConfigBuilderInterface $configBuilder,
-        DataProviderFactory $dataProviderFactory,
-        Manager $dataProviderManager,
-        FilterPoolProvider $filterPoolProvider,
-        array $data = []
-    ) {
-        $this->filterPoolProvider = $filterPoolProvider;
-        parent::__construct(
-            $context,
-            $renderContext,
-            $contentTypeFactory,
-            $configFactory,
-            $configBuilder,
-            $dataProviderFactory,
-            $dataProviderManager,
-            $data
-        );
-    }
-
-    /**
-     * Prepare component data
-     *
-     * @return void
-     */
-    public function prepare()
-    {
-        $configData = $this->getDefaultConfiguration();
-        if ($this->hasData('config')) {
-            $configData = array_merge($configData, $this->getData('config'));
-        }
-        $this->prepareConfiguration($configData);
-        $this->updateDataCollection();
-    }
-
-    /**
-     * Get fields
-     *
-     * @return array
-     */
-    public function getFields()
-    {
-        $meta = $this->renderContext->getStorage()->getMeta($this->getParentName());
-        $fields = [];
-        if (isset($meta['fields'])) {
-            foreach ($meta['fields'] as $name => $config) {
-                if (isset($config['filterable']) && $config['filterable'] === false) {
-                    continue;
-                }
-                $fields[$name] = $config;
-            }
-        }
-        return $fields;
-    }
-
-    /**
-     * Get active filters
-     *
-     * @return array
-     */
-    public function getActiveFilters()
-    {
-        $metaData = $this->renderContext->getStorage()->getMeta($this->getParentName());
-        $metaData = $metaData['fields'];
-        $filters = [];
-        $filterData = $this->prepareFilterString(
-            $this->renderContext->getRequestParam(FilterAbstract::FILTER_VAR)
-        );
-        foreach ($filterData as $field => $value) {
-            if (isset($metaData[$field]['filter_type'])) {
-                $filters[$field] = [
-                    'label' => $metaData[$field]['label'],
-                    'current_display_value' => $value,
-                ];
-            }
-        }
-
-        return $filters;
-    }
-
-    /**
-     * Update data collection
-     *
-     * @return void
-     */
-    protected function updateDataCollection()
-    {
-        $collection = $this->renderContext->getStorage()->getDataCollection($this->getParentName());
-
-        $metaData = $this->renderContext->getStorage()->getMeta($this->getParentName());
-        $metaData = $metaData['fields'];
-        $filterData = $this->prepareFilterString(
-            $this->renderContext->getRequestParam(FilterAbstract::FILTER_VAR)
-        );
-        foreach ($filterData as $field => $value) {
-            if (!isset($metaData[$field]['filter_type'])) {
-                continue;
-            }
-            $condition = $this->filterPoolProvider->getFilter($metaData[$field]['filter_type'])->getCondition($value);
-            if ($condition !== null) {
-                $collection->addFieldToFilter($field, $condition);
-            }
-        }
-    }
-
-    /**
-     * Get list of required filters
-     *
-     * @return array
-     */
-    protected function getListOfRequiredFilters()
-    {
-        $result = [];
-        foreach ($this->getFields() as $field) {
-            $result[] = isset($field['filter_type']) ? $field['filter_type'] : $field['input_type'];
-        }
-
-        return $result;
-    }
-
-    /**
-     * Decode filter string
-     *
-     * @param string $filterString
-     * @return array
-     */
-    protected function prepareFilterString($filterString)
-    {
-        $data = [];
-        $filterString = base64_decode($filterString);
-        parse_str($filterString, $data);
-        array_walk_recursive(
-            $data,
-            // @codingStandardsIgnoreStart
-            /**
-             * Decodes URL-encoded string and trims whitespaces from the beginning and end of a string
-             *
-             * @param string $value
-             */
-            // @codingStandardsIgnoreEnd
-            function (&$value) {
-                $value = trim(rawurldecode($value));
-            }
-        );
-        return $data;
-    }
-}
diff --git a/app/code/Magento/Ui/Component/Filters.php b/app/code/Magento/Ui/Component/Filters.php
new file mode 100644
index 0000000000000000000000000000000000000000..75c5b0d0472b947d132c779d3b079be5fd5d4af1
--- /dev/null
+++ b/app/code/Magento/Ui/Component/Filters.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\Component;
+
+/**
+ * Class Filters
+ */
+class Filters extends AbstractComponent
+{
+    const NAME = 'filters';
+
+    /**
+     * Get component name
+     *
+     * @return string
+     */
+    public function getComponentName()
+    {
+        return static::NAME;
+    }
+
+    /**
+     * Register component.
+     *
+     * @return void
+     */
+    public function prepare()
+    {
+        parent::prepare();
+
+        $jsConfig = $this->getConfiguration($this);
+        $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig);
+    }
+}
diff --git a/app/code/Magento/Ui/Component/Filters/Type/AbstractFilter.php b/app/code/Magento/Ui/Component/Filters/Type/AbstractFilter.php
new file mode 100644
index 0000000000000000000000000000000000000000..d2aa51c314a4b5f0979ba80093959a3364382350
--- /dev/null
+++ b/app/code/Magento/Ui/Component/Filters/Type/AbstractFilter.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\Component\Filters\Type;
+
+use Magento\Ui\Component\AbstractComponent;
+use Magento\Framework\View\Element\UiComponentFactory;
+use Magento\Framework\View\Element\UiComponent\ContextInterface;
+
+/**
+ * Abstract class AbstractFilter
+ */
+abstract class AbstractFilter extends AbstractComponent
+{
+    /**
+     * Filter variable name
+     */
+    const FILTER_VAR = 'filters';
+
+    /**
+     * Filter data
+     *
+     * @var array
+     */
+    protected $filterData;
+
+    /**
+     * @var UiComponentFactory
+     */
+    protected $uiComponentFactory;
+
+    /**
+     * Constructor
+     *
+     * @param ContextInterface $context
+     * @param UiComponentFactory $uiComponentFactory
+     * @param array $components
+     * @param array $data
+     */
+    public function __construct(
+        ContextInterface $context,
+        UiComponentFactory $uiComponentFactory,
+        array $components = [],
+        array $data = []
+    ) {
+        $this->uiComponentFactory = $uiComponentFactory;
+        parent::__construct($context, $components, $data);
+
+        $this->filterData = $this->getContext()->getRequestParam(static::FILTER_VAR);
+    }
+}
diff --git a/app/code/Magento/Ui/Component/Filters/Type/Date.php b/app/code/Magento/Ui/Component/Filters/Type/Date.php
new file mode 100644
index 0000000000000000000000000000000000000000..4211b51838b8eaf3736ab38cd3b612b7486ca5aa
--- /dev/null
+++ b/app/code/Magento/Ui/Component/Filters/Type/Date.php
@@ -0,0 +1,121 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\Component\Filters\Type;
+
+use Magento\Ui\Component\Form\Element\DataType\Date as DataTypeDate;
+
+/**
+ * Class Date
+ */
+class Date extends AbstractFilter
+{
+    const NAME = 'filter_date';
+
+    const COMPONENT = 'date';
+
+    /**
+     * Wrapped component
+     *
+     * @var DataTypeDate
+     */
+    protected $wrappedComponent;
+
+    /**
+     * Get component name
+     *
+     * @return string
+     */
+    public function getComponentName()
+    {
+        return static::NAME;
+    }
+
+    /**
+     * Prepare component configuration
+     *
+     * @return void
+     */
+    public function prepare()
+    {
+        parent::prepare();
+
+        $this->wrappedComponent = $this->uiComponentFactory->create(
+            $this->getName(),
+            static::COMPONENT,
+            ['context' => $this->getContext()]
+        );
+        $this->wrappedComponent->prepare();
+
+        $this->applyFilter();
+        $jsConfig = array_replace_recursive(
+            $this->getConfiguration($this->wrappedComponent),
+            $this->getConfiguration($this)
+        );
+        $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig);
+    }
+
+    /**
+     * Get JS config
+     *
+     * @return array
+     */
+    public function getJsConfig()
+    {
+        return array_replace_recursive(
+            (array) $this->wrappedComponent->getData('config'),
+            (array) $this->getData('config')
+        );
+    }
+
+    /**
+     * Apply filter
+     *
+     * @return void
+     */
+    protected function applyFilter()
+    {
+        $condition = $this->getCondition();
+        if ($condition !== null) {
+            $this->getContext()->getDataProvider()->addFilter($this->getName(), $condition);
+        }
+    }
+
+    /**
+     * Get condition
+     *
+     * @return array|null
+     */
+    protected function getCondition()
+    {
+        $value = isset($this->filterData[$this->getName()]) ? $this->filterData[$this->getName()] : null;
+        if (!empty($value['from']) || !empty($value['to'])) {
+            if (!empty($value['from'])) {
+                $value['orig_from'] = $value['from'];
+                $value['from'] = $this->wrappedComponent->convertDate(
+                    $value['from'],
+                    $this->wrappedComponent->getLocale()
+                );
+            } else {
+                unset($value['from']);
+            }
+            if (!empty($value['to'])) {
+                $value['orig_to'] = $value['to'];
+                $value['to'] = $this->wrappedComponent->convertDate(
+                    $value['to'],
+                    $this->wrappedComponent->getLocale()
+                );
+            } else {
+                unset($value['to']);
+            }
+            $value['datetime'] = true;
+            $value['locale'] = $this->wrappedComponent->getLocale();
+        } else {
+            $value = null;
+        }
+
+        return $value;
+    }
+}
diff --git a/app/code/Magento/Ui/Component/Filters/Type/DateRange.php b/app/code/Magento/Ui/Component/Filters/Type/DateRange.php
new file mode 100644
index 0000000000000000000000000000000000000000..daae0ab2ca7327188259f6c9d9035997dfce5022
--- /dev/null
+++ b/app/code/Magento/Ui/Component/Filters/Type/DateRange.php
@@ -0,0 +1,105 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\Component\Filters\Type;
+
+use Magento\Ui\Component\Form\Element\DataType\Date as DataTypeDate;
+
+/**
+ * Class DateRange
+ */
+class DateRange extends AbstractFilter
+{
+    const NAME = 'filter_range';
+
+    const COMPONENT = 'date';
+
+    /**
+     * Wrapped component
+     *
+     * @var DataTypeDate
+     */
+    protected $wrappedComponent;
+
+    /**
+     * Get component name
+     *
+     * @return string
+     */
+    public function getComponentName()
+    {
+        return static::NAME;
+    }
+
+    /**
+     * Prepare component configuration
+     *
+     * @return void
+     */
+    public function prepare()
+    {
+        parent::prepare();
+
+        $this->wrappedComponent = $this->uiComponentFactory->create(
+            $this->getName(),
+            static::COMPONENT,
+            ['context' => $this->getContext()]
+        );
+        $this->wrappedComponent->prepare();
+
+        $this->applyFilter();
+        $jsConfig = $this->getConfiguration($this);
+        $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig);
+    }
+
+    /**
+     * Apply filter
+     *
+     * @return void
+     */
+    protected function applyFilter()
+    {
+        $condition = $this->getCondition();
+        if ($condition !== null) {
+            $this->getContext()->getDataProvider()->addFilter($this->getName(), $condition);
+        }
+    }
+
+    /**
+     * Get condition by data type
+     *
+     * @return array|null
+     */
+    public function getCondition()
+    {
+        $value = isset($this->filterData[$this->getName()]) ? $this->filterData[$this->getName()] : null;
+        if (!empty($value['from']) || !empty($value['to'])) {
+            if (!empty($value['from'])) {
+                $value['orig_from'] = $value['from'];
+                $value['from'] = $this->wrappedComponent->convertDate(
+                    $value['from'],
+                    $this->wrappedComponent->getLocale()
+                );
+            } else {
+                unset($value['from']);
+            }
+            if (!empty($value['to'])) {
+                $value['orig_to'] = $value['to'];
+                $value['to'] = $this->wrappedComponent->convertDate(
+                    $value['to'],
+                    $this->wrappedComponent->getLocale()
+                );
+            } else {
+                unset($value['to']);
+            }
+            $value['datetime'] = true;
+            $value['locale'] = $this->wrappedComponent->getLocale();
+        } else {
+            $value = null;
+        }
+
+        return $value;
+    }
+}
diff --git a/app/code/Magento/Ui/Component/Filters/Type/Input.php b/app/code/Magento/Ui/Component/Filters/Type/Input.php
new file mode 100644
index 0000000000000000000000000000000000000000..5a9e68b0bd72540dc22c9644094bc81c575631b8
--- /dev/null
+++ b/app/code/Magento/Ui/Component/Filters/Type/Input.php
@@ -0,0 +1,87 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\Component\Filters\Type;
+
+use Magento\Ui\Component\Form\Element\Input as ElementInput;
+
+/**
+ * Class Input
+ */
+class Input extends AbstractFilter
+{
+    const NAME = 'filter_input';
+
+    const COMPONENT = 'input';
+
+    /**
+     * Wrapped component
+     *
+     * @var ElementInput
+     */
+    protected $wrappedComponent;
+
+    /**
+     * Get component name
+     *
+     * @return string
+     */
+    public function getComponentName()
+    {
+        return static::NAME;
+    }
+
+    /**
+     * Prepare component configuration
+     *
+     * @return void
+     */
+    public function prepare()
+    {
+        parent::prepare();
+        $this->wrappedComponent = $this->uiComponentFactory->create(
+            $this->getName(),
+            static::COMPONENT,
+            ['context' => $this->getContext()]
+        );
+        $this->wrappedComponent->prepare();
+
+        $this->applyFilter();
+        $jsConfig = array_replace_recursive(
+            $this->getConfiguration($this->wrappedComponent),
+            $this->getConfiguration($this)
+        );
+        $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig);
+    }
+
+    /**
+     * Apply filter
+     *
+     * @return void
+     */
+    protected function applyFilter()
+    {
+        $condition = $this->getCondition();
+        if ($condition !== null) {
+            $this->getContext()->getDataProvider()->addFilter($this->getName(), $condition);
+        }
+    }
+
+    /**
+     * Get condition by data type
+     *
+     * @return array|null
+     */
+    public function getCondition()
+    {
+        $value = isset($this->filterData[$this->getName()]) ? $this->filterData[$this->getName()] : null;
+        $condition = null;
+        if (!empty($value) || is_numeric($value)) {
+            $condition = ['like' => sprintf('%%%s%%', $value)];
+        }
+
+        return $condition;
+    }
+}
diff --git a/app/code/Magento/Ui/Component/Filters/Type/Range.php b/app/code/Magento/Ui/Component/Filters/Type/Range.php
new file mode 100644
index 0000000000000000000000000000000000000000..7892ef98f52222d4c75d32ef4676f09656f4e827
--- /dev/null
+++ b/app/code/Magento/Ui/Component/Filters/Type/Range.php
@@ -0,0 +1,100 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\Component\Filters\Type;
+
+/**
+ * Class Range
+ */
+class Range extends AbstractFilter
+{
+    const NAME = 'filter_range';
+
+    /**
+     * Get component name
+     *
+     * @return string
+     */
+    public function getComponentName()
+    {
+        return static::NAME;
+    }
+
+    /**
+     * Prepare component configuration
+     *
+     * @return void
+     */
+    public function prepare()
+    {
+        parent::prepare();
+        $this->applyFilter();
+        $jsConfig = $this->getConfiguration($this);
+        $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig);
+    }
+
+    /**
+     * Apply filter
+     *
+     * @return void
+     */
+    protected function applyFilter()
+    {
+        $condition = $this->getCondition();
+        if ($condition !== null) {
+            $this->getContext()->getDataProvider()->addFilter($this->getName(), $condition);
+        }
+    }
+
+    /**
+     * Get condition by data type
+     *
+     * @return array|null
+     */
+    public function getCondition()
+    {
+        $value = isset($this->filterData[$this->getName()]) ? $this->filterData[$this->getName()] : null;
+        if (!empty($value['from']) || !empty($value['to'])) {
+            $value = $this->prepareFrom($value);
+            $value = $this->prepareTo($value);
+        } else {
+            $value = null;
+        }
+
+        return $value;
+    }
+
+    /**
+     * Prepare "from" value
+     *
+     * @param array $value
+     * @return array
+     */
+    protected function prepareFrom(array $value)
+    {
+        if (isset($value['from']) && empty($value['from']) && $value['from'] !== '0') {
+            $value['orig_from'] = $value['from'];
+            $value['from'] = null;
+        }
+
+        return $value;
+    }
+
+    /**
+     * Prepare "from" value
+     *
+     * @param array $value
+     * @return array
+     */
+    protected function prepareTo(array $value)
+    {
+        if (isset($value['to']) && empty($value['to']) && $value['to'] !== '0') {
+            $value['orig_to'] = $value['to'];
+            $value['to'] = null;
+        }
+
+        return $value;
+    }
+}
diff --git a/app/code/Magento/Ui/Component/Filters/Type/Select.php b/app/code/Magento/Ui/Component/Filters/Type/Select.php
new file mode 100644
index 0000000000000000000000000000000000000000..399ad004d5bbb1a72814d16b697315d34d34c84f
--- /dev/null
+++ b/app/code/Magento/Ui/Component/Filters/Type/Select.php
@@ -0,0 +1,128 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\Component\Filters\Type;
+
+use Magento\Framework\Data\OptionSourceInterface;
+use Magento\Framework\View\Element\UiComponentFactory;
+use Magento\Framework\View\Element\UiComponent\ContextInterface;
+use Magento\Ui\Component\Form\Element\Select as ElementSelect;
+
+/**
+ * Class Select
+ */
+class Select extends AbstractFilter
+{
+    const NAME = 'filter_select';
+
+    const COMPONENT = 'select';
+
+    /**
+     * Wrapped component
+     *
+     * @var ElementSelect
+     */
+    protected $wrappedComponent;
+
+    /**
+     * @var OptionSourceInterface
+     */
+    protected $optionsProvider;
+
+    /**
+     * Constructor
+     *
+     * @param ContextInterface $context
+     * @param UiComponentFactory $uiComponentFactory
+     * @param OptionSourceInterface $optionsProvider
+     * @param array $components
+     * @param array $data
+     */
+    public function __construct(
+        ContextInterface $context,
+        UiComponentFactory $uiComponentFactory,
+        OptionSourceInterface $optionsProvider = null,
+        array $components = [],
+        array $data = []
+    ) {
+        $this->optionsProvider = $optionsProvider;
+        parent::__construct($context, $uiComponentFactory, $components, $data);
+    }
+
+    /**
+     * Get component name
+     *
+     * @return string
+     */
+    public function getComponentName()
+    {
+        return static::NAME;
+    }
+
+    /**
+     * Prepare component configuration
+     *
+     * @return void
+     */
+    public function prepare()
+    {
+        parent::prepare();
+        $this->wrappedComponent = $this->uiComponentFactory->create(
+            $this->getName(),
+            static::COMPONENT,
+            ['context' => $this->getContext(), 'options' => $this->optionsProvider]
+        );
+        $this->wrappedComponent->prepare();
+
+        $this->applyFilter();
+        $jsConfig = array_replace_recursive(
+            $this->getConfiguration($this->wrappedComponent),
+            $this->getConfiguration($this)
+        );
+        $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig);
+    }
+
+    /**
+     * Get JS config
+     *
+     * @return array
+     */
+    public function getJsConfig()
+    {
+        return array_replace_recursive(
+            (array) $this->wrappedComponent->getData('config'),
+            (array) $this->getData('config')
+        );
+    }
+
+    /**
+     * Get condition by data type
+     *
+     * @return array|null
+     */
+    public function getCondition()
+    {
+        $value = isset($this->filterData[$this->getName()]) ? $this->filterData[$this->getName()] : null;
+        $condition = null;
+        if (!empty($value) || is_numeric($value)) {
+            $condition = ['eq' => $value];
+        }
+
+        return $condition;
+    }
+
+    /**
+     * Apply filter
+     *
+     * @return void
+     */
+    protected function applyFilter()
+    {
+        $condition = $this->getCondition();
+        if ($condition !== null) {
+            $this->getContext()->getDataProvider()->addFilter($this->getName(), $condition);
+        }
+    }
+}
diff --git a/app/code/Magento/Ui/Component/Form.php b/app/code/Magento/Ui/Component/Form.php
index 4e4435b6773638f14a510253edf655d196508f6a..aa74ffddd3ecabb5967b7aac173534e1ed03ce71 100644
--- a/app/code/Magento/Ui/Component/Form.php
+++ b/app/code/Magento/Ui/Component/Form.php
@@ -5,222 +5,75 @@
  */
 namespace Magento\Ui\Component;
 
-use Magento\Framework\View\Element\Template\Context as TemplateContext;
-use Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface;
-use Magento\Framework\View\Element\UiComponent\ConfigFactory;
-use Magento\Framework\View\Element\UiComponent\Context;
-use Magento\Framework\View\Element\UiElementFactory;
-use Magento\Ui\Component\Control\ActionPool;
-use Magento\Ui\Component\Control\ButtonProviderFactory;
-use Magento\Ui\Component\Control\ButtonProviderInterface;
-use Magento\Ui\ContentType\ContentTypeFactory;
-use Magento\Ui\DataProvider\Factory as DataProviderFactory;
-use Magento\Ui\DataProvider\Manager;
+use Magento\Framework\View\Element\UiComponent\DataSourceInterface;
 
 /**
  * Class Form
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
-class Form extends AbstractView
+class Form extends AbstractComponent
 {
-    /**
-     * Default form element
-     */
-    const DEFAULT_FORM_ELEMENT = 'input';
+    const NAME = 'form';
 
     /**
-     * From element map
+     * Get component name
      *
-     * @var array
-     */
-    protected $formElementMap = [
-        'text' => 'input',
-        'number' => 'input',
-    ];
-
-    /**
-     * Ui element builder
-     *
-     * @var ElementRendererBuilder
-     */
-    protected $elementRendererBuilder;
-
-    /**
-     * @var UiElementFactory
-     */
-    protected $factory;
-
-    /**
-     * @var ActionPool
-     */
-    protected $actionPool;
-
-    /**
-     * @var ButtonProviderFactory
-     */
-    protected $buttonProviderFactory;
-
-    /**
-     * Constructor
-     *
-     * @param TemplateContext $context
-     * @param Context $renderContext
-     * @param ContentTypeFactory $contentTypeFactory
-     * @param ConfigFactory $configFactory
-     * @param ConfigBuilderInterface $configBuilder
-     * @param DataProviderFactory $dataProviderFactory
-     * @param Manager $dataProviderManager
-     * @param ElementRendererBuilder $elementRendererBuilder
-     * @param UiElementFactory $factory
-     * @param ActionPool $actionPool
-     * @param ButtonProviderFactory $buttonProviderFactory
-     * @param array $data
-     * @SuppressWarnings(PHPMD.ExcessiveParameterList)
+     * @return string
      */
-    public function __construct(
-        TemplateContext $context,
-        Context $renderContext,
-        ContentTypeFactory $contentTypeFactory,
-        ConfigFactory $configFactory,
-        ConfigBuilderInterface $configBuilder,
-        DataProviderFactory $dataProviderFactory,
-        Manager $dataProviderManager,
-        ElementRendererBuilder $elementRendererBuilder,
-        UiElementFactory $factory,
-        ActionPool $actionPool,
-        ButtonProviderFactory $buttonProviderFactory,
-        array $data = []
-    ) {
-        $this->elementRendererBuilder = $elementRendererBuilder;
-        $this->factory = $factory;
-        $this->actionPool = $actionPool;
-        $this->buttonProviderFactory = $buttonProviderFactory;
-        parent::__construct(
-            $context,
-            $renderContext,
-            $contentTypeFactory,
-            $configFactory,
-            $configBuilder,
-            $dataProviderFactory,
-            $dataProviderManager,
-            $data
-        );
+    public function getComponentName()
+    {
+        return static::NAME;
     }
 
     /**
-     * Prepare component data
+     * Register component
      *
      * @return void
      */
     public function prepare()
     {
-        $this->registerComponents();
-        $buttons = $this->getData('buttons');
-        if ($buttons) {
-            foreach ($buttons as $buttonId => $buttonClass) {
-                /** @var ButtonProviderInterface $button */
-                $button = $this->buttonProviderFactory->create($buttonClass);
-                $buttonData = $button->getButtonData();
-                if (!$buttonData) {
-                    unset($buttons[$buttonId]);
-                    continue;
-                }
-                $buttons[$buttonId] = $buttonData;
-            }
-            uasort($buttons, [$this, 'sortButtons']);
-            foreach ($buttons as $buttonId => $buttonData) {
-                $this->actionPool->add($buttonId, $buttonData, $this);
-            }
-        }
+        parent::prepare();
 
-        $layoutSettings = (array) $this->getData('layout');
-        $data = [
-            'name' => $this->getData('name'),
-            'label' => $this->getData('label'),
-            'data_sources' => $this->getData('data_sources'),
-            'child_blocks' => $this->getLayout()->getChildBlocks($this->getNameInLayout()),
-            'configuration' => isset($layoutSettings['configuration'])
-                ? $layoutSettings['configuration']
-                : [],
-        ];
-        $layoutType = isset($layoutSettings['type'])
-            ? $layoutSettings['type']
-            : \Magento\Ui\Component\Layout\Tabs::NAME;
-        $layout = $this->factory->create(
-            $layoutType,
-            $data
-        );
-        $layout->prepare();
-        $this->elements[] = $layout;
-    }
+        $jsConfig = $this->getConfiguration($this);
+        unset($jsConfig['extends']);
+        $this->getContext()->addComponentDefinition($this->getContext()->getNamespace(), $jsConfig);
 
-    /**
-     * @return string
-     */
-    public function getDataScope()
-    {
-        return $this->getData('name');
+        $this->getContext()->addButtons($this->getData('buttons'), $this);
     }
 
     /**
-     * Register all UI Components configuration
-     *
-     * @return void
+     * @return array
      */
-    protected function registerComponents()
+    public function getDataSourceData()
     {
-        $this->renderContext->getStorage()->addComponent(
-            $this->getData('name'),
-            [
-                'component' => 'Magento_Ui/js/form/component',
-                'config' => [
-                    'provider' => $this->getData('name'),
-                ],
-                'deps' => [$this->getData('name')]
-            ]
-        );
-        foreach ($this->getLayout()->getAllBlocks() as $name => $block) {
-            if ($block instanceof \Magento\Framework\View\Element\UiComponentInterface) {
-                $config = (array)$block->getData('js_config');
-                if (!isset($config['extends'])) {
-                    $config['extends'] = $this->getData('name');
+        $dataSources = [];
+        foreach ($this->getChildComponents() as $component) {
+            if ($component instanceof DataSourceInterface) {
+                $dataProvider = $component->getDataProvider();
+                $id = $this->getContext()->getRequestParam($dataProvider->getRequestFieldName());
+                $preparedData = [];
+                if ($id) {
+                    $dataProvider->addFilter($dataProvider->getPrimaryFieldName(), $id);
+                    $preparedData = $dataProvider->getData();
+                    if (isset($preparedData[$id])) {
+                        $preparedData = ['data' => $preparedData[$id]];
+                    }
                 }
-                $this->renderContext->getStorage()->addComponent($name, $config);
-            }
-        };
-    }
-
-    /**
-     * @return string
-     */
-    public function getSaveAction()
-    {
-        return $this->getUrl('mui/form/save');
-    }
 
-    /**
-     * @return string
-     */
-    public function getValidateAction()
-    {
-        return $this->getUrl('mui/form/validate');
-    }
-
-    /**
-     * Sort buttons by sort order
-     *
-     * @param array $itemA
-     * @param array $itemB
-     * @return int
-     * @SuppressWarnings(PHPMD.NPathComplexity)
-     */
-    public function sortButtons(array $itemA, array $itemB)
-    {
-        $sortOrderA = isset($itemA['sort_order']) ? intval($itemA['sort_order']) : 0;
-        $sortOrderB = isset($itemB['sort_order']) ? intval($itemB['sort_order']) : 0;
-        if ($sortOrderA == $sortOrderB) {
-            return 0;
+                $config = $dataProvider->getConfigData();
+                if (isset($config['submit_url'])) {
+                    $config['submit_url'] = $this->getContext()->getUrl($config['submit_url']);
+                }
+                if (isset($config['validate_url'])) {
+                    $config['validate_url'] = $this->getContext()->getUrl($config['validate_url']);
+                }
+                $dataSources[$component->getName()] = [
+                    'type' => $component->getComponentName(),
+                    'name' => $component->getName(),
+                    'dataScope' => $component->getContext()->getNamespace(),
+                    'config' => array_merge($preparedData, $config)
+                ];
+            }
         }
-        return ($sortOrderA < $sortOrderB) ? -1 : 1;
+        return $dataSources;
     }
 }
diff --git a/app/code/Magento/Ui/Component/Form/Collection.php b/app/code/Magento/Ui/Component/Form/Collection.php
index 09b67401aaced6f231d871c1e004ed78113e80b3..c816843578c6b2ba80fcdbfea017d713031b0dac 100644
--- a/app/code/Magento/Ui/Component/Form/Collection.php
+++ b/app/code/Magento/Ui/Component/Form/Collection.php
@@ -5,13 +5,23 @@
  */
 namespace Magento\Ui\Component\Form;
 
+use Magento\Ui\Component\AbstractComponent;
 use Magento\Framework\View\Element\UiComponentInterface;
-use Magento\Ui\Component\AbstractView;
 
 /**
  * Class Collection
  */
-class Collection extends AbstractView implements UiComponentInterface
+class Collection extends AbstractComponent implements UiComponentInterface
 {
-    //
+    const NAME = 'collection';
+
+    /**
+     * Get component name
+     *
+     * @return string
+     */
+    public function getComponentName()
+    {
+        return static::NAME;
+    }
 }
diff --git a/app/code/Magento/Ui/Component/Form/Element/AbstractFormElement.php b/app/code/Magento/Ui/Component/Form/Element/AbstractElement.php
similarity index 75%
rename from app/code/Magento/Ui/Component/Form/Element/AbstractFormElement.php
rename to app/code/Magento/Ui/Component/Form/Element/AbstractElement.php
index e536143ab6b4a719b6e8582159d748eb1bc8d182..c01990b9d7e8eec7b59844c8f92d6d9bd6e67726 100644
--- a/app/code/Magento/Ui/Component/Form/Element/AbstractFormElement.php
+++ b/app/code/Magento/Ui/Component/Form/Element/AbstractElement.php
@@ -5,12 +5,12 @@
  */
 namespace Magento\Ui\Component\Form\Element;
 
-use Magento\Ui\Component\AbstractView;
+use Magento\Ui\Component\AbstractComponent;
 
 /**
- * Class AbstractFormElement
+ * Class AbstractElement
  */
-abstract class AbstractFormElement extends AbstractView implements ElementInterface
+abstract class AbstractElement extends AbstractComponent implements ElementInterface
 {
     /**
      * @return string
@@ -38,9 +38,8 @@ abstract class AbstractFormElement extends AbstractView implements ElementInterf
 
     /**
      * @return bool
-     * @SuppressWarnings(PHPMD.BooleanGetMethodName)
      */
-    public function getIsReadonly()
+    public function isReadonly()
     {
         return (bool) $this->getData('readonly');
     }
diff --git a/app/code/Magento/Ui/Component/Form/Element/Checkbox.php b/app/code/Magento/Ui/Component/Form/Element/Checkbox.php
index df26d8c21bb31ba861c4d929b070e5854b917ab7..e3e73495628c2671d23c72ea725ed6da25916f55 100644
--- a/app/code/Magento/Ui/Component/Form/Element/Checkbox.php
+++ b/app/code/Magento/Ui/Component/Form/Element/Checkbox.php
@@ -8,7 +8,30 @@ namespace Magento\Ui\Component\Form\Element;
 /**
  * Class Checkbox
  */
-class Checkbox extends AbstractFormElement
+class Checkbox extends AbstractElement
 {
-    //
+    const NAME = 'checkbox';
+
+    /**
+     * Get component name
+     *
+     * @return string
+     */
+    public function getComponentName()
+    {
+        return static::NAME;
+    }
+
+    /**
+     * Prepare component configuration
+     *
+     * @return void
+     */
+    public function prepare()
+    {
+        parent::prepare();
+
+        $jsConfig = $this->getConfiguration($this, Input::NAME);
+        $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig);
+    }
 }
diff --git a/app/code/Magento/Ui/Component/Form/Element/DataType/AbstractDataType.php b/app/code/Magento/Ui/Component/Form/Element/DataType/AbstractDataType.php
index cc196dea37d70c3b3b0ff57e77e4d3ee40e5fc31..e36e3f3589ad6b119aba9ac2d1fd1436c1dc09e7 100644
--- a/app/code/Magento/Ui/Component/Form/Element/DataType/AbstractDataType.php
+++ b/app/code/Magento/Ui/Component/Form/Element/DataType/AbstractDataType.php
@@ -5,26 +5,20 @@
  */
 namespace Magento\Ui\Component\Form\Element\DataType;
 
-use Magento\Ui\Component\AbstractView;
+use Magento\Ui\Component\AbstractComponent;
 
 /**
  * Class AbstractDataType
  */
-abstract class AbstractDataType extends AbstractView implements DataTypeInterface
+abstract class AbstractDataType extends AbstractComponent implements DataTypeInterface
 {
     /**
+     * Validate value
+     *
      * @return bool
      */
     public function validate()
     {
         return true;
     }
-
-    /**
-     * @return string
-     */
-    public function getDataObjectValue()
-    {
-        return $this->getData('data_object')[$this->getData('name')];
-    }
 }
diff --git a/app/code/Magento/Ui/Component/Form/Element/DataType/Boolean.php b/app/code/Magento/Ui/Component/Form/Element/DataType/Boolean.php
index 8fe4b24f502d9fc7ae0bb70027164dd42715d951..d7865d61e608eae19c3f72bdd63fe2998179953f 100644
--- a/app/code/Magento/Ui/Component/Form/Element/DataType/Boolean.php
+++ b/app/code/Magento/Ui/Component/Form/Element/DataType/Boolean.php
@@ -10,5 +10,15 @@ namespace Magento\Ui\Component\Form\Element\DataType;
  */
 class Boolean extends AbstractDataType
 {
-    //
+    const NAME = 'boolean';
+
+    /**
+     * Get component name
+     *
+     * @return string
+     */
+    public function getComponentName()
+    {
+        return static::NAME;
+    }
 }
diff --git a/app/code/Magento/Ui/Component/Form/Element/DataType/DataTypeInterface.php b/app/code/Magento/Ui/Component/Form/Element/DataType/DataTypeInterface.php
index 63aefa0b72903f3bf46b029b6046426c356f6193..04bbecb0a8de5b2082931292b5ece267a77cc077 100644
--- a/app/code/Magento/Ui/Component/Form/Element/DataType/DataTypeInterface.php
+++ b/app/code/Magento/Ui/Component/Form/Element/DataType/DataTypeInterface.php
@@ -5,7 +5,6 @@
  */
 namespace Magento\Ui\Component\Form\Element\DataType;
 
-use Magento\Framework\Object;
 use Magento\Framework\View\Element\UiComponentInterface;
 
 /**
@@ -19,11 +18,4 @@ interface DataTypeInterface extends UiComponentInterface
      * @return bool
      */
     public function validate();
-
-    /**
-     * Get data object value
-     *
-     * @return mixed
-     */
-    public function getDataObjectValue();
 }
diff --git a/app/code/Magento/Ui/Component/Form/Element/DataType/Date.php b/app/code/Magento/Ui/Component/Form/Element/DataType/Date.php
index 46bd9267d737c7c65b9584101277e8b7845bdd67..e72be53246d1698337ca34784304cf7801e59a33 100644
--- a/app/code/Magento/Ui/Component/Form/Element/DataType/Date.php
+++ b/app/code/Magento/Ui/Component/Form/Element/DataType/Date.php
@@ -5,10 +5,109 @@
  */
 namespace Magento\Ui\Component\Form\Element\DataType;
 
+use Magento\Framework\Locale\ResolverInterface;
+use Magento\Framework\Stdlib\DateTime\TimezoneInterface;
+use Magento\Framework\View\Element\UiComponentInterface;
+use Magento\Framework\View\Element\UiComponent\ContextInterface;
+
 /**
  * Class Date
  */
 class Date extends AbstractDataType
 {
-    //
+    const NAME = 'date';
+
+    /**
+     * Current locale
+     *
+     * @var string
+     */
+    protected $locale;
+
+    /**
+     * Wrapped component
+     *
+     * @var UiComponentInterface
+     */
+    protected $wrappedComponent;
+
+    /**
+     * Constructor
+     *
+     * @param ContextInterface $context
+     * @param TimezoneInterface $localeDate
+     * @param ResolverInterface $localeResolver
+     * @param array $components
+     * @param array $data
+     */
+    public function __construct(
+        ContextInterface $context,
+        TimezoneInterface $localeDate,
+        ResolverInterface $localeResolver,
+        array $components = [],
+        array $data = []
+    ) {
+        $this->locale = $localeResolver->getLocale();
+        $this->localeDate = $localeDate;
+        parent::__construct($context, $components, $data);
+    }
+
+    /**
+     * Prepare component configuration
+     *
+     * @return void
+     */
+    public function prepare()
+    {
+        parent::prepare();
+
+        $config = $this->getData('config');
+        if (!isset($config['dateFormat'])) {
+            $config['dateFormat'] = $this->localeDate->getDateTimeFormat(\IntlDateFormatter::MEDIUM);
+            $this->setData('config', $config);
+        }
+
+        $jsConfig = $this->getConfiguration($this);
+        $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig);
+    }
+
+
+    /**
+     * Get locale
+     *
+     * @return string
+     */
+    public function getLocale()
+    {
+        return $this->locale;
+    }
+
+    /**
+     * Get component name
+     *
+     * @return string
+     */
+    public function getComponentName()
+    {
+        return static::NAME;
+    }
+
+    /**
+     * Convert given date to default (UTC) timezone
+     *
+     * @param int $date
+     * @return \DateTime|null
+     */
+    public function convertDate($date)
+    {
+        try {
+            $dateObj = $this->localeDate->date(new \DateTime($date), $this->getLocale(), false);
+            $dateObj->setTime(0, 0, 0);
+            //convert store date to default date in UTC timezone without DST
+            $dateObj->setTimezone(new \DateTimeZone('UTC'));
+            return $dateObj;
+        } catch (\Exception $e) {
+            return null;
+        }
+    }
 }
diff --git a/app/code/Magento/Ui/Component/Form/Element/DataType/Email.php b/app/code/Magento/Ui/Component/Form/Element/DataType/Email.php
index 7dda21c016ae980f741b1d98396c23e1a8ac8bb0..49b12bbf6277076373c277ed92f873828d99707e 100644
--- a/app/code/Magento/Ui/Component/Form/Element/DataType/Email.php
+++ b/app/code/Magento/Ui/Component/Form/Element/DataType/Email.php
@@ -10,5 +10,15 @@ namespace Magento\Ui\Component\Form\Element\DataType;
  */
 class Email extends AbstractDataType
 {
-    //
+    const NAME = 'email';
+
+    /**
+     * Get component name
+     *
+     * @return string
+     */
+    public function getComponentName()
+    {
+        return static::NAME;
+    }
 }
diff --git a/app/code/Magento/Ui/Component/Form/Element/DataType/Media.php b/app/code/Magento/Ui/Component/Form/Element/DataType/Media.php
index 0f361470f944bc0956bdbdd1b61e0ba1e1050da7..fda46d7b137a0168884f6df5f38656127a8e7755 100644
--- a/app/code/Magento/Ui/Component/Form/Element/DataType/Media.php
+++ b/app/code/Magento/Ui/Component/Form/Element/DataType/Media.php
@@ -10,5 +10,15 @@ namespace Magento\Ui\Component\Form\Element\DataType;
  */
 class Media extends AbstractDataType
 {
-    //
+    const NAME = 'media';
+
+    /**
+     * Get component name
+     *
+     * @return string
+     */
+    public function getComponentName()
+    {
+        return static::NAME;
+    }
 }
diff --git a/app/code/Magento/Ui/Component/Form/Element/DataType/Number.php b/app/code/Magento/Ui/Component/Form/Element/DataType/Number.php
index 4b5d7924e53c234d953efac46c438d3a6afc102c..929a86ab19a8a12b9694d3b9d546e3e4ce23680e 100644
--- a/app/code/Magento/Ui/Component/Form/Element/DataType/Number.php
+++ b/app/code/Magento/Ui/Component/Form/Element/DataType/Number.php
@@ -10,5 +10,15 @@ namespace Magento\Ui\Component\Form\Element\DataType;
  */
 class Number extends AbstractDataType
 {
-    //
+    const NAME = 'number';
+
+    /**
+     * Get component name
+     *
+     * @return string
+     */
+    public function getComponentName()
+    {
+        return static::NAME;
+    }
 }
diff --git a/app/code/Magento/Ui/Component/Form/Element/DataType/Password.php b/app/code/Magento/Ui/Component/Form/Element/DataType/Password.php
index d58d74bd4c9d9ce839cd98e90e9b5bdac459f5dc..77a93da72288bfa57e0f8f20711461cd1ff4395a 100644
--- a/app/code/Magento/Ui/Component/Form/Element/DataType/Password.php
+++ b/app/code/Magento/Ui/Component/Form/Element/DataType/Password.php
@@ -10,5 +10,15 @@ namespace Magento\Ui\Component\Form\Element\DataType;
  */
 class Password extends AbstractDataType
 {
-    //
+    const NAME = 'password';
+
+    /**
+     * Get component name
+     *
+     * @return string
+     */
+    public function getComponentName()
+    {
+        return static::NAME;
+    }
 }
diff --git a/app/code/Magento/Ui/Component/Form/Element/DataType/Price.php b/app/code/Magento/Ui/Component/Form/Element/DataType/Price.php
index 138c224dea80d65aa506d19691d479b80a02bdf5..a183fc4ad1760c3059baf1a37b50dede49e1cbb6 100644
--- a/app/code/Magento/Ui/Component/Form/Element/DataType/Price.php
+++ b/app/code/Magento/Ui/Component/Form/Element/DataType/Price.php
@@ -10,5 +10,15 @@ namespace Magento\Ui\Component\Form\Element\DataType;
  */
 class Price extends AbstractDataType
 {
-    //
+    const NAME = 'price';
+
+    /**
+     * Get component name
+     *
+     * @return string
+     */
+    public function getComponentName()
+    {
+        return static::NAME;
+    }
 }
diff --git a/app/code/Magento/Ui/Component/Form/Element/DataType/Text.php b/app/code/Magento/Ui/Component/Form/Element/DataType/Text.php
index 43c259b510bcde506b3a41bbdb8876ae1fd20b8a..c3187b92a7706dd1bc89e830b53205755262483a 100644
--- a/app/code/Magento/Ui/Component/Form/Element/DataType/Text.php
+++ b/app/code/Magento/Ui/Component/Form/Element/DataType/Text.php
@@ -10,5 +10,15 @@ namespace Magento\Ui\Component\Form\Element\DataType;
  */
 class Text extends AbstractDataType
 {
-    //
+    const NAME = 'text';
+
+    /**
+     * Get component name
+     *
+     * @return string
+     */
+    public function getComponentName()
+    {
+        return static::NAME;
+    }
 }
diff --git a/app/code/Magento/Ui/Component/Form/Element/ElementInterface.php b/app/code/Magento/Ui/Component/Form/Element/ElementInterface.php
index f6cd906ed59ec2b3113b6513f3d33e4bd88d2755..3450d6238384ecb7298d7ed642b1bccfa218e19c 100644
--- a/app/code/Magento/Ui/Component/Form/Element/ElementInterface.php
+++ b/app/code/Magento/Ui/Component/Form/Element/ElementInterface.php
@@ -24,9 +24,8 @@ interface ElementInterface extends UiComponentInterface
 
     /**
      * @return bool
-     * @SuppressWarnings(PHPMD.BooleanGetMethodName)
      */
-    public function getIsReadonly();
+    public function isReadonly();
 
     /**
      * @return string
diff --git a/app/code/Magento/Ui/Component/Form/Element/Input.php b/app/code/Magento/Ui/Component/Form/Element/Input.php
index 9d149e9dd290f4dd12712501d1ce778cc9007860..9b43d1b7db952c7907ac8e0152a8b345ff26efb5 100644
--- a/app/code/Magento/Ui/Component/Form/Element/Input.php
+++ b/app/code/Magento/Ui/Component/Form/Element/Input.php
@@ -8,21 +8,30 @@ namespace Magento\Ui\Component\Form\Element;
 /**
  * Class Input
  */
-class Input extends AbstractFormElement
+class Input extends AbstractElement
 {
+    const NAME = 'input';
+
     /**
-     * @return mixed|string
+     * Get component name
+     *
+     * @return string
      */
-    public function getType()
+    public function getComponentName()
     {
-        return $this->getData('input_type') ? $this->getData('input_type') : 'text';
+        return static::NAME;
     }
 
     /**
+     * Prepare component configuration
+     *
      * @return void
      */
     public function prepare()
     {
-        parent::prepare(); // TODO: Change the autogenerated stub
+        parent::prepare();
+
+        $jsConfig = $this->getConfiguration($this);
+        $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig);
     }
 }
diff --git a/app/code/Magento/Ui/Component/Form/Element/Multiline.php b/app/code/Magento/Ui/Component/Form/Element/Multiline.php
index 5e8b3b226dcb0bb8827f12809f9d10c756542e29..de3cd8900ddd5c6fdac0ead4735637226ea578e0 100644
--- a/app/code/Magento/Ui/Component/Form/Element/Multiline.php
+++ b/app/code/Magento/Ui/Component/Form/Element/Multiline.php
@@ -8,8 +8,20 @@ namespace Magento\Ui\Component\Form\Element;
 /**
  * Class Multiline
  */
-class Multiline extends AbstractFormElement
+class Multiline extends AbstractElement
 {
+    const NAME = 'multiline';
+
+    /**
+     * Get component name
+     *
+     * @return string
+     */
+    public function getComponentName()
+    {
+        return static::NAME;
+    }
+
     /**
      * @return mixed|string
      */
@@ -19,10 +31,15 @@ class Multiline extends AbstractFormElement
     }
 
     /**
+     * Prepare component configuration
+     *
      * @return void
      */
     public function prepare()
     {
-        parent::prepare(); // TODO: Change the autogenerated stub
+        parent::prepare();
+
+        $jsConfig = $this->getConfiguration($this, Input::NAME);
+        $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig);
     }
 }
diff --git a/app/code/Magento/Ui/Component/Form/Element/Radio.php b/app/code/Magento/Ui/Component/Form/Element/Radio.php
index 1737d460db14218d51e0edad5542b86c716a4723..1f93d43aa4fc16083193d5b8138bb4267eddba59 100644
--- a/app/code/Magento/Ui/Component/Form/Element/Radio.php
+++ b/app/code/Magento/Ui/Component/Form/Element/Radio.php
@@ -8,8 +8,20 @@ namespace Magento\Ui\Component\Form\Element;
 /**
  * Class Radio
  */
-class Radio extends AbstractFormElement
+class Radio extends AbstractElement
 {
+    const NAME = 'radio';
+
+    /**
+     * Get component name
+     *
+     * @return string
+     */
+    public function getComponentName()
+    {
+        return static::NAME;
+    }
+
     /**
      * @return bool
      * @SuppressWarnings(PHPMD.BooleanGetMethodName)
diff --git a/app/code/Magento/Ui/Component/Form/Element/Range.php b/app/code/Magento/Ui/Component/Form/Element/Range.php
index 549b295108c339afb4ca0170af0b76f1e4ae6195..debd3e1acabaa187c0482a73133b972ccecd6ca1 100644
--- a/app/code/Magento/Ui/Component/Form/Element/Range.php
+++ b/app/code/Magento/Ui/Component/Form/Element/Range.php
@@ -8,8 +8,20 @@ namespace Magento\Ui\Component\Form\Element;
 /**
  * Class Range
  */
-class Range extends AbstractFormElement
+class Range extends AbstractElement
 {
+    const NAME = 'range';
+
+    /**
+     * Get component name
+     *
+     * @return string
+     */
+    public function getComponentName()
+    {
+        return static::NAME;
+    }
+
     /**
      * @return mixed
      */
diff --git a/app/code/Magento/Ui/Component/Form/Element/Select.php b/app/code/Magento/Ui/Component/Form/Element/Select.php
index 59a366d3e4b2aac3a270c2e41cefa9e2e4e1e1f1..be31eb6acad7955d8cd5757464282834bb016877 100644
--- a/app/code/Magento/Ui/Component/Form/Element/Select.php
+++ b/app/code/Magento/Ui/Component/Form/Element/Select.php
@@ -5,11 +5,75 @@
  */
 namespace Magento\Ui\Component\Form\Element;
 
+use Magento\Framework\Data\OptionSourceInterface;
+use Magento\Framework\View\Element\UiComponent\ContextInterface;
+
 /**
  * Class Select
  */
-class Select extends AbstractFormElement
+class Select extends AbstractElement
 {
+    const NAME = 'select';
+
+    /**
+     * @var array|OptionSourceInterface|null
+     */
+    protected $options;
+
+    /**
+     * Constructor
+     *
+     * @param ContextInterface $context
+     * @param array|OptionSourceInterface|null $options
+     * @param array $components
+     * @param array $data
+     */
+    public function __construct(
+        ContextInterface $context,
+        $options = null,
+        array $components = [],
+        array $data = []
+    ) {
+        $this->options = $options;
+        parent::__construct($context, $components, $data);
+    }
+
+    /**
+     * Get component name
+     *
+     * @return string
+     */
+    public function getComponentName()
+    {
+        return static::NAME;
+    }
+
+    /**
+     * Prepare component configuration
+     *
+     * @return void
+     */
+    public function prepare()
+    {
+        parent::prepare();
+        $config = $this->getData('config');
+        if (isset($this->options)) {
+            if (!isset($config['options'])) {
+                $config['options'] = [];
+            }
+            if ($this->options instanceof OptionSourceInterface) {
+                $options = $this->options->toOptionArray();
+            } else {
+                $options = array_values($this->options);
+            }
+            $config['options'] = array_values(array_merge_recursive($options, $config['options']));
+        }
+        $this->setData('config', (array)$config);
+
+        $jsConfig = $this->getConfiguration($this, Input::NAME);
+        $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig);
+    }
+
     /**
      * Check if option value
      *
diff --git a/app/code/Magento/Ui/Component/Form/Element/Textarea.php b/app/code/Magento/Ui/Component/Form/Element/Textarea.php
index 0b7031ef8f6ce2dd7a6e76dcc810469704ff2d74..d7f12580d67d5c6b4f68c22a437f7cc28f228af6 100644
--- a/app/code/Magento/Ui/Component/Form/Element/Textarea.php
+++ b/app/code/Magento/Ui/Component/Form/Element/Textarea.php
@@ -8,7 +8,30 @@ namespace Magento\Ui\Component\Form\Element;
 /**
  * Class Textarea
  */
-class Textarea extends AbstractFormElement
+class Textarea extends AbstractElement
 {
-    //
+    const NAME = 'textarea';
+
+    /**
+     * Get component name
+     *
+     * @return string
+     */
+    public function getComponentName()
+    {
+        return static::NAME;
+    }
+
+    /**
+     * Prepare component configuration
+     *
+     * @return void
+     */
+    public function prepare()
+    {
+        parent::prepare();
+
+        $jsConfig = $this->getConfiguration($this, Input::NAME);
+        $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig);
+    }
 }
diff --git a/app/code/Magento/Ui/Component/Form/Field.php b/app/code/Magento/Ui/Component/Form/Field.php
index 5f0c94dd42d765eb405c94b154e0c0956c10010d..890288d086a2a9c22ca51bb912391e6e220a42b5 100644
--- a/app/code/Magento/Ui/Component/Form/Field.php
+++ b/app/code/Magento/Ui/Component/Form/Field.php
@@ -5,29 +5,107 @@
  */
 namespace Magento\Ui\Component\Form;
 
+use Magento\Framework\Exception\LocalizedException;
+use Magento\Ui\Component\AbstractComponent;
+use Magento\Framework\View\Element\UiComponentFactory;
 use Magento\Framework\View\Element\UiComponentInterface;
-use Magento\Ui\Component\AbstractView;
+use Magento\Framework\View\Element\UiComponent\ContextInterface;
 
 /**
- * Class AbstractFormElement
+ * Class Field
  */
-class Field extends AbstractView implements UiComponentInterface
+class Field extends AbstractComponent
 {
+    const NAME = 'field';
+
+    /**
+     * Wrapped component
+     *
+     * @var UiComponentInterface
+     */
+    protected $wrappedComponent;
+
+    /**
+     * UI component factory
+     *
+     * @var UiComponentFactory
+     */
+    protected $uiComponentFactory;
+
     /**
-     * @return mixed
+     * Constructor
+     *
+     * @param ContextInterface $context
+     * @param UiComponentFactory $uiComponentFactory
+     * @param UiComponentInterface[] $components
+     * @param array $data
      */
-    public function renderHeader()
+    public function __construct(
+        ContextInterface $context,
+        UiComponentFactory $uiComponentFactory,
+        array $components = [],
+        array $data = []
+    ) {
+        $this->uiComponentFactory = $uiComponentFactory;
+        parent::__construct($context, $components, $data);
+    }
+
+    /**
+     * Get component name
+     *
+     * @return string
+     */
+    public function getComponentName()
     {
-        return $this->getRenderEngine()->render($this, $this->getHeaderTemplate());
+        return 'form.' . $this->wrappedComponent->getComponentName();
     }
 
     /**
-     * Getting template for field header section
+     * Prepare component configuration
      *
-     * @return string|false
+     * @return void
+     * @throws \Magento\Framework\Exception\LocalizedException
      */
-    public function getHeaderTemplate()
+    public function prepare()
     {
-        return isset($this->configuration['header_template']) ? $this->configuration['header_template'] : false;
+        parent::prepare();
+        $formElement = $this->getData('config/formElement');
+        if (null === $formElement) {
+            throw new LocalizedException(__(
+                'The configuration parameter "formElement" is a required for "' . $this->getName() . '" field.'
+            ));
+        }
+        // Create of wrapped component
+        $this->wrappedComponent = $this->uiComponentFactory->create(
+            $this->getName(),
+            $formElement,
+            array_merge(['context' => $this->getContext()], (array) $this->getData())
+        );
+        $this->wrappedComponent->prepare();
+
+        // To prepare the component configuration
+        $wrappedComponentConfig = $this->getConfiguration($this->wrappedComponent);
+        $jsConfig = array_replace_recursive(
+            $wrappedComponentConfig,
+            $this->getConfiguration($this, $this->wrappedComponent->getComponentName())
+        );
+        $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig);
+    }
+
+    /**
+     * Get JS config
+     *
+     * @return array
+     */
+    public function getJsConfig()
+    {
+        if (isset($this->wrappedComponent)) {
+            return array_replace_recursive(
+                (array) $this->wrappedComponent->getData('config'),
+                (array) $this->getData('config')
+            );
+        }
+
+        return (array) $this->getData('config');
     }
 }
diff --git a/app/code/Magento/Ui/Component/Form/Fieldset.php b/app/code/Magento/Ui/Component/Form/Fieldset.php
index 03fd8f62d6e847ba154c2390de4cde80732dcca0..f8d9ee0b012330a138d9d5cbb4ce743d07aef753 100644
--- a/app/code/Magento/Ui/Component/Form/Fieldset.php
+++ b/app/code/Magento/Ui/Component/Form/Fieldset.php
@@ -5,14 +5,19 @@
  */
 namespace Magento\Ui\Component\Form;
 
-use Magento\Ui\Component\AbstractView;
+use Magento\Framework\Exception\LocalizedException;
+use Magento\Ui\Component\Container;
+use Magento\Ui\Component\AbstractComponent;
+use Magento\Framework\View\Element\UiComponentFactory;
+use Magento\Framework\View\Element\UiComponentInterface;
+use Magento\Framework\View\Element\UiComponent\ContextInterface;
 
 /**
  * Class Fieldset
  */
-class Fieldset extends AbstractView
+class Fieldset extends AbstractComponent
 {
-    const UI_ELEMENT_FIELDSET = 'fieldset';
+    const NAME = 'fieldset';
 
     /**
      * @var bool
@@ -20,43 +25,125 @@ class Fieldset extends AbstractView
     protected $collapsible = false;
 
     /**
+     * @var UiComponentInterface[]
+     */
+    protected $fieldsInContainers = [];
+
+    /**
+     * Constructor
+     *
+     * @param ContextInterface $context
+     * @param UiComponentFactory $uiComponentFactory
+     * @param UiComponentInterface[] $components
+     * @param array $data
+     */
+    public function __construct(
+        ContextInterface $context,
+        UiComponentFactory $uiComponentFactory,
+        array $components = [],
+        array $data = []
+    ) {
+        $this->uiComponentFactory = $uiComponentFactory;
+        parent::__construct($context, $components, $data);
+    }
+
+    /**
+     * Get component name
+     *
      * @return string
      */
-    public function getLegendText()
+    public function getComponentName()
     {
-        return $this->getData('config/label');
+        return static::NAME;
     }
 
     /**
-     * @return bool
-     * @SuppressWarnings(PHPMD.BooleanGetMethodName)
+     * Prepare component configuration
+     *
+     * @return void
      */
-    public function getIsCollapsible()
+    public function prepare()
     {
-        return $this->getData('config/collapsible', $this->collapsible);
+        parent::prepare();
+        foreach ($this->getChildComponents() as $name => $child) {
+            if ($child instanceof Container) {
+                $this->fieldsInContainers += $child->getChildComponents();
+            }
+        }
+
+        $fieldsMeta = $this->getContext()->getDataProvider()->getFieldsMetaInfo($this->getName());
+        foreach ($fieldsMeta as $name => $fieldData) {
+            if (empty($fieldData)) {
+                continue;
+            }
+            $fieldComponent = $this->getComponent($name);
+            $this->prepareField($fieldData, $name, $fieldComponent);
+        }
+
+        $jsConfig = $this->getConfiguration($this);
+        $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig);
     }
 
     /**
-     * @return string
+     * Prepare field component
+     *
+     * @param array $fieldData
+     * @param string $name
+     * @param UiComponentInterface|null $fieldComponent
+     * @return void
+     * @throws \Magento\Framework\Exception\LocalizedException
      */
-    public function getAjaxUrl()
+    protected function prepareField(array $fieldData, $name, UiComponentInterface $fieldComponent = null)
     {
-        return $this->getData('config/source');
+        if ($fieldComponent === null) {
+            if (isset($this->fieldsInContainers[$name])) {
+                $this->updateField($fieldData, $this->fieldsInContainers[$name]);
+                return;
+            }
+            $fieldData = $this->updateDataScope($fieldData, $name);
+            $argument = [
+                'context' => $this->getContext(),
+                'data' => [
+                    'name' => $name,
+                    'config' => $fieldData
+                ]
+            ];
+            $fieldComponent = $this->uiComponentFactory->create($name, 'field', $argument);
+            $fieldComponent->prepare();
+            $this->addComponent($name, $fieldComponent);
+        } else {
+            $this->updateField($fieldData, $fieldComponent);
+        }
     }
 
     /**
-     * @return string
+     * Update field data
+     *
+     * @param array $fieldData
+     * @param UiComponentInterface $component
+     * @return void
      */
-    public function getContent()
+    protected function updateField(array $fieldData, UiComponentInterface $component)
     {
-        return $this->getData('config/content');
+        $config = $component->getData('config');
+        // XML data configuration override configuration coming from the DB
+        $config = array_replace_recursive($fieldData, $config);
+        $config = $this->updateDataScope($config, $component->getName());
+        $component->setData('config', $config);
     }
 
     /**
+     * Update DataScope
+     *
+     * @param array $data
+     * @param string $name
      * @return array
      */
-    public function getChildren()
+    protected function updateDataScope(array $data, $name)
     {
-        return $this->getData('children');
+        if (!isset($data['dataScope'])) {
+            $data['dataScope'] = $name;
+        }
+        return $data;
     }
 }
diff --git a/app/code/Magento/Ui/Component/Form/Fieldset/Factory.php b/app/code/Magento/Ui/Component/Form/Fieldset/Factory.php
index f0b10c0b2dd618c161023307a70cab513e245849..191778de59da1f7813cedb6fa4f7daff481bc477 100644
--- a/app/code/Magento/Ui/Component/Form/Fieldset/Factory.php
+++ b/app/code/Magento/Ui/Component/Form/Fieldset/Factory.php
@@ -5,8 +5,8 @@
  */
 namespace Magento\Ui\Component\Form\Fieldset;
 
-use Magento\Framework\ObjectManagerInterface;
 use Magento\Ui\Component\Form\Fieldset;
+use Magento\Framework\ObjectManagerInterface;
 
 /**
  * Class Factory
diff --git a/app/code/Magento/Ui/Component/Layout.php b/app/code/Magento/Ui/Component/Layout.php
new file mode 100644
index 0000000000000000000000000000000000000000..369701019290432daf1a8e3fc31d7cf0166a4843
--- /dev/null
+++ b/app/code/Magento/Ui/Component/Layout.php
@@ -0,0 +1,89 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\Component;
+
+use Magento\Ui\Component\Layout\LayoutPool;
+use Magento\Framework\View\Element\Template;
+use Magento\Framework\View\Element\UiComponent\LayoutInterface;
+use Magento\Framework\View\Element\UiComponent\ContextInterface;
+
+/**
+ * Class Layout
+ */
+class Layout extends AbstractComponent
+{
+    const NAME = 'layout';
+
+    /**
+     * @var LayoutPool
+     */
+    protected $layoutPool;
+
+    /**
+     * @var string
+     */
+    protected $type;
+
+    /**
+     * @var LayoutInterface
+     */
+    protected $layoutTypeObject;
+
+    /**
+     * @var array
+     */
+    protected $structure = [];
+
+    /**
+     * Constructor
+     *
+     * @param ContextInterface $context
+     * @param LayoutPool $layoutPool
+     * @param string $type
+     * @param array $components
+     * @param array $data
+     */
+    public function __construct(
+        ContextInterface $context,
+        LayoutPool $layoutPool,
+        $type,
+        array $components = [],
+        array $data = []
+    ) {
+        $this->layoutPool = $layoutPool;
+        $this->type = $type;
+        parent::__construct($context, $components, $data);
+    }
+
+    /**
+     * Get component name
+     *
+     * @return string
+     */
+    public function getComponentName()
+    {
+        return static::NAME;
+    }
+
+    /**
+     * Register component and build layout structure
+     *
+     * @inheritdoc
+     */
+    public function prepare()
+    {
+        $this->layoutTypeObject = $this->layoutPool->create($this->type);
+        $this->structure = $this->layoutTypeObject->build($this);
+    }
+
+    /**
+     * @return array
+     */
+    public function getStructure()
+    {
+        return $this->structure;
+    }
+}
diff --git a/app/code/Magento/Ui/Component/Layout/AbstractStructure.php b/app/code/Magento/Ui/Component/Layout/AbstractStructure.php
deleted file mode 100644
index 8fdd8616b7c8b2b22eb3b2b390e06d3d534ed9b8..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/Component/Layout/AbstractStructure.php
+++ /dev/null
@@ -1,564 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\Component\Layout;
-
-use Magento\Framework\View\Element\Template;
-use Magento\Framework\View\Element\Template\Context as TemplateContext;
-use Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface;
-use Magento\Framework\View\Element\UiComponent\ConfigFactory;
-use Magento\Framework\View\Element\UiComponent\Context;
-use Magento\Framework\View\Element\UiElementFactory;
-use Magento\Ui\Component\AbstractView;
-use Magento\Ui\Component\Layout\Tabs\TabInterface;
-use Magento\Ui\ContentType\ContentTypeFactory;
-use Magento\Ui\DataProvider\Factory as DataProviderFactory;
-use Magento\Ui\DataProvider\Manager;
-use Magento\Ui\DataProvider\Metadata;
-
-/**
- * Class AbstractStructure
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
- */
-class AbstractStructure extends AbstractView
-{
-    /**
-     * @var array
-     */
-    protected $structure = [
-        'sections' => [],
-        'areas' => [],
-        'groups' => [],
-        'elements' => [],
-    ];
-
-    /**
-     * @var UiElementFactory
-     */
-    protected $factory;
-
-    /**
-     * Layout Namespace
-     *
-     * @var string
-     */
-    protected $ns;
-
-    /**
-     * @var int
-     */
-    protected $sortInc = 10;
-
-    /**
-     * Constructor
-     *
-     * @param TemplateContext $context
-     * @param Context $renderContext
-     * @param ContentTypeFactory $contentTypeFactory
-     * @param ConfigFactory $configFactory
-     * @param ConfigBuilderInterface $configBuilder
-     * @param DataProviderFactory $dataProviderFactory
-     * @param Manager $dataProviderManager
-     * @param UiElementFactory $factory
-     * @param array $data
-     */
-    public function __construct(
-        TemplateContext $context,
-        Context $renderContext,
-        ContentTypeFactory $contentTypeFactory,
-        ConfigFactory $configFactory,
-        ConfigBuilderInterface $configBuilder,
-        DataProviderFactory $dataProviderFactory,
-        Manager $dataProviderManager,
-        UiElementFactory $factory,
-        array $data = []
-    ) {
-        $this->factory = $factory;
-        parent::__construct(
-            $context,
-            $renderContext,
-            $contentTypeFactory,
-            $configFactory,
-            $configBuilder,
-            $dataProviderFactory,
-            $dataProviderManager,
-            $data
-        );
-    }
-
-    /**
-     * @inheritdoc
-     * @SuppressWarnings(PHPMD.UnusedLocalVariable)
-     */
-    public function prepare()
-    {
-        $this->ns = $this->getData('name');
-
-        $this->initSections();
-        $this->initAreas();
-        $this->initGroups();
-        $this->initElements();
-
-        foreach ($this->getDataSources() as $name => $dataSourceConfig) {
-            $this->processDataSource($dataSourceConfig);
-        }
-
-        $this->processChildBLocks();
-
-        $this->renderContext->getStorage()->addLayoutStructure(
-            $this->getDataScope(),
-            [
-                'children' => $this->structure
-            ]
-        );
-
-        $navBlock = $this->factory->create(
-            \Magento\Ui\Component\Layout\Tabs\Nav::NAME,
-            [
-                'data_scope' => $this->ns
-            ]
-        );
-        if ($this->getData('configuration/tabs_container_name')) {
-            $this->getRenderContext()->getPageLayout()
-                ->addBlock($navBlock, 'tabs_nav', $this->getData('configuration/tabs_container_name'));
-        } else {
-            $this->getRenderContext()->getPageLayout()
-                ->addBlock($navBlock, 'tabs_nav', 'content');
-        }
-    }
-
-    /**
-     * @return string
-     */
-    public function getDataScope()
-    {
-        return $this->ns;
-    }
-
-    /**
-     * Prepare initial structure for sections
-     *
-     * @return void
-     */
-    protected function initSections()
-    {
-        $this->structure['sections'] = [
-            'type' => \Magento\Ui\Component\Layout\Tabs\Nav::NAME,
-            'config' => [
-                'label' => $this->getData('label'),
-            ],
-            'children' => [],
-        ];
-    }
-
-    /**
-     * Prepare initial structure for areas
-     *
-     * @return void
-     */
-    protected function initAreas()
-    {
-        $this->structure['areas'] = [
-            'type' => 'form',
-            'config' => [
-                'namespace' => $this->ns,
-            ],
-            'children' => [],
-        ];
-    }
-
-    /**
-     * Prepare initial structure for groups
-     *
-     * @return void
-     */
-    protected function initGroups()
-    {
-        $this->structure['groups'] = [
-            'children' => [],
-        ];
-    }
-
-    /**
-     * Prepare initial structure for elements
-     *
-     * @return void
-     */
-    protected function initElements()
-    {
-        $this->structure['elements'] = [
-            'children' => [],
-        ];
-    }
-
-    /**
-     * Get registered Data Sources
-     *
-     * @return array
-     */
-    protected function getDataSources()
-    {
-        return $this->getData('data_sources');
-    }
-
-    /**
-     * @param array $dataSourceConfig
-     * @return void
-     * @SuppressWarnings(PHPMD.NPathComplexity)
-     */
-    protected function processDataSource(array $dataSourceConfig)
-    {
-        $id = $this->renderContext->getRequestParam('id');
-        $dataSource = $dataSourceConfig['name'];
-
-        $meta = $this->dataManager->getMetadata($dataSource);
-
-        $this->addArea(
-            $dataSource,
-            [
-                'insertTo' => [
-                    $this->ns . '.sections' => [
-                        'position' => $this->getNextSortInc(),
-                    ],
-                ],
-                'config' => [
-                    'label' => $meta->getLabel(),
-                ]
-            ]
-        );
-        $referenceGroupName = $this->addGroup(
-            $dataSource,
-            [
-                'label' => $meta->getLabel()
-            ]
-        );
-
-        $elements = $meta->getFields();
-        uasort($elements, [$this, 'sortChildren']);
-        foreach ($elements as $name => $element) {
-            if (isset($element['visible']) && $element['visible'] === 'false') {
-                continue;
-            }
-            if ($name != Metadata::CHILD_DATA_SOURCES) {
-                $collection = & $this->structure['elements'];
-                $this->addElementToCollection($collection, $name, "{$dataSource}.{$name}", $element);
-
-                $referenceName = "{$this->ns}.elements.{$name}";
-                $this->addElementToGroup($dataSource, $name, $referenceName, $element);
-            }
-        }
-
-        $this->addToArea($dataSource, $referenceGroupName);
-
-        $children = $meta->get(Metadata::CHILD_DATA_SOURCES);
-        foreach ($children as $childName => $childMeta) {
-            $this->processChildDataSource($dataSource, $childName, $childMeta);
-        }
-
-        $preparedData = [];
-        $data = $id ? $this->dataManager->getData($dataSource, ['entity_id' => $id]) : [];
-        if ($data) {
-            $preparedData[$dataSource] = [];
-            foreach (array_shift($data) as $key => $value) {
-                $preparedData[$dataSource][$key] = $value;
-            }
-        }
-
-        $this->renderContext->getStorage()->addDataSource(
-            $this->getData('name'),
-            [
-                'data' => $preparedData,
-                'config' => $dataSourceConfig,
-            ]
-        );
-    }
-
-    /**
-     * @param string $dataSource
-     * @param string $childName
-     * @param \Magento\Ui\DataProvider\Metadata $childMeta
-     * @return void
-     */
-    protected function processChildDataSource($dataSource, $childName, \Magento\Ui\DataProvider\Metadata $childMeta)
-    {
-        $this->addArea(
-            $childName,
-            [
-                'insertTo' => [
-                    $this->ns . '.sections' => [
-                        'position' => $this->getNextSortInc(),
-                    ],
-                ],
-                'config' => [
-                    'label' => $childMeta->getLabel(),
-                ]
-            ]
-        );
-        $referenceChildGroupName = $this->addGroup(
-            $childName,
-            [
-                'label' => $childMeta->getLabel()
-            ]
-        );
-        $this->addToArea($childName, $referenceChildGroupName);
-
-        $itemTemplate = [
-            'type' => $this->ns,
-            'isTemplate' => true,
-            'component' => 'Magento_Ui/js/form/components/collection/item',
-            'childType' => 'group',
-            'config' => [
-                'label' => __('New ' . $childMeta->getLabel()),
-            ],
-        ];
-
-        $elements = $childMeta->getFields();
-        uasort($elements, [$this, 'sortChildren']);
-        foreach ($elements as $name => $element) {
-            if (isset($element['visible']) && $element['visible'] === 'false') {
-                continue;
-            }
-            $this->addElementToCollection($itemTemplate, $name, $name, $element);
-        }
-
-        $referenceCollectionName = $this->addCollection(
-            $childName . 'Collection',
-            "{$dataSource}.{$childName}",
-            [
-                'active' => 1,
-                'label' => $childMeta->getLabel(),
-                'removeLabel' => __('Remove ' . $childMeta->getLabel()),
-                'removeMessage' => __('Are you sure you want to delete this item?'),
-                'addLabel' => __('Add New ' . $childMeta->getLabel()),
-                'itemTemplate' => 'item_template'
-            ]
-        );
-        $this->addTemplateToCollection($childName . 'Collection', 'item_template', $itemTemplate);
-
-        $this->structure['groups']['children'][$childName]['children'][] = $referenceCollectionName;
-    }
-
-    /**
-     * @throws \Exception
-     * @return void
-     */
-    protected function processChildBlocks()
-    {
-        //Add child blocks content
-        foreach ($this->getData('child_blocks') as $blockName => $childBlock) {
-            /** @var TabInterface $childBlock */
-            if (!($childBlock instanceof TabInterface)) {
-                throw new \Exception(__('"%1" tab should implement TabInterface', $blockName));
-            }
-            if (!$childBlock->canShowTab()) {
-                continue;
-            }
-            $childBlock->setData('target_form', $this->getDataScope());
-            $sortOrder = $childBlock->hasSortOrder() ? $childBlock->getSortOrder() : $this->getNextSortInc();
-            $this->addArea(
-                $blockName,
-                [
-                    'insertTo' => [
-                        $this->ns . '.sections' => [
-                            'position' => (int)$sortOrder,
-                        ],
-                    ],
-                    'config' => [
-                        'label' => $childBlock->getTabTitle(),
-                    ]
-                ]
-            );
-
-            $config = [
-                'label' => $childBlock->getTabTitle(),
-            ];
-            if ($childBlock->isAjaxLoaded()) {
-                $config['source'] = $childBlock->getTabUrl();
-            } else {
-                $config['content'] = $childBlock->toHtml();
-            }
-            $referenceGroupName = $this->addGroup($blockName, $config, 'html_content');
-            $this->addToArea($blockName, $referenceGroupName);
-        }
-    }
-
-    /**
-     * @param string $name
-     * @param array $config
-     * @return string
-     */
-    protected function addArea($name, array $config = [])
-    {
-        $config['type'] = 'tab';
-        $this->structure['areas']['children'][$name] = $config;
-        return "{$this->ns}.areas.{$name}";
-    }
-
-    /**
-     * @param string $areaName
-     * @param string $itemName
-     * @return void
-     */
-    protected function addToArea($areaName, $itemName)
-    {
-        $this->structure['areas']['children'][$areaName]['children'][] = $itemName;
-    }
-
-    /**
-     * @param string $groupName
-     * @param array $config
-     * @param string $type
-     * @return string
-     */
-    protected function addGroup($groupName, array $config = [], $type = 'fieldset')
-    {
-        $this->structure['groups']['children'][$groupName] = [
-            'type' => $type,
-            'config' => $config,
-        ];
-        return "{$this->ns}.groups.{$groupName}";
-    }
-
-    /**
-     * @param string $groupName
-     * @param string $elementName
-     * @param string $referenceElementName
-     * @param array $element
-     * @return void
-     */
-    protected function addElementToGroup($groupName, $elementName, $referenceElementName, array $element)
-    {
-        if (isset($element['fieldGroup'])) {
-            if ($elementName === $element['fieldGroup']) {
-                $this->structure['groups']['children'][$groupName]['children'][] = $referenceElementName;
-            }
-        } else {
-            $this->structure['groups']['children'][$groupName]['children'][] = $referenceElementName;
-        }
-    }
-
-    /**
-     * @param array $collection
-     * @param string $elementName
-     * @param string $dataScope
-     * @param array $element
-     * @return string
-     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
-     */
-    protected function addElementToCollection(array & $collection, $elementName, $dataScope, array $element)
-    {
-        $collection['children'][$elementName] = [
-            'type' => 'group',
-        ];
-        if (isset($element['fieldGroup'])) {
-            $elementName = $element['fieldGroup'];
-            if ($elementName === $element['fieldGroup']) {
-                $collection['children'][$elementName]['config'] = [
-                    'displayArea' => $element['displayArea'],
-                ];
-            }
-        } else {
-            $collection['children'][$elementName]['config'] = [
-                'displayArea' => $element['displayArea'],
-            ];
-        }
-
-        if (isset($element['constraints'])) {
-            if (isset($element['constraints']['validate'])) {
-                $element['validation'] = $element['constraints']['validate'];
-            }
-            if (isset($element['constraints']['filter'])) {
-                foreach ($element['constraints']['filter'] as $filter) {
-                    $element['listeners'] = [
-                        "data:" . $filter['on'] => [
-                            'filter' => [$filter['by']],
-                        ],
-                    ];
-                }
-            }
-            unset($element['constraints']);
-        }
-        if (isset($element['size'])) {
-            $collection['children'][$elementName]['dataScope'] = $dataScope;
-            $size = (int)$element['size'];
-            for ($i = 0; $i < $size; $i++) {
-                $collection['children'][$elementName]['children'][] = [
-                    'type' => $element['formElement'],
-                    'dataScope' => (string)$i,
-                    'config' => $element,
-                ];
-                if (isset($element['validation']['required-entry'])) {
-                    unset($element['validation']['required-entry']);
-                }
-            }
-        } else {
-            $collection['children'][$elementName]['children'][] = [
-                'type' => $element['formElement'],
-                'dataScope' => $dataScope,
-                'config' => $element,
-            ];
-        }
-    }
-
-    /**
-     * @param string $collectionName
-     * @param string $dataScope
-     * @param array $config
-     * @return string
-     */
-    protected function addCollection($collectionName, $dataScope, array $config = [])
-    {
-        $this->structure['groups']['children'][$collectionName] = [
-            'type' => 'collection',
-            'dataScope' => $dataScope,
-            'config' => $config,
-        ];
-        return "{$this->ns}.groups.{$collectionName}";
-    }
-
-    /**
-     * @param string $collectionName
-     * @param string $templateName
-     * @param array $template
-     * @return void
-     */
-    protected function addTemplateToCollection($collectionName, $templateName, $template)
-    {
-        $this->structure['groups']['children'][$collectionName]['children'][$templateName] = $template;
-    }
-
-    /**
-     * @return int
-     */
-    protected function getNextSortInc()
-    {
-        $this->sortInc += 10;
-        return $this->sortInc;
-    }
-
-    /**
-     * Sort child elements
-     *
-     * @param array $one
-     * @param array $two
-     * @return int
-     * @SuppressWarnings(PHPMD.NPathComplexity)
-     */
-    public function sortChildren(array $one, array $two)
-    {
-        if (!isset($one['sortOrder'])) {
-            return 1;
-        }
-        if (!isset($two['sortOrder'])) {
-            return -1;
-        }
-        $sortOrderA = isset($one['sortOrder']) ? intval($one['sortOrder']) : -1;
-        $sortOrderB = isset($two['sortOrder']) ? intval($two['sortOrder']) : -1;
-        if ($sortOrderA == $sortOrderB) {
-            return 0;
-        }
-        return ($sortOrderA < $sortOrderB) ? -1 : 1;
-    }
-}
diff --git a/app/code/Magento/Ui/Component/Layout/Generator/Structure.php b/app/code/Magento/Ui/Component/Layout/Generator/Structure.php
new file mode 100644
index 0000000000000000000000000000000000000000..c26b9c40664a3bd93122a7f6bee509264fcb8049
--- /dev/null
+++ b/app/code/Magento/Ui/Component/Layout/Generator/Structure.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\Component\Layout\Generator;
+
+use Magento\Ui\Component\Layout\LayoutPool;
+use Magento\Framework\View\Element\UiComponentInterface;
+use Magento\Framework\View\Element\UiComponent\LayoutInterface;
+
+/**
+ * Class Structure
+ */
+class Structure
+{
+    /**
+     * @var LayoutPool
+     */
+    protected $layoutPool;
+
+    /**
+     * Constructor
+     *
+     * @param LayoutPool $layoutPool
+     */
+    public function __construct(LayoutPool $layoutPool)
+    {
+        $this->layoutPool = $layoutPool;
+    }
+
+    /**
+     * Build component structure and retrieve
+     *
+     * @param UiComponentInterface $component
+     * @return array
+     */
+    public function generate(UiComponentInterface $component)
+    {
+        /** @var LayoutInterface $layout */
+        if (!$layoutDefinition = $component->getData('layout')) {
+            $layoutDefinition = ['type' => 'generic'];
+        }
+        $layout = $this->layoutPool->create($layoutDefinition['type'], $layoutDefinition);
+
+        return $layout->build($component);
+    }
+}
diff --git a/app/code/Magento/Ui/Component/Layout/Generic.php b/app/code/Magento/Ui/Component/Layout/Generic.php
new file mode 100644
index 0000000000000000000000000000000000000000..04b0fbabe28de22f1799aa4dc43bd1740022e3bf
--- /dev/null
+++ b/app/code/Magento/Ui/Component/Layout/Generic.php
@@ -0,0 +1,87 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\Component\Layout;
+
+use Magento\Framework\View\Element\UiComponent\DataSourceInterface;
+use Magento\Framework\View\Element\UiComponent\JsConfigInterface;
+use Magento\Framework\View\Element\UiComponent\LayoutInterface;
+use Magento\Framework\View\Element\UiComponentInterface;
+
+/**
+ * Class Generic
+ */
+class Generic implements LayoutInterface
+{
+    /**
+     * Generate Java Script configuration element
+     *
+     * @param UiComponentInterface $component
+     * @return array
+     */
+    public function build(UiComponentInterface $component)
+    {
+        $children = [];
+        $context = $component->getContext();
+        $this->addChildren($children, $component, $component->getName());
+        $dataSources = $component->getDataSourceData();
+        $configuration = [
+            'types' => $context->getComponentsDefinitions(),
+            'components' => [
+                $context->getNamespace() => [
+                    'children' => array_merge($children, $dataSources)
+                ]
+            ]
+        ];
+        return $configuration;
+    }
+
+    /**
+     * Add children data
+     *
+     * @param array $topNode
+     * @param UiComponentInterface $component
+     * @param string $componentType
+     * @return void
+     */
+    protected function addChildren(
+        array &$topNode,
+        UiComponentInterface $component,
+        $componentType
+    ) {
+        $childrenNode = [];
+        $childComponents = $component->getChildComponents();
+        if (!empty($childComponents)) {
+            /** @var UiComponentInterface $child */
+            foreach ($childComponents as $child) {
+                if ($child instanceof DataSourceInterface) {
+                    continue;
+                }
+                self::addChildren($childrenNode, $child, $child->getComponentName());
+            }
+        }
+        /** @var JsConfigInterface $component */
+        $config = $component->getJsConfig();
+        if (is_string($config)) {
+            $topNode[] = $config;
+        } else {
+            $nodeData = [
+                'type' => $componentType,
+                'name' => $component->getName(),
+            ];
+            if (!empty($childrenNode)) {
+                $nodeData['children'] = $childrenNode;
+            }
+            if (isset($config['dataScope'])) {
+                $nodeData['dataScope'] = $config['dataScope'];
+                unset($config['dataScope']);
+            }
+            if (!empty($config)) {
+                $nodeData['config'] = $config;
+            }
+            $topNode[] = $nodeData;
+        }
+    }
+}
diff --git a/app/code/Magento/Ui/Component/Layout/Group.php b/app/code/Magento/Ui/Component/Layout/Group.php
deleted file mode 100644
index 4b3eb842c56f9805ae8647c3376b4334ead92199..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/Component/Layout/Group.php
+++ /dev/null
@@ -1,22 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\Component\Layout;
-
-use Magento\Ui\Component\AbstractView;
-
-/**
- * Class Group
- */
-class Group extends AbstractView
-{
-    /**
-     * @return string
-     */
-    public function getIsRequired()
-    {
-        return $this->getData('required') ? 'required' : '';
-    }
-}
diff --git a/app/code/Magento/Ui/Component/Layout/LayoutPool.php b/app/code/Magento/Ui/Component/Layout/LayoutPool.php
new file mode 100644
index 0000000000000000000000000000000000000000..b15a513ff42c604797718731bb16798f670b95a4
--- /dev/null
+++ b/app/code/Magento/Ui/Component/Layout/LayoutPool.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\Component\Layout;
+
+use Magento\Framework\ObjectManagerInterface;
+use Magento\Framework\View\Element\UiComponent\LayoutInterface;
+
+/**
+ * Class LayoutPool
+ */
+class LayoutPool
+{
+    const DEFAULT_CLASS = 'Magento\Ui\Component\Layout\Generic';
+
+    /**
+     * Layouts pool
+     *
+     * @var array
+     */
+    protected $types;
+
+    /**
+     * @var ObjectManagerInterface
+     */
+    protected $objectManager;
+
+    /**
+     * Constructor
+     *
+     * @param ObjectManagerInterface $objectManager
+     * @param array $types
+     */
+    public function __construct(
+        ObjectManagerInterface $objectManager,
+        array $types = []
+    ) {
+        $this->objectManager = $objectManager;
+        $this->types = $types;
+    }
+
+    /**
+     * Get layout by type
+     *
+     * @param string $layoutType
+     * @param array $arguments
+     * @return LayoutInterface
+     */
+    public function create($layoutType, array $arguments = [])
+    {
+        if (!isset($this->types[$layoutType])) {
+            throw new \InvalidArgumentException(sprintf('Unknown layout type "%s"', $layoutType));
+        }
+        $defArgs = $this->types[$layoutType];
+        $class = isset($defArgs['class']) ? $defArgs['class'] : self::DEFAULT_CLASS;
+        unset($defArgs['class']);
+        if ($defArgs) {
+            $arguments = array_merge($defArgs, $arguments);
+        }
+        return $this->objectManager->create($class, $arguments);
+    }
+}
diff --git a/app/code/Magento/Ui/Component/Layout/Tabs.php b/app/code/Magento/Ui/Component/Layout/Tabs.php
index d56881d3904c3b2f8134020ffbc59b3f7b93f506..ffdfc631486b59dff94fa9b0538e32af9b72641f 100644
--- a/app/code/Magento/Ui/Component/Layout/Tabs.php
+++ b/app/code/Magento/Ui/Component/Layout/Tabs.php
@@ -5,13 +5,396 @@
  */
 namespace Magento\Ui\Component\Layout;
 
+use Magento\Framework\Exception\LocalizedException;
+use Magento\Framework\View\Element\Template;
+use Magento\Ui\Component\Layout\Tabs\TabInterface;
+use Magento\Framework\View\Element\UiComponentFactory;
+use Magento\Framework\View\Element\UiComponentInterface;
+use Magento\Framework\View\Element\UiComponent\LayoutInterface;
+use Magento\Framework\View\Element\UiComponent\JsConfigInterface;
 
 /**
  * Class Tabs
- *
- * @package Magento\Ui\Component\Layout
  */
-class Tabs extends AbstractStructure
+class Tabs extends Generic implements LayoutInterface
 {
-    const NAME = 'tabs';
+    /**
+     * @var string
+     */
+    protected $navContainerName;
+
+    /**
+     * @var UiComponentInterface
+     */
+    protected $component;
+
+    /**
+     * @var string
+     */
+    protected $namespace;
+
+    /**
+     * @var array
+     */
+    protected $structure = [];
+
+    /**
+     * @var int
+     */
+    protected $sortIncrement = 10;
+
+    /**
+     * @var UiComponentFactory
+     */
+    protected $uiComponentFactory;
+
+    /**
+     * Constructor
+     *
+     * @param UiComponentFactory $uiComponentFactory
+     * @param null|string $navContainerName
+     */
+    public function __construct(UiComponentFactory $uiComponentFactory, $navContainerName = null)
+    {
+        $this->navContainerName = $navContainerName;
+        $this->uiComponentFactory = $uiComponentFactory;
+    }
+
+    /**
+     * Build
+     *
+     * @param UiComponentInterface $component
+     * @return array
+     */
+    public function build(UiComponentInterface $component)
+    {
+        $this->component = $component;
+        $this->namespace = $component->getContext()->getNamespace();
+
+        $this->addNavigationBlock();
+
+        // Initialization of structure components
+        $this->initSections();
+        $this->initAreas();
+
+        return parent::build($component);
+    }
+
+    /**
+     * Add children data
+     *
+     * @param array $topNode
+     * @param UiComponentInterface $component
+     * @param string $componentType
+     * @return void
+     * @throws \Magento\Framework\Exception\LocalizedException
+     */
+    protected function addChildren(array &$topNode, UiComponentInterface $component, $componentType)
+    {
+        $childrenAreas = [];
+        $collectedComponents = [];
+
+        foreach ($component->getContext()->getDataProvider()->getMeta() as $name => $meta) {
+            $childComponent = $component->getComponent($name);
+            if (null === $childComponent) {
+                continue;
+            }
+            $collectedComponents[$childComponent->getName()] = true;
+
+            if (isset($meta['is_collection']) && $meta['is_collection'] === true) {
+                $label = $childComponent->getData('config/label');
+                $this->component->getContext()->addComponentDefinition(
+                    'collection',
+                    [
+                        'component' => 'Magento_Ui/js/form/components/collection',
+                        'extends' => $this->namespace
+                    ]
+                );
+
+                /**
+                 * @var UiComponentInterface $childComponent
+                 * @var array $structure
+                 */
+                list($childComponent, $structure) = $this->prepareChildComponents($childComponent, $name);
+
+                $childrenStructure = $structure[$name]['children'];
+
+                $structure[$name]['children'] = [
+                    $name . '_collection' => [
+                        'type' => 'collection',
+                        'config' => [
+                            'active' => 1,
+                            'removeLabel' => __('Remove ' . $label),
+                            'addLabel' => __('Add New ' . $label),
+                            'removeMessage' => $childComponent->getData('config/removeMessage'),
+                            'itemTemplate' => 'item_template',
+                        ],
+                        'children' => [
+                            'item_template' => ['type' => $this->namespace,
+                                'isTemplate' => true,
+                                'component' => 'Magento_Ui/js/form/components/collection/item',
+                                'childType' => 'group',
+                                'config' => [
+                                    'label' => __('New ' . $label),
+                                ],
+                                'children' => $childrenStructure
+                            ]
+                        ]
+                    ]
+                ];
+            } else {
+                /**
+                 * @var UiComponentInterface $childComponent
+                 * @var array $structure
+                 */
+                list($childComponent, $structure) = $this->prepareChildComponents($childComponent, $name);
+            }
+
+            $tabComponent = $this->createTabComponent($childComponent, $name);
+
+            $childrenAreas[$name] = [
+                'type' => $tabComponent->getComponentName(),
+                'dataScope' => 'data.' . $name,
+                'config' => isset($meta['config']) ? $meta['config'] : [],
+                'insertTo' => [
+                    $this->namespace . '.sections' => [
+                        'position' => $this->getNextSortIncrement()
+                    ]
+                ],
+                'children' => $structure,
+            ];
+        }
+
+        $this->addWrappedBlock($childrenAreas, $component, $collectedComponents);
+
+        $this->structure[static::AREAS_KEY]['children'] = $childrenAreas;
+        $topNode = $this->structure;
+    }
+
+    /**
+     * Add wrapped layout block
+     *
+     * @param array $areas
+     * @param UiComponentInterface $component
+     * @param array $collectedComponents
+     * @return void
+     */
+    protected function addWrappedBlock(array &$areas, UiComponentInterface $component, array $collectedComponents)
+    {
+        /** @var \Magento\Ui\Component\Wrapper\Block $childComponent */
+        foreach ($component->getChildComponents() as $name => $childComponent) {
+            /** @var TabInterface $block */
+            $block = $childComponent->getBlock();
+            if (isset($collectedComponents[$name]) || !($block instanceof TabInterface) || !$block->canShowTab()) {
+                continue;
+            }
+            $block->setData('target_form', $this->namespace);
+
+            $config = [];
+            if ($block->isAjaxLoaded()) {
+                $config['url'] = $block->getTabUrl();
+            } else {
+                $config['content'] = $block->toHtml();
+            }
+
+            $tabComponent = $this->createTabComponent($childComponent, $name);
+            $areas[$name] = [
+                'type' => $tabComponent->getComponentName(),
+                'dataScope' => $name,
+                'insertTo' => [
+                    $this->namespace . '.sections' => [
+                        'position' => $block->hasSortOrder() ? $block->getSortOrder() : $this->getNextSortIncrement()
+                    ]
+                ],
+                'config' => [
+                    'label' => $block->getTabTitle()
+                ],
+                'children' => [
+                    $name => [
+                        'type' => 'html_content',
+                        'dataScope' => $name,
+                        'config' => $config,
+                    ]
+                ],
+            ];
+        }
+
+        $this->component->getContext()->addComponentDefinition(
+            'html_content',
+            [
+                'component' => 'Magento_Ui/js/form/components/html',
+                'extends' => $this->namespace
+            ]
+        );
+    }
+
+    /**
+     * Create tab component
+     *
+     * @param UiComponentInterface $childComponent
+     * @param string $name
+     * @return UiComponentInterface
+     * @throws \Magento\Framework\Exception\LocalizedException
+     */
+    protected function createTabComponent(UiComponentInterface $childComponent, $name)
+    {
+        $tabComponent = $this->uiComponentFactory->create(
+            $name,
+            'tab',
+            [
+                'context' => $this->component->getContext(),
+                'components' => [$childComponent->getName() => $childComponent]
+            ]
+        );
+        $tabComponent->prepare();
+        $this->component->addComponent($name, $tabComponent);
+
+        return $tabComponent;
+    }
+
+    /**
+     * To prepare the structure of child components
+     *
+     * @param UiComponentInterface $component
+     * @param string $parentName
+     * @return array
+     */
+    protected function prepareChildComponents(UiComponentInterface $component, $parentName)
+    {
+        $name = $component->getName();
+        $childComponents = $component->getChildComponents();
+
+        $childrenStructure = [];
+        foreach ($childComponents as $childName => $child) {
+            $isVisible = $child->getData('config/visible');
+            if ($isVisible !== null && $isVisible == 0) {
+                continue;
+            }
+            /**
+             * @var UiComponentInterface $childComponent
+             * @var array $childStructure
+             */
+            list($childComponent, $childStructure) = $this->prepareChildComponents($child, $component->getName());
+            $childrenStructure = array_merge($childrenStructure, $childStructure);
+            $component->addComponent($childName, $childComponent);
+        }
+
+        $structure = [
+            $name => [
+                'type' => $component->getComponentName(),
+                'name' => $component->getName(),
+                'children' => $childrenStructure
+            ]
+        ];
+
+        /** @var JsConfigInterface $component */
+        list($config, $dataScope) = $this->prepareConfig((array) $component->getJsConfig(), $name, $parentName);
+
+        if ($dataScope !== false) {
+            $structure[$name]['dataScope'] = $dataScope;
+        }
+        $structure[$name]['config'] = $config;
+
+        return [$component, $structure];
+    }
+
+    /**
+     * Prepare config
+     *
+     * @param array $config
+     * @param string $name
+     * @param string $parentName
+     * @return array
+     */
+    protected function prepareConfig(array $config, $name, $parentName)
+    {
+        $dataScope = false;
+        if (!isset($config['displayArea'])) {
+            $config['displayArea'] = 'body';
+        }
+        if (isset($config['dataScope'])) {
+            $dataScope = $config['dataScope'];
+            unset($config['dataScope']);
+        } else if ($name !== $parentName) {
+            $dataScope = $name;
+        }
+
+        return [$config, $dataScope];
+    }
+
+    /**
+     * Prepare initial structure for sections
+     *
+     * @return void
+     */
+    protected function initSections()
+    {
+        $this->structure[static::SECTIONS_KEY] = [
+            'type' => 'nav',
+            'config' => [
+                'label' => $this->component->getData('label'),
+            ],
+            'children' => [],
+        ];
+    }
+
+    /**
+     * Prepare initial structure for areas
+     *
+     * @return void
+     */
+    protected function initAreas()
+    {
+        $this->structure[static::AREAS_KEY] = [
+            'type' => $this->namespace,
+            'config' => [
+                'namespace' => $this->namespace,
+            ],
+            'children' => [],
+        ];
+    }
+
+    /**
+     * Add navigation block
+     *
+     * @return void
+     */
+    protected function addNavigationBlock()
+    {
+        $pageLayout = $this->component->getContext()->getPageLayout();
+        /** @var \Magento\Ui\Component\Layout\Tabs\Nav $navBlock */
+        if (isset($this->navContainerName)) {
+            $navBlock = $pageLayout->addBlock(
+                'Magento\Ui\Component\Layout\Tabs\Nav',
+                'tabs_nav',
+                $this->navContainerName
+            );
+        } else {
+            $navBlock = $pageLayout->addBlock('Magento\Ui\Component\Layout\Tabs\Nav', 'tabs_nav', 'content');
+        }
+        $navBlock->setTemplate('Magento_Ui::layout/tabs/nav/default.phtml');
+        $navBlock->setData('data_scope', $this->namespace);
+
+        $this->component->getContext()->addComponentDefinition(
+            'nav',
+            [
+                'component' => 'Magento_Ui/js/form/components/tab_group',
+                'config' => [
+                    'template' => 'ui/tab'
+                ],
+                'extends' => $this->namespace
+            ]
+        );
+    }
+
+    /**
+     * Get next sort increment
+     *
+     * @return int
+     */
+    protected function getNextSortIncrement()
+    {
+        $this->sortIncrement += 10;
+        return $this->sortIncrement;
+    }
 }
diff --git a/app/code/Magento/Ui/Component/Layout/Tabs/Nav.php b/app/code/Magento/Ui/Component/Layout/Tabs/Nav.php
index 885eb69e277de40df6f7d45d4c41928840ea6385..7c93e19f9a0d8653927119f5d8a94d205e41c59c 100644
--- a/app/code/Magento/Ui/Component/Layout/Tabs/Nav.php
+++ b/app/code/Magento/Ui/Component/Layout/Tabs/Nav.php
@@ -5,12 +5,12 @@
  */
 namespace Magento\Ui\Component\Layout\Tabs;
 
-use Magento\Ui\Component\AbstractView;
+use Magento\Framework\View\Element\Template;
 
 /**
  * Class Nav
  */
-class Nav extends AbstractView
+class Nav extends Template
 {
-    const NAME = 'nav';
+    //
 }
diff --git a/app/code/Magento/Ui/Component/Layout/Tabs/Tab.php b/app/code/Magento/Ui/Component/Layout/Tabs/Tab.php
index 4428717e8bc0774656adeaa07d8644e84f49efc0..ac3c530df89b7dcb80879a0c5a9c1a53cf447cd6 100644
--- a/app/code/Magento/Ui/Component/Layout/Tabs/Tab.php
+++ b/app/code/Magento/Ui/Component/Layout/Tabs/Tab.php
@@ -5,21 +5,105 @@
  */
 namespace Magento\Ui\Component\Layout\Tabs;
 
-use Magento\Ui\Component\AbstractView;
+use Magento\Ui\Component\AbstractComponent;
 
 /**
  * Class Tab
  */
-class Tab extends AbstractView
+class Tab extends AbstractComponent implements TabInterface
 {
+    const NAME = 'tab';
+
+    /**
+     * Get component name
+     *
+     * @return string
+     */
+    public function getComponentName()
+    {
+        return static::NAME;
+    }
+
+    /**
+     * Prepare component configuration
+     *
+     * @return void
+     */
+    public function prepare()
+    {
+        parent::prepare();
+
+        $jsConfig = $this->getConfiguration($this);
+        $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig);
+    }
+
+    /**
+     * Return Tab label
+     *
+     * @return string
+     */
+    public function getTabLabel()
+    {
+        return $this->getData('tab_label');
+    }
+
+    /**
+     * Return Tab title
+     *
+     * @return string
+     */
+    public function getTabTitle()
+    {
+        return $this->getData('tab_title');
+    }
+
+    /**
+     * Tab class getter
+     *
+     * @return string
+     */
+    public function getTabClass()
+    {
+        return $this->getData('tab_class');
+    }
+
     /**
-     * Render content
+     * Return URL link to Tab content
      *
-     * @param array $data
      * @return string
      */
-    public function render(array $data = [])
+    public function getTabUrl()
+    {
+        return $this->getData('tab_url');
+    }
+
+    /**
+     * Tab should be loaded trough Ajax call
+     *
+     * @return bool
+     */
+    public function isAjaxLoaded()
+    {
+        return $this->getData('is_ajax_loaded');
+    }
+
+    /**
+     * Can show tab in tabs
+     *
+     * @return boolean
+     */
+    public function canShowTab()
+    {
+        return $this->getData('can_show_tab');
+    }
+
+    /**
+     * Tab is hidden
+     *
+     * @return boolean
+     */
+    public function isHidden()
     {
-        //
+        return $this->getData('is_hidden');
     }
 }
diff --git a/app/code/Magento/Ui/Component/Layout/Tabs/TabInterface.php b/app/code/Magento/Ui/Component/Layout/Tabs/TabInterface.php
index 1e65e984b0732f219b72810c72ba7f68f2a0b05e..cb47ad3afabab2d54745e8ec276bbce32a648617 100644
--- a/app/code/Magento/Ui/Component/Layout/Tabs/TabInterface.php
+++ b/app/code/Magento/Ui/Component/Layout/Tabs/TabInterface.php
@@ -3,14 +3,11 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
+namespace Magento\Ui\Component\Layout\Tabs;
 
 /**
- * Tab Interface
- *
- * @author      Magento Core Team <core@magentocommerce.com>
+ * Interface TabInterface
  */
-namespace Magento\Ui\Component\Layout\Tabs;
-
 interface TabInterface
 {
     /**
diff --git a/app/code/Magento/Ui/Component/Layout/Tabs/TabWrapper.php b/app/code/Magento/Ui/Component/Layout/Tabs/TabWrapper.php
index 6c0cd88e0a0d3397faf30676f44f537aa5989e66..bccdc5eda3c3da42fb423d13bfa734fad5521616 100644
--- a/app/code/Magento/Ui/Component/Layout/Tabs/TabWrapper.php
+++ b/app/code/Magento/Ui/Component/Layout/Tabs/TabWrapper.php
@@ -3,11 +3,13 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-
 namespace Magento\Ui\Component\Layout\Tabs;
 
 use Magento\Framework\View\Element\Text\ListText;
 
+/**
+ * Class TabWrapper
+ */
 class TabWrapper extends ListText implements TabInterface
 {
     /**
diff --git a/app/code/Magento/Ui/Component/Listing.php b/app/code/Magento/Ui/Component/Listing.php
index 6d8437a886c5e531522c59fe1fae4e13f7461ab3..d84fd74cf278d59f688832bc2bc3bb1bfe114671 100644
--- a/app/code/Magento/Ui/Component/Listing.php
+++ b/app/code/Magento/Ui/Component/Listing.php
@@ -5,262 +5,102 @@
  */
 namespace Magento\Ui\Component;
 
-use Magento\Framework\View\Element\Template\Context as TemplateContext;
-use Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface;
-use Magento\Framework\View\Element\UiComponent\ConfigFactory;
-use Magento\Framework\View\Element\UiComponent\Context;
-use Magento\Ui\Component\Control\ActionPool;
-use Magento\Ui\Component\Listing\OptionsFactory;
-use Magento\Ui\Component\Listing\RowPool;
-use Magento\Ui\ContentType\ContentTypeFactory;
-use Magento\Ui\DataProvider\Factory as DataProviderFactory;
-use Magento\Ui\DataProvider\Manager;
+use Magento\Ui\Component\Listing\Columns;
+use Magento\Ui\Component\Listing\Columns\Column;
+use Magento\Framework\View\Element\UiComponent\DataSourceInterface;
 
 /**
  * Class Listing
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
-class Listing extends AbstractView
+class Listing extends AbstractComponent
 {
-    /**
-     * Options provider key in data array
-     */
-    const OPTIONS_PROVIDER_KEY = 'options_provider';
-
-    /**
-     * Row data provider key in data array
-     */
-    const ROW_DATA_PROVIDER_KEY = 'row_data_provider';
-
-    /**
-     * Data provider row pool
-     *
-     * @var RowPool
-     */
-    protected $dataProviderRowPool;
-
-    /**
-     * Page action pool
-     *
-     * @var ActionPool
-     */
-    protected $actionPool;
+    const NAME = 'listing';
 
     /**
-     * Constructor
+     * Get component name
      *
-     * @param TemplateContext $context
-     * @param Context $renderContext
-     * @param ContentTypeFactory $contentTypeFactory
-     * @param ConfigFactory $configFactory
-     * @param ConfigBuilderInterface $configBuilder
-     * @param DataProviderFactory $dataProviderFactory
-     * @param Manager $dataProviderManager
-     * @param OptionsFactory $optionsFactory
-     * @param ActionPool $actionPool
-     * @param RowPool $dataProviderRowPool
-     * @param array $data
-     * @SuppressWarnings(PHPMD.ExcessiveParameterList)
+     * @return string
      */
-    public function __construct(
-        TemplateContext $context,
-        Context $renderContext,
-        ContentTypeFactory $contentTypeFactory,
-        ConfigFactory $configFactory,
-        ConfigBuilderInterface $configBuilder,
-        DataProviderFactory $dataProviderFactory,
-        Manager $dataProviderManager,
-        OptionsFactory $optionsFactory,
-        ActionPool $actionPool,
-        RowPool $dataProviderRowPool,
-        array $data = []
-    ) {
-        $this->actionPool = $actionPool;
-        $this->optionsFactory = $optionsFactory;
-        $this->dataProviderRowPool = $dataProviderRowPool;
-        parent::__construct(
-            $context,
-            $renderContext,
-            $contentTypeFactory,
-            $configFactory,
-            $configBuilder,
-            $dataProviderFactory,
-            $dataProviderManager,
-            $data
-        );
+    public function getComponentName()
+    {
+        return static::NAME;
     }
 
     /**
-     * Prepare custom data
+     * Register component and it's page main actions
      *
      * @return void
      */
     public function prepare()
     {
-        $meta = $this->getMeta();
-        $defaultConfigData = $this->getDefaultConfiguration();
-
-        if ($this->hasData('configuration')) {
-            $configData = $this->getData('configuration');
-            if (!empty($configData['page_actions'])) {
-                foreach ($configData['page_actions'] as $key => $action) {
-                    $defaultConfigData['page_actions'][$key] = isset($configData['page_actions'])
-                        ? array_replace($defaultConfigData['page_actions'][$key], $configData['page_actions'][$key])
-                        : $defaultConfigData['page_actions'][$key];
-                }
-            }
-            unset($configData['page_actions']);
-            $defaultConfigData = array_merge($defaultConfigData, $configData);
-        }
-
-        foreach ($defaultConfigData['page_actions'] as $key => $action) {
-            $this->actionPool->add($key, $action, $this);
-        }
-        unset($defaultConfigData['page_actions']);
-
-        $this->prepareConfiguration($defaultConfigData, $this->getData('name'));
-        $this->renderContext->getStorage()->addMeta($this->getData('name'), $meta);
-        $this->renderContext->getStorage()->addDataCollection($this->getData('name'), $this->getData('dataSource'));
-    }
+        parent::prepare();
 
-    /**
-     * Render content
-     *
-     * @param array $data
-     * @return string
-     */
-    public function render(array $data = [])
-    {
-        $this->initialConfiguration();
+        $jsConfig = $this->getConfiguration($this);
+        unset($jsConfig['extends']);
+        $this->getContext()->addComponentDefinition($this->getContext()->getNamespace(), $jsConfig);
 
-        return parent::render($data);
+        $this->getContext()->addButtons($this->getData('buttons'), $this);
     }
 
     /**
-     * Get meta data
-     *
-     * @return array
+     * @inheritdoc
      */
-    public function getMeta()
+    public function getDataSourceData()
     {
-        $meta = $this->getData('meta');
-        foreach ($meta['fields'] as $key => $field) {
-            if ($field['data_type'] === 'date') {
-                $field['date_format'] = $this->_localeDate->getDateTimeFormat(
-                    \IntlDateFormatter::MEDIUM
-                );
+        $columns = $this->collectColumns();
+        $dataSources = [];
+        foreach ($this->getChildComponents() as $component) {
+            // we need to process only Data Sources
+            if (!$component instanceof DataSourceInterface) {
+                continue;
             }
-
-            if (isset($field[static::OPTIONS_PROVIDER_KEY])) {
-                $field['options'] = $this->optionsFactory->create($field[static::OPTIONS_PROVIDER_KEY])
-                    ->getOptions(empty($field['options']) ? [] : $field['options']);
+            $data = $component->getDataProvider()->getData();
+            if (!empty($data['items']) && !empty($columns)) {
+                // Columns may need to pre-process data before using it
+                foreach ($columns as $column) {
+                    $column->prepareItems($data['items']);
+                }
             }
 
-            unset($field[static::OPTIONS_PROVIDER_KEY]);
-            $meta['fields'][$key] = $field;
-        }
-
-        return $meta;
-    }
-
-    /**
-     * Apply data provider to row data
-     *
-     * @param array $dataRow
-     * @return array
-     */
-    protected function getDataFromDataProvider(array $dataRow)
-    {
-        if ($this->hasData(static::ROW_DATA_PROVIDER_KEY)) {
-            foreach ($this->getData(static::ROW_DATA_PROVIDER_KEY) as $field => $data) {
-                $dataRow[$field] = $this->dataProviderRowPool->get($data['class'])->getData($dataRow, $data);
-            }
+            $dataSources[] = [
+                'type' => $component->getComponentName(),
+                'name' => $component->getName(),
+                'dataScope' => $component->getContext()->getNamespace(),
+                'config' => array_replace_recursive(
+                    [
+                        'data' => $data,
+                        'totalCount' => $component->getDataProvider()->count(),
+                    ],
+                    (array) $component->getData('config'),
+                    // ensure that namespace hasn't been overridden by accident
+                    [
+                        'params' => [
+                            'namespace' => $this->getContext()->getNamespace()
+                        ],
+                    ]
+                ),
+            ];
         }
-
-        return $dataRow;
+        return $dataSources;
     }
 
     /**
-     * Get collection items
+     * Go through child components and collect Column types only.
      *
-     * @return array
+     * @return Column[]
      */
-    public function getCollectionItems()
+    protected function collectColumns()
     {
-        $items = [];
-        $collection = $this->getDataCollection();
-        foreach ($collection->getItems() as $item) {
-            $actualFields = [];
-            $itemsData = $this->getDataFromDataProvider($item->getData());
-            foreach (array_keys($this->getData('meta/fields')) as $field) {
-                $actualFields[$field] = $itemsData[$field];
+        $columns = [];
+        foreach ($this->getChildComponents() as $component) {
+            if ($component instanceof Columns) {
+                foreach ($component->getChildComponents() as $column) {
+                    if ($column instanceof Column) {
+                        $columns[] = $column;
+                    }
+                }
             }
-            $items[] = $actualFields;
         }
-
-        return $items;
-    }
-
-    /**
-     * @return \Magento\Framework\Api\CriteriaInterface|\Magento\Framework\Data\CollectionDataSourceInterface
-     */
-    protected function getDataCollection()
-    {
-        return $this->renderContext->getStorage()->getDataCollection($this->getName());
-    }
-
-    /**
-     * Configuration initialization
-     *
-     * @return void
-     */
-    protected function initialConfiguration()
-    {
-        $url = $this->getUrl($this->getData('client_root'));
-        $this->renderContext->getStorage()->addGlobalData(
-            'client',
-            [
-                'root' => $url,
-                'ajax' => [
-                    'data' => [
-                        'component' => $this->getNameInLayout(),
-                    ],
-                ]
-            ]
-        );
-        $this->renderContext->getStorage()->addGlobalData('dump', ['extenders' => []]);
-
-        $collection = $this->getDataCollection();
-        $totalCount = $collection->count();
-        $this->renderContext->getStorage()->addDataSource(
-            $this->getName(),
-            [
-                'data' => [
-                    'meta_reference' => $this->getName(),
-                    'items' => $this->getCollectionItems(),
-                    'pages' => ceil($totalCount / $this->renderContext->getRequestParam('limit', 20)),
-                    'totalCount' => $totalCount,
-                ]
-            ]
-        );
-    }
-
-    /**
-     * Get default parameters
-     *
-     * @return array
-     */
-    public function getDefaultConfiguration()
-    {
-        return [
-            'page_actions' => [
-                'add' => [
-                    'name' => 'add',
-                    'label' => __('Add New'),
-                    'class' => 'primary',
-                    'url' => $this->getUrl('*/*/new'),
-                ],
-            ]
-        ];
+        return $columns;
     }
 }
diff --git a/app/code/Magento/Ui/Component/Listing/Columns.php b/app/code/Magento/Ui/Component/Listing/Columns.php
new file mode 100644
index 0000000000000000000000000000000000000000..6e2eee1180af125d572fef1d048ad6435744f3f8
--- /dev/null
+++ b/app/code/Magento/Ui/Component/Listing/Columns.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\Component\Listing;
+
+use Magento\Ui\Component\AbstractComponent;
+use Magento\Ui\Component\Listing\Columns\Column;
+
+/**
+ * Class Columns
+ */
+class Columns extends AbstractComponent
+{
+    const NAME = 'columns';
+
+    /**
+     * Get component name
+     *
+     * @return string
+     */
+    public function getComponentName()
+    {
+        return static::NAME;
+    }
+
+    /**
+     * Prepare component configuration
+     *
+     * @return void
+     */
+    public function prepare()
+    {
+        parent::prepare();
+        foreach ($this->getChildComponents() as $column) {
+            if ($column instanceof Column) {
+                $meta = $this->getContext()->getDataProvider()->getFieldMetaInfo($this->getName(), $column->getName());
+                if ($meta) {
+                    $config = $column->getData('config');
+                    $config = array_replace_recursive($config, $meta);
+                    $column->setData('config', $config);
+                }
+            }
+        }
+
+        $jsConfig = $this->getConfiguration($this);
+        $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig);
+    }
+}
diff --git a/app/code/Magento/Ui/Component/Listing/Columns/Column.php b/app/code/Magento/Ui/Component/Listing/Columns/Column.php
new file mode 100644
index 0000000000000000000000000000000000000000..cda819b5f7d0cf61c9d65aa49dec99cba41d90bd
--- /dev/null
+++ b/app/code/Magento/Ui/Component/Listing/Columns/Column.php
@@ -0,0 +1,136 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\Component\Listing\Columns;
+
+use Magento\Ui\Component\AbstractComponent;
+use Magento\Framework\View\Element\UiComponentFactory;
+use Magento\Framework\View\Element\UiComponentInterface;
+use Magento\Framework\View\Element\UiComponent\ContextInterface;
+
+/**
+ * Class Column
+ */
+class Column extends AbstractComponent implements ColumnInterface
+{
+    const NAME = 'column';
+
+    /**
+     * Wrapped component
+     *
+     * @var UiComponentInterface
+     */
+    protected $wrappedComponent;
+
+    /**
+     * UI component factory
+     *
+     * @var UiComponentFactory
+     */
+    protected $uiComponentFactory;
+
+    /**
+     * Constructor
+     *
+     * @param ContextInterface $context
+     * @param UiComponentFactory $uiComponentFactory
+     * @param array $components
+     * @param array $data
+     */
+    public function __construct(
+        ContextInterface $context,
+        UiComponentFactory $uiComponentFactory,
+        array $components = [],
+        array $data = []
+    ) {
+        $this->uiComponentFactory = $uiComponentFactory;
+        parent::__construct($context, $components, $data);
+    }
+
+    /**
+     * Get component name
+     *
+     * @return string
+     */
+    public function getComponentName()
+    {
+        return static::NAME . '.' . $this->getData('config/dataType');
+    }
+
+    /**
+     * Prepare component configuration
+     *
+     * @return void
+     */
+    public function prepare()
+    {
+        parent::prepare();
+
+        $dataType = $this->getData('config/dataType');
+        $wrappedComponentConfig = [];
+        if ($dataType) {
+            $this->wrappedComponent = $this->uiComponentFactory->create(
+                $this->getName(),
+                $dataType,
+                array_merge(['context' => $this->getContext()], (array) $this->getData())
+            );
+            $this->wrappedComponent->prepare();
+            $wrappedComponentConfig = $this->getConfiguration($this->wrappedComponent);
+        }
+
+        $this->applySorting();
+        $jsConfig = array_replace_recursive($wrappedComponentConfig, $this->getConfiguration($this));
+        $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig);
+    }
+
+    /**
+     * Get JS config
+     *
+     * @return array
+     */
+    public function getJsConfig()
+    {
+        if (isset($this->wrappedComponent)) {
+            return array_replace_recursive(
+                (array) $this->wrappedComponent->getData('config'),
+                (array) $this->getData('config')
+            );
+        }
+
+        return (array) $this->getData('config');
+    }
+
+    /**
+     * To prepare items of a column
+     *
+     * @param array $items
+     * @return array
+     */
+    public function prepareItems(array & $items)
+    {
+        return $items;
+    }
+
+    /**
+     * Apply sorting
+     *
+     * @return void
+     */
+    protected function applySorting()
+    {
+        $sorting = $this->getContext()->getRequestParam('sorting');
+        $isSortable = $this->getData('config/sortable');
+        if ($isSortable !== false
+            && !empty($sorting['field'])
+            && !empty($sorting['direction'])
+            && $sorting['field'] === $this->getName()
+        ) {
+            $this->getContext()->getDataProvider()->addOrder(
+                $this->getName(),
+                strtoupper($sorting['direction'])
+            );
+        }
+    }
+}
diff --git a/app/code/Magento/Ui/Component/Listing/Columns/ColumnInterface.php b/app/code/Magento/Ui/Component/Listing/Columns/ColumnInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..0fb07d7e415f9a94089c7c0fe4468600e953aaf3
--- /dev/null
+++ b/app/code/Magento/Ui/Component/Listing/Columns/ColumnInterface.php
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\Component\Listing\Columns;
+
+use Magento\Framework\View\Element\UiComponentInterface;
+
+/**
+ * Interface ColumnInterface
+ */
+interface ColumnInterface extends UiComponentInterface
+{
+    /**
+     * To prepare items of a column
+     *
+     * @param array $items
+     * @return array
+     */
+    public function prepareItems(array & $items);
+}
diff --git a/app/code/Magento/Ui/Component/Listing/OptionsFactory.php b/app/code/Magento/Ui/Component/Listing/OptionsFactory.php
deleted file mode 100644
index ab1e1c822f451e57e73737ea093ce742f87a169a..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/Component/Listing/OptionsFactory.php
+++ /dev/null
@@ -1,49 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\Component\Listing;
-
-use Magento\Framework\ObjectManagerInterface;
-
-/**
- * Class OptionsFactory
- */
-class OptionsFactory
-{
-    /**
-     * @var ObjectManagerInterface
-     */
-    protected $objectManager;
-
-    /**
-     * Constructor
-     *
-     * @param ObjectManagerInterface $objectManager
-     */
-    public function __construct(ObjectManagerInterface $objectManager)
-    {
-        $this->objectManager = $objectManager;
-    }
-
-    /**
-     * Getting provider object
-     *
-     * @param string $class
-     * @param array $arguments
-     * @return OptionsInterface
-     * @throws \InvalidArgumentException
-     */
-    public function create($class, array $arguments = [])
-    {
-        $object = $this->objectManager->create($class, $arguments);
-        if (!($object instanceof OptionsInterface)) {
-            throw new \InvalidArgumentException(
-                sprintf('"%s" must implement the interface \Magento\Ui\Component\Listing\OptionsInterface', $class)
-            );
-        }
-
-        return $object;
-    }
-}
diff --git a/app/code/Magento/Ui/Component/Listing/OptionsInterface.php b/app/code/Magento/Ui/Component/Listing/OptionsInterface.php
deleted file mode 100644
index 97ffc3d9c15f19373f518f445813abbee7afe343..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/Component/Listing/OptionsInterface.php
+++ /dev/null
@@ -1,20 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\Component\Listing;
-
-/**
- * Class OptionsInterface
- */
-interface OptionsInterface
-{
-    /**
-     * Get options
-     *
-     * @param array $options
-     * @return array
-     */
-    public function getOptions(array $options = []);
-}
diff --git a/app/code/Magento/Ui/Component/Listing/RowPool.php b/app/code/Magento/Ui/Component/Listing/RowPool.php
deleted file mode 100644
index 165eaef33ab3d2a8f1ef794b859095b7e9d95f3a..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/Component/Listing/RowPool.php
+++ /dev/null
@@ -1,56 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\Component\Listing;
-
-use Magento\Framework\ObjectManagerInterface;
-
-/**
- * Class RowPool
- */
-class RowPool
-{
-    /**
-     * @var RowInterface[]
-     */
-    protected $classPool;
-
-    /**
-     * @var ObjectManagerInterface
-     */
-    protected $objectManager;
-
-    /**
-     * Constructor
-     *
-     * @param ObjectManagerInterface $objectManager
-     */
-    public function __construct(ObjectManagerInterface $objectManager)
-    {
-        $this->objectManager = $objectManager;
-    }
-
-    /**
-     * Getting provider object
-     *
-     * @param string $class
-     * @param array $arguments
-     * @return RowInterface
-     * @throws \InvalidArgumentException
-     */
-    public function get($class, array $arguments = [])
-    {
-        if (!isset($this->classPool[$class])) {
-            $this->classPool[$class] = $this->objectManager->create($class, $arguments);
-            if (!($this->classPool[$class] instanceof RowInterface)) {
-                throw new \InvalidArgumentException(
-                    sprintf('"%s" must implement the interface \Magento\Ui\Component\Listing\RowInterface', $class)
-                );
-            }
-        }
-
-        return $this->classPool[$class];
-    }
-}
diff --git a/app/code/Magento/Ui/Component/MassAction.php b/app/code/Magento/Ui/Component/MassAction.php
index e892c9ed2793ef68bf535dea55721fc6f85f8092..140e48c0b15f3eb112d1e17b686f768f6da692ac 100644
--- a/app/code/Magento/Ui/Component/MassAction.php
+++ b/app/code/Magento/Ui/Component/MassAction.php
@@ -5,33 +5,51 @@
  */
 namespace Magento\Ui\Component;
 
+use Magento\Framework\View\Element\UiComponent\ContextInterface;
+
 /**
  * Class MassAction
  */
-class MassAction extends AbstractView
+class MassAction extends AbstractComponent
 {
+    const NAME = 'massaction';
+
+    /**
+     * Get component name
+     *
+     * @return string
+     */
+    public function getComponentName()
+    {
+        return static::NAME;
+    }
+
     /**
-     * Prepare component data
+     * Register component
      *
-     * @return $this|void
+     * @return void
      */
     public function prepare()
     {
-        $configData = $this->getDefaultConfiguration();
-        if ($this->hasData('config')) {
-            $configData = array_merge($configData, $this->getData('config'));
+        $this->prepareConfiguration();
+        $config = $this->getData('config');
+        if (isset($config['actions'])) {
+            $config['actions'] = array_values($config['actions']);
+            array_walk_recursive(
+                $config['actions'],
+                function (&$item, $key, $context) {
+                    /** @var ContextInterface $context */
+                    if ($key === 'url') {
+                        $item = $context->getUrl($item);
+                    }
+                },
+                $this->getContext()
+            );
+            $this->setData('config', $config);
         }
-        array_walk_recursive(
-            $configData,
-            function (&$item, $key, $object) {
-                if ($key === 'url') {
-                    $item = $object->getUrl($item);
-                }
-            },
-            $this
-        );
 
-        $this->prepareConfiguration($configData);
+        $jsConfig = $this->getConfiguration($this);
+        $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig);
     }
 
     /**
diff --git a/app/code/Magento/Ui/Component/MassAction/Columns/Column.php b/app/code/Magento/Ui/Component/MassAction/Columns/Column.php
new file mode 100644
index 0000000000000000000000000000000000000000..6e1e438782197597e4db7e1545bfe72406b91fd9
--- /dev/null
+++ b/app/code/Magento/Ui/Component/MassAction/Columns/Column.php
@@ -0,0 +1,86 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\Component\MassAction\Columns;
+
+use Magento\Ui\Component\AbstractComponent;
+use Magento\Framework\View\Element\UiComponentFactory;
+use Magento\Framework\View\Element\UiComponentInterface;
+use Magento\Ui\Component\Listing\Columns\ColumnInterface;
+use Magento\Framework\View\Element\UiComponent\ContextInterface;
+
+/**
+ * Class Column
+ */
+class Column extends AbstractComponent implements ColumnInterface
+{
+    const NAME = 'column.massaction';
+
+    /**
+     * Wrapped component
+     *
+     * @var UiComponentInterface
+     */
+    protected $wrappedComponent;
+
+    /**
+     * UI component factory
+     *
+     * @var UiComponentFactory
+     */
+    protected $uiComponentFactory;
+
+    /**
+     * Constructor
+     *
+     * @param ContextInterface $context
+     * @param UiComponentFactory $uiComponentFactory
+     * @param array $components
+     * @param array $data
+     */
+    public function __construct(
+        ContextInterface $context,
+        UiComponentFactory $uiComponentFactory,
+        array $components = [],
+        array $data = []
+    ) {
+        $this->uiComponentFactory = $uiComponentFactory;
+        parent::__construct($context, $components, $data);
+    }
+
+    /**
+     * Get component name
+     *
+     * @return string
+     */
+    public function getComponentName()
+    {
+        return static::NAME;
+    }
+
+    /**
+     * Prepare component configuration
+     *
+     * @return void
+     */
+    public function prepare()
+    {
+        parent::prepare();
+
+        $jsConfig = $this->getConfiguration($this);
+        $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig);
+    }
+
+    /**
+     * Prepare items
+     *
+     * @param array $items
+     * @return array
+     */
+    public function prepareItems(array & $items)
+    {
+        return $items;
+    }
+}
diff --git a/app/code/Magento/Ui/Component/Paging.php b/app/code/Magento/Ui/Component/Paging.php
index 7c504b74ac8303fff539ffe9671af8a9c68039e7..df104e0948771197d7e688671483e8197c3bc467 100644
--- a/app/code/Magento/Ui/Component/Paging.php
+++ b/app/code/Magento/Ui/Component/Paging.php
@@ -8,39 +8,80 @@ namespace Magento\Ui\Component;
 /**
  * Class Paging
  */
-class Paging extends AbstractView
+class Paging extends AbstractComponent
 {
+    const NAME = 'paging';
+
+    /**
+     * Get component name
+     *
+     * @return string
+     */
+    public function getComponentName()
+    {
+        return static::NAME;
+    }
+
     /**
-     * Prepare component data
+     * Register component and apply paging settings to Data Provider
      *
      * @return void
      */
     public function prepare()
     {
-        $configData = $this->getDefaultConfiguration();
-        if ($this->hasData('config')) {
-            $configData = array_merge($configData, $this->getData('config'));
-        }
+        parent::prepare();
+
+        $this->prepareConfiguration();
+        $this->prepareOptions();
+
+        $paging = $this->getContext()->getRequestParam('paging');
+
+        $this->getContext()->getDataProvider()->setLimit($this->getOffset($paging), $this->getSize($paging));
+
+        $jsConfig = $this->getConfiguration($this);
+        $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig);
+    }
+
+    /**
+     * Get offset
+     *
+     * @param array|null $paging
+     * @return int
+     */
+    protected function getOffset($paging)
+    {
+        $defaultPage = $this->getData('config/current') ?: 1;
+        return (int) (isset($paging['current']) ? $paging['current'] : $defaultPage);
+    }
 
-        $this->prepareConfiguration($configData);
-        $this->updateDataCollection();
+    /**
+     * Get size
+     *
+     * @param array|null $paging
+     * @return int
+     */
+    protected function getSize($paging)
+    {
+        $defaultLimit = $this->getData('config/pageSize') ?: 20;
+        return (int) (isset($paging['pageSize']) ? $paging['pageSize'] : $defaultLimit);
     }
 
     /**
-     * Update data collection
+     * Prepare paging options
      *
      * @return void
      */
-    protected function updateDataCollection()
+    protected function prepareOptions()
     {
-        $defaultPage = $this->config->getData('current');
-        $offset = $this->renderContext->getRequestParam('page', $defaultPage);
-        $defaultLimit = $this->config->getData('pageSize');
-        $size = $this->renderContext->getRequestParam('limit', $defaultLimit);
-        $this->renderContext->getStorage()
-            ->getDataCollection($this->getParentName())
-            ->setPageSize($size)
-            ->setCurPage($offset);
+        $config = $this->getData('config');
+        if (isset($config['options'])) {
+            $config['options'] = array_values($config['options']);
+            foreach ($config['options'] as &$item) {
+                $item['value'] = (int) $item['value'];
+            }
+            unset($item);
+            $this->setData('config', $config);
+        }
     }
 
     /**
@@ -51,7 +92,28 @@ class Paging extends AbstractView
     protected function getDefaultConfiguration()
     {
         return  [
-            'sizes' => [20, 30, 50, 100, 200],
+            'options' => [
+                '20' => [
+                    'value' => 20,
+                    'label' => 20
+                ],
+                '30' => [
+                    'value' => 30,
+                    'label' => 30
+                ],
+                '50' => [
+                    'value' => 50,
+                    'label' => 50
+                ],
+                '100' => [
+                    'value' => 100,
+                    'label' => 100
+                ],
+                '200' => [
+                    'value' => 200,
+                    'label' => 200
+                ],
+            ],
             'pageSize' => 20,
             'current' => 1
         ];
diff --git a/app/code/Magento/Ui/Component/RenderLayoutInterface.php b/app/code/Magento/Ui/Component/RenderLayoutInterface.php
deleted file mode 100644
index 34bb85e8d7469fd0280c242b09906225995bb80d..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/Component/RenderLayoutInterface.php
+++ /dev/null
@@ -1,15 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\Component;
-
-use Magento\Framework\View\Element\UiComponentInterface;
-
-/**
- * Interface RenderLayoutInterface
- */
-interface RenderLayoutInterface extends UiComponentInterface
-{
-}
diff --git a/app/code/Magento/Ui/Component/Search.php b/app/code/Magento/Ui/Component/Search.php
deleted file mode 100644
index b32227b5561eb819fead4ab817637f25cfcc7abc..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/Component/Search.php
+++ /dev/null
@@ -1,14 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\Component;
-
-/**
- * Class Search
- */
-class Search extends AbstractView
-{
-    //
-}
diff --git a/app/code/Magento/Ui/Component/Sorting.php b/app/code/Magento/Ui/Component/Sorting.php
deleted file mode 100644
index 944c8e531b3004400ca35e6a36b58ed84d3792ac..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/Component/Sorting.php
+++ /dev/null
@@ -1,55 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\Component;
-
-/**
- * Class Sorting
- */
-class Sorting extends AbstractView
-{
-    /**
-     * Prepare component data
-     *
-     * @return void
-     */
-    public function prepare()
-    {
-        $configData = $this->getDefaultConfiguration();
-        if ($this->hasData('config')) {
-            $configData = array_merge($configData, $this->getData('config'));
-        }
-
-        $this->prepareConfiguration($configData);
-        $this->updateDataCollection();
-    }
-
-    /**
-     * Update data collection
-     *
-     * @return void
-     */
-    protected function updateDataCollection()
-    {
-        $field = $this->config->getData('field');
-        $direction = $this->config->getData('direction');
-        if (!empty($field) && !empty($direction)) {
-            $this->renderContext->getStorage()->getDataCollection($this->getParentName())->addOrder(
-                $this->renderContext->getRequestParam('sort', $field),
-                strtoupper($this->renderContext->getRequestParam('dir', $direction))
-            );
-        }
-    }
-
-    /**
-     * Get default parameters
-     *
-     * @return array
-     */
-    protected function getDefaultConfiguration()
-    {
-        return ['direction' => 'asc'];
-    }
-}
diff --git a/app/code/Magento/Ui/Component/Wrapper/Block.php b/app/code/Magento/Ui/Component/Wrapper/Block.php
new file mode 100644
index 0000000000000000000000000000000000000000..8f352313d94fd153ed1f10112970cc5f8bf18b0a
--- /dev/null
+++ b/app/code/Magento/Ui/Component/Wrapper/Block.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\Component\Wrapper;
+
+use Magento\Framework\View\Element\BlockInterface;
+use Magento\Framework\View\Element\UiComponent\ContextInterface;
+use Magento\Ui\Component\AbstractComponent;
+
+/**
+ * Class Block
+ */
+class Block extends AbstractComponent
+{
+    const NAME = 'blockWrapper';
+
+    /**
+     * @var BlockInterface
+     */
+    protected $block;
+
+    /**
+     * Constructor
+     *
+     * @param ContextInterface $context
+     * @param BlockInterface $block
+     * @param array $components
+     * @param array $data
+     */
+    public function __construct(
+        ContextInterface $context,
+        BlockInterface $block,
+        array $components = [],
+        array $data = []
+    ) {
+        $this->block = $block;
+        parent::__construct($context, $components, $data);
+    }
+
+    /**
+     * Get wrapped block
+     *
+     * @return BlockInterface
+     */
+    public function getBlock()
+    {
+        return $this->block;
+    }
+
+    /**
+     * Get component name
+     *
+     * @return string
+     */
+    public function getComponentName()
+    {
+        return static::NAME;
+    }
+
+    /**
+     * @return string
+     */
+    public function render()
+    {
+        return $this->block->toHtml();
+    }
+}
diff --git a/app/code/Magento/Ui/Component/Wrapper/UiComponent.php b/app/code/Magento/Ui/Component/Wrapper/UiComponent.php
new file mode 100644
index 0000000000000000000000000000000000000000..28f67161272ab1b44f59709a28379379e30178a1
--- /dev/null
+++ b/app/code/Magento/Ui/Component/Wrapper/UiComponent.php
@@ -0,0 +1,75 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\Component\Wrapper;
+
+use Magento\Framework\View\Element\Template;
+use Magento\Framework\View\Element\UiComponentInterface;
+use Magento\Framework\View\Element\UiComponent\ContainerInterface;
+use Magento\Framework\View\Element\Template\Context as TemplateContext;
+
+/**
+ * Class UiComponent
+ *
+ * Encapsulate UI Component to represent it as standard Layout Block
+ */
+class UiComponent extends Template implements ContainerInterface
+{
+    /**
+     * Ui component
+     *
+     * @var UiComponentInterface
+     */
+    protected $component;
+
+    /**
+     * @var BlockFactory
+     */
+    protected $blockWrapperFactory;
+
+    /**
+     * Constructor
+     *
+     * @param TemplateContext $context
+     * @param UiComponentInterface $component
+     * @param BlockFactory $blockWrapperFactory
+     * @param array $data
+     */
+    public function __construct(
+        TemplateContext $context,
+        UiComponentInterface $component,
+        BlockFactory $blockWrapperFactory,
+        array $data = []
+    ) {
+        $this->component = $component;
+        $this->blockWrapperFactory = $blockWrapperFactory;
+        $this->setNameInLayout($this->component->getName());
+        parent::__construct($context, $data);
+    }
+
+    /**
+     * Render block HTML
+     *
+     * @return string
+     */
+    protected function _toHtml()
+    {
+        foreach ($this->getChildNames() as $childName) {
+            $childBlock = $this->getLayout()->getBlock($childName);
+            if ($childBlock) {
+                $wrapper = $this->blockWrapperFactory->create([
+                    'block' => $childBlock,
+                    'data' => [
+                        'name' => 'block_' . $childName
+                    ]
+                ]);
+                $this->component->addComponent('block_' . $childName, $wrapper);
+            }
+        }
+
+        $result = $this->component->render();
+        return (string)$result;
+    }
+}
diff --git a/app/code/Magento/Ui/ContentType/Builder/ConfigJson.php b/app/code/Magento/Ui/ContentType/Builder/ConfigJson.php
deleted file mode 100644
index 74c3af86783591d5c34f50df4918cf1c4a8a2928..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/ContentType/Builder/ConfigJson.php
+++ /dev/null
@@ -1,30 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\ContentType\Builder;
-
-use Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface;
-use Magento\Framework\View\Element\UiComponent\ConfigInterface;
-
-/**
- * Class ConfigJson
- */
-class ConfigJson implements ConfigBuilderInterface
-{
-    /**
-     * Config data to JSON by output
-     *
-     * @param ConfigInterface $configuration
-     * @return string
-     */
-    public function toJson(ConfigInterface $configuration)
-    {
-        $result = $configuration->getData();
-        $result['name'] = $configuration->getName();
-        $result['parent_name'] = $configuration->getParentName();
-
-        return json_encode($result);
-    }
-}
diff --git a/app/code/Magento/Ui/ContentType/Builder/ConfigStorageJson.php b/app/code/Magento/Ui/ContentType/Builder/ConfigStorageJson.php
deleted file mode 100644
index 99eca8d2994345fba40b8769903002da11fac1a5..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/ContentType/Builder/ConfigStorageJson.php
+++ /dev/null
@@ -1,73 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\ContentType\Builder;
-
-use Magento\Framework\View\Element\UiComponent\ConfigInterface;
-use Magento\Framework\View\Element\UiComponent\ConfigStorageBuilderInterface;
-use Magento\Framework\View\Element\UiComponent\ConfigStorageInterface;
-
-/**
- * Class ConfigStorageBuilder
- */
-class ConfigStorageJson implements ConfigStorageBuilderInterface
-{
-    /**
-     * Config storage data to JSON by output
-     *
-     * @param ConfigStorageInterface $storage
-     * @param string $parentName
-     * @return string
-     */
-    public function toJson(ConfigStorageInterface $storage, $parentName = null)
-    {
-        $result = [
-            'config' => [],
-        ];
-        $result['meta'] = $storage->getMeta($parentName);
-        $dataSource = $storage->getDataSource($parentName);
-        $data = isset($dataSource['data']) ? $dataSource['data'] : null;
-        if ($parentName !== null) {
-            $rootComponent = $storage->getComponentsData($parentName);
-            $result['name'] = $rootComponent->getName();
-            $result['parent_name'] = $rootComponent->getParentName();
-            $result['data'] = $data;
-            $result['config']['components'][$rootComponent->getName()] = $rootComponent->getData();
-        } else {
-            $components = $storage->getComponentsData();
-            if (!empty($components)) {
-                /** @var ConfigInterface $component */
-                foreach ($components as $name => $component) {
-                    $result['config']['components'][$name] = $component->getData();
-                }
-            }
-            $result['data'] = $data;
-        }
-        $result['config'] += $storage->getGlobalData();
-        $result['dump']['extenders'] = [];
-
-        return json_encode($result);
-    }
-
-    /**
-     * Config storage data to JSON by output
-     *
-     * @param ConfigStorageInterface $storage
-     * @return string
-     */
-    public function toJsonNew(ConfigStorageInterface $storage)
-    {
-        $result = [];
-        foreach ($storage->getDataSource() as $name => $dataSource) {
-            $dataSource['path'] = 'Magento_Ui/js/form/provider';
-            $result['providers'][$name] = $dataSource;
-        }
-        $result['renderer'] = [
-            'types' => $storage->getComponents(),
-            'layout' => $storage->getLayoutStructure(),
-        ];
-        return json_encode($result);
-    }
-}
diff --git a/app/code/Magento/Ui/ContentType/Html.php b/app/code/Magento/Ui/ContentType/Html.php
deleted file mode 100644
index dee784fdbbd37f279a2ed6637cc9fa70a37e9cac..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/ContentType/Html.php
+++ /dev/null
@@ -1,61 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\ContentType;
-
-use Magento\Framework\View\Element\UiComponentInterface;
-use Magento\Framework\View\FileSystem;
-use Magento\Framework\View\TemplateEnginePool;
-
-/**
- * Class Html
- */
-class Html implements ContentTypeInterface
-{
-    /**
-     * @var \Magento\Framework\View\FileSystem
-     */
-    protected $filesystem;
-
-    /**
-     * @var \Magento\Framework\View\TemplateEnginePool
-     */
-    protected $templateEnginePool;
-
-    /**
-     * Constructor
-     *
-     * @param FileSystem $filesystem
-     * @param TemplateEnginePool $templateEnginePool
-     */
-    public function __construct(FileSystem $filesystem, TemplateEnginePool $templateEnginePool)
-    {
-        $this->filesystem = $filesystem;
-        $this->templateEnginePool = $templateEnginePool;
-    }
-
-    /**
-     * Render data
-     *
-     * @param UiComponentInterface $view
-     * @param string $template
-     * @return string
-     */
-    public function render(UiComponentInterface $view, $template = '')
-    {
-        $templateEngine = false;
-        if ($template) {
-            $extension = pathinfo($template, PATHINFO_EXTENSION);
-            $templateEngine = $this->templateEnginePool->get($extension);
-        }
-        if ($templateEngine) {
-            $path = $this->filesystem->getTemplateFileName($template);
-            $result = $templateEngine->render($view, $path);
-        } else {
-            $result = '';
-        }
-        return $result;
-    }
-}
diff --git a/app/code/Magento/Ui/ContentType/Json.php b/app/code/Magento/Ui/ContentType/Json.php
deleted file mode 100644
index 4eb26e619a8311974f44615e1a3e448ccc7a1555..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/ContentType/Json.php
+++ /dev/null
@@ -1,52 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\ContentType;
-
-use Magento\Framework\View\Element\UiComponentInterface;
-use Magento\Framework\View\FileSystem;
-use Magento\Framework\View\TemplateEnginePool;
-
-/**
- * Class Json
- */
-class Json implements ContentTypeInterface
-{
-    /**
-     * @var \Magento\Framework\View\FileSystem
-     */
-    protected $filesystem;
-
-    /**
-     * @var \Magento\Framework\View\TemplateEnginePool
-     */
-    protected $templateEnginePool;
-
-    /**
-     * Constructor
-     *
-     * @param FileSystem $filesystem
-     * @param TemplateEnginePool $templateEnginePool
-     */
-    public function __construct(FileSystem $filesystem, TemplateEnginePool $templateEnginePool)
-    {
-        $this->filesystem = $filesystem;
-        $this->templateEnginePool = $templateEnginePool;
-    }
-
-    /**
-     * Render data
-     *
-     * @param UiComponentInterface $view
-     * @param string $template
-     * @return string
-     */
-    public function render(UiComponentInterface $view, $template = '')
-    {
-        return $view->getRenderContext()
-            ->getConfigBuilder()
-            ->toJson($view->getRenderContext()->getStorage(), $view->getName());
-    }
-}
diff --git a/app/code/Magento/Ui/Context/Configuration.php b/app/code/Magento/Ui/Context/Configuration.php
deleted file mode 100644
index 7711fec456f00869c7b7771d7b6edc9556188034..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/Context/Configuration.php
+++ /dev/null
@@ -1,109 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\Context;
-
-use Magento\Framework\View\Element\UiComponent\ConfigInterface;
-
-/**
- * Class Configuration
- */
-class Configuration implements ConfigInterface
-{
-    /**
-     * Configuration data
-     *
-     * @var array
-     */
-    protected $configuration = [];
-
-    /**
-     * Name of owner
-     *
-     * @var string
-     */
-    protected $name;
-
-    /**
-     * Name of parent owner
-     *
-     * @var string
-     */
-    protected $parentName;
-
-    /**
-     * Constructor
-     *
-     * @param string $name
-     * @param  string $parentName
-     * @param array $configuration
-     */
-    public function __construct($name, $parentName, $configuration = [])
-    {
-        $this->name = $name;
-        $this->parentName = $parentName;
-        $this->configuration = $configuration;
-    }
-
-    /**
-     * Get configuration data
-     *
-     * @param string|null $key
-     * @return mixed
-     */
-    public function getData($key = null)
-    {
-        if ($key === null) {
-            return (array)$this->configuration;
-        }
-        return isset($this->configuration[$key]) ? $this->configuration[$key] : null;
-    }
-
-    /**
-     * Add configuration data
-     *
-     * @param string $key
-     * @param mixed $data
-     * @return mixed
-     */
-    public function addData($key, $data)
-    {
-        if (!isset($this->configuration[$key])) {
-            $this->configuration[$key] = $data;
-        }
-    }
-
-    /**
-     * Update configuration data
-     *
-     * @param string $key
-     * @param mixed $data
-     * @return mixed
-     */
-    public function updateData($key, $data)
-    {
-        $this->configuration[$key] = $data;
-    }
-
-    /**
-     * Get owner name
-     *
-     * @return string
-     */
-    public function getName()
-    {
-        return $this->name;
-    }
-
-    /**
-     * Get owner parent name
-     *
-     * @return string
-     */
-    public function getParentName()
-    {
-        return $this->parentName;
-    }
-}
diff --git a/app/code/Magento/Ui/Context/ConfigurationStorage.php b/app/code/Magento/Ui/Context/ConfigurationStorage.php
deleted file mode 100644
index 91218f496e01087985d06a62a06df8184bc3de0e..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/Context/ConfigurationStorage.php
+++ /dev/null
@@ -1,340 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\Context;
-
-use Magento\Framework\Data\CollectionDataSourceInterface;
-use Magento\Framework\View\Element\UiComponent\ConfigInterface;
-use Magento\Framework\View\Element\UiComponent\ConfigStorageInterface;
-use Magento\Framework\View\Element\UiComponent\DataProviderInterface;
-
-/**
- * Class ConfigurationStorage
- */
-class ConfigurationStorage implements ConfigStorageInterface
-{
-    /**
-     * Components configuration storage
-     *
-     * @var array
-     */
-    protected $componentStorage = [];
-
-    /**
-     * Data storage
-     *
-     * @var array
-     */
-    protected $dataStorage = [];
-
-    /**
-     * Meta storage
-     *
-     * @var array
-     */
-    protected $metaStorage = [];
-
-    /**
-     * Data collection storage
-     *
-     * @var CollectionDataSourceInterface[]
-     */
-    protected $collectionStorage = [];
-
-    /**
-     * Global data storage
-     *
-     * @var array
-     */
-    protected $globalDataStorage = [];
-
-    /**
-     * Data provider storage
-     *
-     * @var array
-     */
-    protected $dataProviderStorage = [];
-
-    /**
-     * @var array
-     */
-    protected $components = [];
-
-    /**
-     * @var array
-     */
-    protected $layoutStructure = [];
-
-    /**
-     * @inheritdoc
-     */
-    public function addComponent($name, $data)
-    {
-        $this->components[$name] = $data;
-    }
-
-    /**
-     * @inheritdoc
-     */
-    public function addComponentsData(ConfigInterface $config)
-    {
-        if (!isset($this->componentStorage[$config->getName()])) {
-            $this->componentStorage[$config->getName()] = $config;
-        }
-    }
-
-    /**
-     * @return array
-     */
-    public function getComponents()
-    {
-        return $this->components;
-    }
-
-    /**
-     * @return array
-     */
-    public function getMetaKeys()
-    {
-        return array_keys($this->metaStorage);
-    }
-
-    /**
-     * @inheritdoc
-     */
-    public function removeComponentsData(ConfigInterface $configuration)
-    {
-        unset($this->componentStorage[$configuration->getName()]);
-    }
-
-    /**
-     * @inheritdoc
-     */
-    public function getComponentsData($name = null)
-    {
-        if ($name === null) {
-            return $this->componentStorage;
-        }
-        return isset($this->componentStorage[$name]) ? $this->componentStorage[$name] : null;
-    }
-
-    /**
-     * @inheritdoc
-     */
-    public function addDataSource($name, array $dataSource)
-    {
-        if (!isset($this->dataStorage[$name])) {
-            $this->dataStorage[$name] = $dataSource;
-        }
-    }
-
-    /**
-     * @inheritdoc
-     */
-    public function removeDataSource($name)
-    {
-        unset($this->dataStorage[$name]);
-    }
-
-    /**
-     * @inheritdoc
-     */
-    public function getDataSource($name = null)
-    {
-        if ($name === null) {
-            return $this->dataStorage;
-        }
-        return isset($this->dataStorage[$name]) ? $this->dataStorage[$name] : null;
-    }
-
-    /**
-     * @inheritdoc
-     */
-    public function updateDataSource($name, array $dataSource)
-    {
-        if (isset($this->dataStorage[$name])) {
-            $this->dataStorage[$name] = $dataSource;
-        }
-    }
-
-    /**
-     * @inheritdoc
-     */
-    public function addMeta($key, array $data)
-    {
-        if (!isset($this->metaStorage[$key])) {
-            $this->metaStorage[$key] = $data;
-        }
-    }
-
-    /**
-     * @inheritdoc
-     */
-    public function removeMeta($key)
-    {
-        unset($this->metaStorage[$key]);
-    }
-
-    /**
-     * @inheritdoc
-     */
-    public function getMeta($key = null)
-    {
-        if ($key === null) {
-            return $this->metaStorage;
-        }
-        return isset($this->metaStorage[$key]) ? $this->metaStorage[$key] : null;
-    }
-
-    /**
-     * @inheritdoc
-     */
-    public function updateMeta($key, array $data)
-    {
-        if (isset($this->metaStorage[$key])) {
-            $this->metaStorage[$key] = $data;
-        }
-    }
-
-    /**
-     * @inheritdoc
-     */
-    public function addDataCollection($key, CollectionDataSourceInterface $dataCollection)
-    {
-        if (!isset($this->collectionStorage[$key])) {
-            $this->collectionStorage[$key] = $dataCollection;
-        }
-    }
-
-    /**
-     * @inheritdoc
-     */
-    public function getDataCollection($key = null)
-    {
-        if ($key === null) {
-            return $this->collectionStorage;
-        }
-        return isset($this->collectionStorage[$key]) ? $this->collectionStorage[$key] : null;
-    }
-
-    /**
-     * @inheritdoc
-     */
-    public function updateDataCollection($key, CollectionDataSourceInterface $dataCollection)
-    {
-        if (isset($this->collectionStorage[$key])) {
-            $this->collectionStorage[$key] = $dataCollection;
-        }
-    }
-
-    /**
-     * @inheritdoc
-     */
-    public function addGlobalData($key, array $data)
-    {
-        if (!isset($this->globalDataStorage[$key])) {
-            $this->globalDataStorage[$key] = $data;
-        }
-    }
-
-    /**
-     * @inheritdoc
-     */
-    public function removeGlobalData($key)
-    {
-        unset($this->globalDataStorage[$key]);
-    }
-
-    /**
-     * @inheritdoc
-     */
-    public function getGlobalData($key = null)
-    {
-        if ($key === null) {
-            return $this->globalDataStorage;
-        }
-        return isset($this->globalDataStorage[$key]) ? $this->globalDataStorage[$key] : null;
-    }
-
-    /**
-     * @inheritdoc
-     */
-    public function addDataProvider($key, DataProviderInterface $dataProvider)
-    {
-        if (!isset($this->dataProviderStorage[$key])) {
-            $this->dataProviderStorage[$key] = $dataProvider;
-        }
-    }
-
-    /**
-     * @inheritdoc
-     */
-    public function removeDataProvider($key)
-    {
-        if (isset($this->dataProviderStorage[$key])) {
-            unset($this->dataProviderStorage[$key]);
-        }
-    }
-
-    /**
-     * @inheritdoc
-     */
-    public function getDataProvider($key = null)
-    {
-        if ($key === null) {
-            return $this->dataProviderStorage;
-        }
-        return isset($this->dataProviderStorage[$key]) ? $this->dataProviderStorage[$key] : null;
-    }
-
-    /**
-     * @inheritdoc
-     */
-    public function updateDataProvider($key, DataProviderInterface $dataProvider)
-    {
-        if (isset($this->dataProviderStorage[$key])) {
-            $this->dataProviderStorage[$key] = $dataProvider;
-        }
-    }
-
-    /**
-     * @inheritdoc
-     */
-    public function addLayoutStructure($dataScope, array $structure)
-    {
-        $this->layoutStructure[$dataScope] = $structure;
-    }
-
-    /**
-     * @inheritdoc
-     */
-    public function getLayoutStructure()
-    {
-        return $this->layoutStructure;
-    }
-
-    /**
-     * @inheritdoc
-     */
-    public function getLayoutNode($name, $default = null)
-    {
-        if (strpos($name, '.') !== false) {
-            $nameParts = explode('.', $name);
-            $firstChunk = array_shift($nameParts);
-            $node = isset($this->layoutStructure[$firstChunk]) ? $this->layoutStructure[$firstChunk] : [];
-            foreach ($nameParts as $nodeName) {
-                if (isset($node['children'][$nodeName])) {
-                    $node = $node['children'][$nodeName];
-                } else {
-                    $node = $default;
-                    break;
-                }
-            }
-        } else {
-            $node = isset($this->layoutStructure[$name]) ? $this->layoutStructure[$name] : [];
-        }
-        return $node;
-    }
-}
diff --git a/app/code/Magento/Ui/Context/DataProvider.php b/app/code/Magento/Ui/Context/DataProvider.php
deleted file mode 100644
index 1621470ec575263082f3ff569b560f721039e92b..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/Context/DataProvider.php
+++ /dev/null
@@ -1,22 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\Context;
-
-use Magento\Ui\Component\AbstractView;
-
-/**
- * Class DataProvider
- */
-class DataProvider extends AbstractView
-{
-    /**
-     * @return string
-     */
-    public function getAsJson()
-    {
-        return $this->renderContext->getConfigBuilder()->toJson($this->renderContext->getStorage());
-    }
-}
diff --git a/app/code/Magento/Ui/Controller/Adminhtml/AbstractAction.php b/app/code/Magento/Ui/Controller/Adminhtml/AbstractAction.php
index 46a218025258c33dfd1f9d8425e57bc5dd6d8966..6893905b14938d6e9f4906cb9c205c8563c43244 100644
--- a/app/code/Magento/Ui/Controller/Adminhtml/AbstractAction.php
+++ b/app/code/Magento/Ui/Controller/Adminhtml/AbstractAction.php
@@ -1,19 +1,19 @@
 <?php
 /**
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
 namespace Magento\Ui\Controller\Adminhtml;
 
+use Magento\Backend\App\Action;
 use Magento\Backend\App\Action\Context;
-use Magento\Framework\View\Element\UiComponentFactory;
 use Magento\Ui\Controller\UiActionInterface;
+use Magento\Framework\View\Element\UiComponentFactory;
 
 /**
  * Class Render
  */
-abstract class AbstractAction extends \Magento\Backend\App\Action implements UiActionInterface
+abstract class AbstractAction extends Action implements UiActionInterface
 {
     /**
      * @var UiComponentFactory
diff --git a/app/code/Magento/Ui/Controller/Adminhtml/Form/Fieldset.php b/app/code/Magento/Ui/Controller/Adminhtml/Form/Fieldset.php
deleted file mode 100644
index 9c556c7191cdf6d854d146abea66c7c9586e7126..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/Controller/Adminhtml/Form/Fieldset.php
+++ /dev/null
@@ -1,44 +0,0 @@
-<?php
-/**
- *
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-// @codingStandardsIgnoreFile
-
-namespace Magento\Ui\Controller\Adminhtml\Form;
-
-/**
- * Class Fieldset
- *
- * @package Magento\Ui\Controller\Adminhtml\Form
- */
-class Fieldset extends \Magento\Ui\Controller\Adminhtml\AbstractAction
-{
-    /**
-     * Action for AJAX request
-     *
-     * @return void
-     */
-    public function execute()
-    {
-        //        $component = $this->getComponent();
-//        $name = $this->getName();
-//        if ($component && $name) {
-//            $fieldset = $this->factory->createUiComponent($this->getComponent(), $this->getName())->getContainer($this->_request->getParam('container'));
-//            $fieldset->setNotLoadByAjax();
-//            $this->_response->appendBody(
-//                $fieldset->render()
-//            );
-//        } else {
-//            $this->_redirect('admin');
-//        }
-//        $tabIndex = $this->getRequest()->getParam('container');
-//        $this->getResponse()->appendBody(
-//            json_encode(
-//                ['layout' => ['customer_form_tabs' => [$tabIndex => ['label' => 'loaded', 'content' => 'content is loaded']]]]
-//            )
-//        );
-    }
-}
diff --git a/app/code/Magento/Ui/Controller/Adminhtml/Form/Save.php b/app/code/Magento/Ui/Controller/Adminhtml/Form/Save.php
deleted file mode 100644
index 27bcd9d5096c5243c8ce52f02106c573df457a66..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/Controller/Adminhtml/Form/Save.php
+++ /dev/null
@@ -1,33 +0,0 @@
-<?php
-/**
- *
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\Controller\Adminhtml\Form;
-
-/**
- * Class Save
- *
- * @package Magento\Ui\Controller\Adminhtml\Form
- */
-class Save extends \Magento\Ui\Controller\Adminhtml\AbstractAction
-{
-    /**
-     * Action for AJAX request
-     *
-     * @return void
-     */
-    public function execute()
-    {
-        $component = $this->getComponent();
-        $name = $this->getName();
-        if ($component && $name) {
-            $formElement = $this->factory->createUiComponent($component, $name);
-            list($module, $controller, $action) = explode('\\', $formElement->getSaveMca());
-            $this->_forward($action, $controller, $module, $this->getRequest()->getParams());
-        } else {
-            $this->_redirect('admin');
-        }
-    }
-}
diff --git a/app/code/Magento/Ui/Controller/Adminhtml/Form/Validate.php b/app/code/Magento/Ui/Controller/Adminhtml/Form/Validate.php
deleted file mode 100644
index 2d55343ed1e1230ea9128a477931187926ab5b70..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/Controller/Adminhtml/Form/Validate.php
+++ /dev/null
@@ -1,28 +0,0 @@
-<?php
-/**
- *
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\Controller\Adminhtml\Form;
-
-class Validate extends \Magento\Ui\Controller\Adminhtml\AbstractAction
-{
-    /**
-     * Action for AJAX request
-     *
-     * @return void
-     */
-    public function execute()
-    {
-        $component = $this->getComponent();
-        $name = $this->getName();
-        if ($component && $name) {
-            $formElement = $this->factory->createUiComponent($component, $name);
-            list($module, $controller, $action) = explode('\\', $formElement->getValidateMca());
-            $this->_forward($action, $controller, $module, $this->getRequest()->getParams());
-        } else {
-            $this->_redirect('admin');
-        }
-    }
-}
diff --git a/app/code/Magento/Ui/Controller/Adminhtml/Index/Render.php b/app/code/Magento/Ui/Controller/Adminhtml/Index/Render.php
index bda4c09c8751aaf1185e3ee8a61a078bd8354f71..d7d89e88d378fc305dfd01ed98c8dbc00c22e933 100644
--- a/app/code/Magento/Ui/Controller/Adminhtml/Index/Render.php
+++ b/app/code/Magento/Ui/Controller/Adminhtml/Index/Render.php
@@ -1,18 +1,31 @@
 <?php
 /**
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
 namespace Magento\Ui\Controller\Adminhtml\Index;
 
+use Magento\Backend\App\Action\Context;
+use Magento\Ui\Controller\Adminhtml\AbstractAction;
+use Magento\Framework\View\Element\UiComponentFactory;
+use Magento\Framework\View\Element\UiComponentInterface;
+
 /**
  * Class Render
- *
- * @package Magento\Ui\Controller\Adminhtml\Index
  */
-class Render extends \Magento\Ui\Controller\Adminhtml\AbstractAction
+class Render extends AbstractAction
 {
+    /**
+     * Constructor
+     *
+     * @param Context $context
+     * @param UiComponentFactory $factory
+     */
+    public function __construct(Context $context, UiComponentFactory $factory)
+    {
+        parent::__construct($context, $factory);
+    }
+
     /**
      * Action for AJAX request
      *
@@ -20,8 +33,25 @@ class Render extends \Magento\Ui\Controller\Adminhtml\AbstractAction
      */
     public function execute()
     {
-        $this->_response->appendBody(
-            $this->factory->createUiComponent($this->getComponent(), $this->getName())->render()
-        );
+        $component = $this->factory->create($this->_request->getParam('namespace'));
+        $this->prepareComponent($component);
+        $this->_response->appendBody((string) $component->render());
+    }
+
+    /**
+     * Call prepare method in the component UI
+     *
+     * @param UiComponentInterface $component
+     * @return void
+     */
+    protected function prepareComponent(UiComponentInterface $component)
+    {
+        $childComponents = $component->getChildComponents();
+        if (!empty($childComponents)) {
+            foreach ($childComponents as $child) {
+                $this->prepareComponent($child);
+            }
+        }
+        $component->prepare();
     }
 }
diff --git a/app/code/Magento/Ui/Controller/UiActionInterface.php b/app/code/Magento/Ui/Controller/UiActionInterface.php
index 33a13418955a5f5c351f0e8f6600da8acc2d2b00..53932aba49cce3a94a02175a622ab42aab57856e 100644
--- a/app/code/Magento/Ui/Controller/UiActionInterface.php
+++ b/app/code/Magento/Ui/Controller/UiActionInterface.php
@@ -1,6 +1,5 @@
 <?php
 /**
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
@@ -8,7 +7,6 @@ namespace Magento\Ui\Controller;
 
 /**
  * Interface UiActionInterface
- * @package Magento\Ui\Controller
  */
 interface UiActionInterface
 {
diff --git a/app/code/Magento/Ui/DataProvider/Config/Converter.php b/app/code/Magento/Ui/DataProvider/Config/Converter.php
deleted file mode 100644
index 6402821d585af92a6283787813f6e74fbdfcc860..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/DataProvider/Config/Converter.php
+++ /dev/null
@@ -1,248 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-// @codingStandardsIgnoreFile
-
-namespace Magento\Ui\DataProvider\Config;
-
-use Magento\Framework\Config\ConverterInterface;
-
-/**
- * Class Converter
- */
-class Converter implements ConverterInterface
-{
-    /**
-     * @var \Magento\Eav\Model\Entity\TypeFactory
-     */
-    protected $entityTypeFactory;
-
-    /**
-     * Map EAV frontend_input property to form element types
-     *
-     * @var array
-     */
-    protected $inputTypeMap = [
-        'text' => 'input',
-        'textarea' => 'textarea',
-        'multiline' => 'input',
-        'date' => 'date',
-        'select' => 'select',
-        'multiselect' => 'multiselect',
-        'boolean' => 'select',
-        'file' => 'media',
-        'image' => 'media',
-    ];
-
-    /**
-     * @param \Magento\Eav\Model\Entity\TypeFactory $entityTypeFactory
-     */
-    public function __construct(\Magento\Eav\Model\Entity\TypeFactory $entityTypeFactory)
-    {
-        $this->entityTypeFactory = $entityTypeFactory;
-    }
-
-    /**
-     * Transform Xml to array
-     *
-     * @param \DOMNode $source
-     * @return array
-     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
-     */
-    protected function toArray(\DOMNode $source)
-    {
-        $result = [];
-        if ($source->hasAttributes()) {
-            foreach ($source->attributes as $attr) {
-                $result['@attributes'][$attr->name] = $attr->value;
-            }
-        }
-
-        if (!$source->hasChildNodes()) {
-            if (empty($result)) {
-                $result = $source->nodeValue;
-            }
-        } else {
-            if ($source->hasChildNodes()) {
-                $groups = [];
-                foreach ($source->childNodes as $child) {
-                    if ($child->nodeType == XML_TEXT_NODE || $child->nodeType == XML_COMMENT_NODE) {
-                        continue;
-                    }
-                    if ($this->isTextNode($child)) {
-                        $result[$child->nodeName] = $this->getTextNode($child)->data;
-                    } else {
-                        if (in_array($child->nodeName, ['validate', 'filter', 'readonly'])) {
-                            if (!isset($result[$child->nodeName])) {
-                                $result[$child->nodeName] = [];
-                            }
-                            $result[$child->nodeName][] = $this->toArray($child);
-                        } else {
-                            if (isset($result[$child->nodeName])) {
-                                if (!isset($groups[$child->nodeName])) {
-                                    $result[$child->nodeName] = [$result[$child->nodeName]];
-                                    $groups[$child->nodeName] = 1;
-                                }
-                                $result[$child->nodeName][] = $this->toArray($child);
-                            } else {
-                                $result[$child->nodeName] = $this->toArray($child);
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        return $result;
-    }
-
-    /**
-     * Convert configuration
-     *
-     * @param \DOMDocument $source
-     * @return array
-     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
-     * @SuppressWarnings(PHPMD.NPathComplexity)
-     */
-    public function convert($source)
-    {
-        $data = [];
-        $output = $this->toArray($source);
-        foreach ($output['config']['dataSource'] as $dataSource) {
-            $data[$dataSource['@attributes']['name']] = [
-                'name' => $dataSource['@attributes']['name'],
-                'label' => $dataSource['@attributes']['label'],
-                'dataSet' => $dataSource['@attributes']['dataSet'],
-            ];
-            $fields = [];
-            if (isset($dataSource['fields']['@attributes']['entityType'])) {
-                $entityType = $this->entityTypeFactory->create()
-                    ->load($dataSource['fields']['@attributes']['entityType'], 'entity_type_code');
-                $attributeCollection = $entityType->getAttributeCollection();
-                foreach ($attributeCollection as $attribute) {
-                    if ($attribute->getIsUserDefined()) {
-                        $fields[$attribute->getAttributeCode()] = [
-                            'name' => $attribute->getAttributeCode(),
-                            'source' => 'eav',
-                            'formElement' => $this->mapFrontendInput($attribute->getFrontendInput()),
-                            'is_required' => $attribute->getScopeIsRequired(),
-                            'default_value' => $attribute->getScopeDefaultValue(),
-                            'visible' => $attribute->getScopeIsVisible(),
-                            'multiline_count' => $attribute->getScopeMultilineCount(),
-                        ];
-                        if ($attribute->getValidateRules()) {
-                            $fields[$attribute->getAttributeCode()]['constraints']['validate']
-                                = $attribute->getValidateRules();
-                        }
-                    }
-                }
-            }
-            foreach ($dataSource['fields']['field'] as $field) {
-                foreach ($field['@attributes'] as $key => $value) {
-                    $fields[$field['@attributes']['name']][$key] = $value;
-                }
-                if (isset($field['@attributes']['source'])) {
-                    if (in_array($field['@attributes']['source'], ['lookup', 'option', 'reference'])) {
-                        $fields[$field['@attributes']['name']]['reference'] = [
-                            'target' => $field['reference']['@attributes']['target'],
-                            'targetField' => $field['reference']['@attributes']['targetField'],
-                            'referencedField' => $field['reference']['@attributes']['referencedField'],
-                            'neededField' => $field['reference']['@attributes']['neededField'],
-                        ];
-                    }
-                }
-                if (isset($field['tooltip'])) {
-                    $fields[$field['@attributes']['name']]['tooltip'] = [
-                        'link' => $field['tooltip']['link'],
-                        'description' => $field['tooltip']['description'],
-                    ];
-                }
-                if (isset($field['constraints']['validate'])) {
-                    foreach ($field['constraints']['validate'] as $rule) {
-                        $fields[$field['@attributes']['name']]['constraints']['validate'][$rule['@attributes']['name']] =
-                            isset($rule['@attribute']['value'])
-                                ? $rule['@attribute']['value'] : true;
-                    }
-                }
-                if (isset($field['constraints']['filter'])) {
-                    foreach ($field['constraints']['filter'] as $filter) {
-                        $filterValues['on'] = isset($filter['@attributes']['on']) ? $filter['@attributes']['on'] : null;
-                        $filterValues['by'] = isset($filter['@attributes']['by']) ? $filter['@attributes']['by'] : null;
-                        $filterValues['value'] = isset($filter['@attributes']['value'])
-                            ? $filter['@attributes']['value'] : null;
-                        $fields[$field['@attributes']['name']]['constraints']['filter'][] = $filterValues;
-                    }
-                }
-                if (isset($field['constraints']['readonly'])) {
-                    foreach ($field['constraints']['readonly'] as $condition) {
-                        $fields[$field['@attributes']['name']]['constraints']['readonly'][] = [
-                            'on' => $condition['@attributes']['on'],
-                            'value' => $condition['@attributes']['value'],
-                        ];
-                    }
-                }
-            }
-            $data[$dataSource['@attributes']['name']]['fields'] = $fields;
-            if (!empty($dataSource['references'])) {
-                foreach ($dataSource['references'] as $reference) {
-                    $data[$reference['@attributes']['target']]['children'][$dataSource['@attributes']['name']][] = [
-                        'targetField' => $reference['@attributes']['targetField'],
-                        'referencedField' => $reference['@attributes']['referencedField'],
-                    ];
-                }
-            }
-        }
-
-        return $data;
-    }
-
-    /**
-     * @param \DOMNode $node
-     * @return bool
-     */
-    protected function isTextNode(\DOMNode $node)
-    {
-        $result = true;
-        if (!$node instanceof \DOMText) {
-            if ($node->hasChildNodes()) {
-                foreach ($node->childNodes as $child) {
-                    if ($child->nodeType != XML_TEXT_NODE) {
-                        $result = false;
-                        break;
-                    }
-                }
-            } else {
-                $result = false;
-            }
-        }
-        return $result;
-    }
-
-    /**
-     * @param \DOMNode $node
-     * @return \DOMText
-     */
-    protected function getTextNode(\DOMNode $node)
-    {
-        if ($node instanceof \DOMText) {
-            return $node;
-        }
-        foreach ($node->childNodes as $child) {
-            if ($child->nodeType == XML_TEXT_NODE) {
-                return $child;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * @param string $input
-     * @return string
-     */
-    protected function mapFrontendInput($input)
-    {
-        return isset($this->inputTypeMap[$input]) ? $this->inputTypeMap[$input] : 'input';
-    }
-}
diff --git a/app/code/Magento/Ui/DataProvider/Config/Data.php b/app/code/Magento/Ui/DataProvider/Config/Data.php
deleted file mode 100644
index a975606507f0dcca2896847d54cf4a261eb09d01..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/DataProvider/Config/Data.php
+++ /dev/null
@@ -1,34 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-namespace Magento\Ui\DataProvider\Config;
-
-/**
- * Class Data
- */
-class Data extends \Magento\Framework\Config\Data
-{
-    /**
-     * @param Reader $reader
-     * @param \Magento\Framework\Config\CacheInterface $cache
-     */
-    public function __construct(
-        Reader $reader,
-        \Magento\Framework\Config\CacheInterface $cache
-    ) {
-        $this->cacheTags = [\Magento\Eav\Model\Entity\Attribute::CACHE_TAG];
-        parent::__construct($reader, $cache, 'data_source');
-    }
-
-    /**
-     * @param string $name
-     * @return array|mixed|null
-     */
-    public function getDataSource($name)
-    {
-        return $this->get($name);
-    }
-}
diff --git a/app/code/Magento/Ui/DataProvider/Config/FileResolver.php b/app/code/Magento/Ui/DataProvider/Config/FileResolver.php
deleted file mode 100644
index fbd093b8c1acd0b47a2811897796da918a3ff14b..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/DataProvider/Config/FileResolver.php
+++ /dev/null
@@ -1,53 +0,0 @@
-<?php
-/**
- * Hierarchy config file resolver
- *
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\DataProvider\Config;
-
-use Magento\Framework\App\Filesystem\DirectoryList;
-use Magento\Framework\Config\FileIteratorFactory;
-use Magento\Framework\Config\FileResolverInterface;
-use Magento\Framework\Filesystem;
-
-/**
- * Class FileResolver
- */
-class FileResolver implements \Magento\Framework\Config\FileResolverInterface
-{
-    /**
-     * @var \Magento\Framework\Filesystem\Directory\ReadInterface
-     */
-    protected $directoryRead;
-
-    /**
-     * @var FileIteratorFactory
-     */
-    protected $iteratorFactory;
-
-    /**
-     * @param Filesystem $filesystem
-     * @param FileIteratorFactory $iteratorFactory
-     */
-    public function __construct(
-        Filesystem $filesystem,
-        FileIteratorFactory $iteratorFactory
-    ) {
-        $this->directoryRead = $filesystem->getDirectoryRead(DirectoryList::MODULES);
-        $this->iteratorFactory = $iteratorFactory;
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function get($filename, $scope)
-    {
-        $iterator = $this->iteratorFactory->create(
-            $this->directoryRead,
-            $this->directoryRead->search('/*/*/etc/data_source/' . $filename)
-        );
-        return $iterator;
-    }
-}
diff --git a/app/code/Magento/Ui/DataProvider/Config/Reader.php b/app/code/Magento/Ui/DataProvider/Config/Reader.php
deleted file mode 100644
index 6360437f16eb38326cf8a69ec0f6bd8c24102da1..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/DataProvider/Config/Reader.php
+++ /dev/null
@@ -1,54 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-namespace Magento\Ui\DataProvider\Config;
-
-use Magento\Framework\Config\ValidationStateInterface;
-
-/**
- * Class Reader
- */
-class Reader extends \Magento\Framework\Config\Reader\Filesystem
-{
-    /**
-     * List of id attributes for merge
-     *
-     * @var array
-     */
-    protected $_idAttributes = ['/config/dataSource' => 'name'];
-
-    /**
-     * @param FileResolver $fileResolver
-     * @param Converter $converter
-     * @param SchemaLocator $schemaLocator
-     * @param ValidationStateInterface $validationState
-     * @param string $fileName
-     * @param array $idAttributes
-     * @param string $domDocumentClass
-     * @param string $defaultScope
-     */
-    public function __construct(
-        FileResolver $fileResolver,
-        Converter $converter,
-        SchemaLocator $schemaLocator,
-        ValidationStateInterface $validationState,
-        $fileName = '*.xml',
-        $idAttributes = [],
-        $domDocumentClass = 'Magento\Framework\Config\Dom',
-        $defaultScope = ''
-    ) {
-        parent::__construct(
-            $fileResolver,
-            $converter,
-            $schemaLocator,
-            $validationState,
-            $fileName,
-            $idAttributes,
-            $domDocumentClass,
-            $defaultScope
-        );
-    }
-}
diff --git a/app/code/Magento/Ui/DataProvider/Config/SchemaLocator.php b/app/code/Magento/Ui/DataProvider/Config/SchemaLocator.php
deleted file mode 100644
index 02f64378eefe18816c057dff8b19319ba49ec96a..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/DataProvider/Config/SchemaLocator.php
+++ /dev/null
@@ -1,43 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\DataProvider\Config;
-
-/**
- * Class SchemaLocator
- */
-class SchemaLocator implements \Magento\Framework\Config\SchemaLocatorInterface
-{
-    /**
-     * Path to corresponding XSD file with validation rules for both individual and merged configs
-     *
-     * @var string
-     */
-    private $_schema;
-
-    /**
-     * @param \Magento\Framework\Module\Dir\Reader $moduleReader
-     */
-    public function __construct(\Magento\Framework\Module\Dir\Reader $moduleReader)
-    {
-        $this->_schema = $moduleReader->getModuleDir('etc', 'Magento_Ui') . '/data_source.xsd';
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function getSchema()
-    {
-        return $this->_schema;
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function getPerFileSchema()
-    {
-        return $this->_schema;
-    }
-}
diff --git a/app/code/Magento/Ui/DataProvider/DataProviderCollectionInterface.php b/app/code/Magento/Ui/DataProvider/DataProviderCollectionInterface.php
deleted file mode 100644
index b6cc0da7753b1fcd4e9b97558d22c31c19cc7f01..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/DataProvider/DataProviderCollectionInterface.php
+++ /dev/null
@@ -1,29 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\DataProvider;
-
-use Magento\Framework\View\Element\UiComponent\DataProviderInterface;
-
-/**
- * Interface DataProviderCollectionInterface
- */
-interface DataProviderCollectionInterface extends DataProviderInterface
-{
-    /**
-     * Add a filter to the data
-     *
-     * @param array $filter
-     * @return void
-     */
-    public function addFilter(array $filter);
-
-    /**
-     * Get data
-     *
-     * @return \Magento\Framework\Object[]
-     */
-    public function getData();
-}
diff --git a/app/code/Magento/Ui/DataProvider/DataProviderEntityInterface.php b/app/code/Magento/Ui/DataProvider/DataProviderEntityInterface.php
deleted file mode 100644
index f36e72f9f2eb7dac08f6556bd9e4f2541a905ef4..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/DataProvider/DataProviderEntityInterface.php
+++ /dev/null
@@ -1,16 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\DataProvider;
-
-use Magento\Framework\View\Element\UiComponent\DataProviderInterface;
-
-/**
- * Interface DataProviderEntityInterface
- */
-interface DataProviderEntityInterface extends DataProviderInterface
-{
-    const CONFIG_KEY = 'field';
-}
diff --git a/app/code/Magento/Ui/DataProvider/EavValidationRul.php b/app/code/Magento/Ui/DataProvider/EavValidationRul.php
new file mode 100644
index 0000000000000000000000000000000000000000..1d338ec30755af34f8653ca99b65f8202b141d7a
--- /dev/null
+++ b/app/code/Magento/Ui/DataProvider/EavValidationRul.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\DataProvider;
+
+use Magento\Eav\Model\Entity\Attribute\AbstractAttribute;
+
+/**
+ * Class EavValidationRul
+ */
+class EavValidationRul
+{
+    /**
+     * @var array
+     */
+    protected $validationRul = [
+        'input_validation' => [
+            'email' => ['validate-email' => true],
+            'date' => ['validate-date' => true],
+        ],
+    ];
+
+    /**
+     * Build validation rules
+     *
+     * @param AbstractAttribute $attribute
+     * @param array $data
+     * @return array
+     */
+    public function build(AbstractAttribute $attribute, array $data)
+    {
+        $rules = [];
+        if (isset($data['required']) && $data['required'] == 1) {
+            $rules['required-entry'] = true;
+        }
+        $validation = $attribute->getValidateRules();
+        if (!empty($validation)) {
+            foreach ($validation as $type => $ruleName) {
+                switch ($type) {
+                    case 'input_validation':
+                        if (isset($this->validationRul[$type][$ruleName])) {
+                            $rules = array_merge($rules, $this->validationRul[$type][$ruleName]);
+                        }
+                        break;
+                    case 'min_text_length':
+                    case 'max_text_length':
+                        $rules = array_merge($rules, [$type => $ruleName]);
+                        break;
+                }
+
+            }
+        }
+
+        return $rules;
+    }
+}
diff --git a/app/code/Magento/Ui/DataProvider/Manager.php b/app/code/Magento/Ui/DataProvider/Manager.php
deleted file mode 100644
index c2f2379ff77ba8ded751261fe6754a1c1241067c..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/DataProvider/Manager.php
+++ /dev/null
@@ -1,153 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-namespace Magento\Ui\DataProvider;
-
-use Magento\Framework\ObjectManagerInterface;
-use Magento\Ui\DataProvider\Config\Data as Config;
-
-/**
- * Class Manager
- */
-class Manager
-{
-    /**
-     * @var Config
-     */
-    protected $config;
-
-    /**
-     * @var ObjectManagerInterface
-     */
-    protected $objectManager;
-
-    /**
-     * @var ObjectManagerInterface
-     */
-    protected $metadataFactory;
-
-    /**
-     * @var array
-     */
-    protected $cache = [];
-
-    /**
-     * @param Config $config
-     * @param ObjectManagerInterface $objectManager
-     * @param MetadataFactory $metadataFactory
-     */
-    public function __construct(Config $config, ObjectManagerInterface $objectManager, MetadataFactory $metadataFactory)
-    {
-        $this->config = $config;
-        $this->objectManager = $objectManager;
-        $this->metadataFactory = $metadataFactory;
-    }
-
-    /**
-     * Returns Data Source metadata
-     *
-     * @param string $dataSource
-     * @return \Magento\Ui\DataProvider\Metadata
-     */
-    public function getMetadata($dataSource)
-    {
-        return $this->metadataFactory->create(
-            [
-                'config' => $this->config->getDataSource($dataSource),
-            ]
-        );
-    }
-
-    /**
-     * @param string $dataSource
-     * @param array $filters
-     * @return mixed
-     */
-    public function getCollectionData($dataSource, array $filters = [])
-    {
-        $collectionHash = md5($dataSource . serialize($filters));
-        if (!isset($this->cache[$collectionHash])) {
-            $config = $this->config->getDataSource($dataSource);
-            /** @var \Magento\Framework\Data\Collection\Db $collection */
-            $collection = $this->objectManager->create($config['dataSet']);
-
-            foreach ($config['fields'] as $field) {
-                if (isset($field['source']) && $field['source'] == 'eav') {
-                    $collection->addAttributeToSelect($field['name']);
-                }
-            }
-
-            if ($filters) {
-                foreach ($filters as $field => $expression) {
-                    $collection->addFieldToFilter($field, $expression);
-                }
-            }
-            $this->cache[$collectionHash] = $collection->getItems();
-        }
-        return $this->cache[$collectionHash];
-    }
-
-    /**
-     * Returns data by specified Data Source name
-     *
-     * @param string $dataSource
-     * @param array $filters
-     * @return array
-     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
-     */
-    public function getData($dataSource, array $filters = [])
-    {
-        $children = $this->getMetadata($dataSource)->getChildren();
-        $fields = $this->getMetadata($dataSource)->getFields();
-        $items = $this->getCollectionData($dataSource, $filters);
-
-        $rows = [];
-        foreach ($items as $item) {
-            $row = [];
-            foreach ($fields as $name => $field) {
-                if (isset($field['source']) && $field['source'] == 'lookup') {
-                    $lookupCollection = $this->getCollectionData(
-                        $field['reference']['target'],
-                        [$field['reference']['targetField'] => $item->getData($field['reference']['referencedField'])]
-                    );
-                    $lookup = reset($lookupCollection);
-                    $row[$name] = $lookup[$field['reference']['neededField']];
-                } elseif (isset($field['source']) && $field['source'] == 'reference') {
-                    $lookupCollection = $this->getCollectionData(
-                        $field['reference']['target'],
-                        [$field['reference']['targetField'] => $item->getData($field['reference']['referencedField'])]
-                    );
-                    $lookup = reset($lookupCollection);
-                    $isReferenced = isset($lookup[$field['reference']['neededField']])
-                        && $lookup[$field['reference']['neededField']] == $item->getId();
-                    $row[$name] = $isReferenced;
-                } elseif (isset($field['source']) && $field['source'] == 'option') {
-                    $row[$name] = $item->getData($field['reference']['referencedField']);
-                } else {
-                    $row[$name] = $item->getData($name);
-                }
-
-                if (isset($field['size'])) {
-                    $row[$name] = explode("\n", $row[$name]);
-                }
-            }
-            if (!empty($children)) {
-                foreach ($children as $name => $reference) {
-                    $filter = [];
-                    foreach ($reference as $metadata) {
-                        $filter[$metadata['referencedField']] = $row[$metadata['targetField']];
-                    }
-                    $row[$name] = $this->getData($name, $filter);
-                    if (empty($row[$name])) {
-                        unset($row[$name]);
-                    }
-                }
-            }
-            $rows[$item->getId()] = $row;
-        }
-        return $rows;
-    }
-}
diff --git a/app/code/Magento/Ui/DataProvider/Metadata.php b/app/code/Magento/Ui/DataProvider/Metadata.php
deleted file mode 100644
index 0d86e46754b76349a63947d928f43f1cf44b7261..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/DataProvider/Metadata.php
+++ /dev/null
@@ -1,324 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-namespace Magento\Ui\DataProvider;
-
-use Magento\Framework\ObjectManagerInterface;
-use Magento\Framework\Validator\UniversalFactory;
-
-/**
- * Class Metadata
- */
-class Metadata implements \Iterator, \ArrayAccess
-{
-    /**
-     * Node name of children data sources
-     */
-    const CHILD_DATA_SOURCES = 'childDataSources';
-
-    /**
-     * @var array
-     */
-    protected $config;
-
-    /**
-     * @var array
-     */
-    protected $metadata = [];
-
-    /**
-     * @var array
-     */
-    protected $attributes = [];
-
-    /**
-     * @var \Magento\Eav\Model\Entity\Collection\AbstractCollection
-     */
-    protected $dataSet;
-
-    /**
-     * @var array
-     */
-    protected $children;
-
-    /**
-     * @var Manager
-     */
-    protected $manager;
-
-    /**
-     * @var UniversalFactory
-     */
-    protected $universalFactory;
-
-    /**
-     * @param ObjectManagerInterface $objectManager
-     * @param Manager $manager
-     * @param UniversalFactory $universalFactory
-     * @param array $config
-     */
-    public function __construct(
-        ObjectManagerInterface $objectManager,
-        Manager $manager,
-        UniversalFactory $universalFactory,
-        array $config
-    ) {
-        $this->config = $config;
-        if (isset($this->config['children'])) {
-            $this->config['fields'][self::CHILD_DATA_SOURCES] = $config['children'];
-        }
-        $this->dataSet = $objectManager->get($this->config['dataSet']);
-        $this->manager = $manager;
-        $this->universalFactory = $universalFactory;
-        $this->initAttributes();
-
-        foreach ($this->config['fields'] as $name => & $field) {
-            $this->prepare($name, $field);
-        }
-    }
-
-    /**
-     * Return Data Source fields
-     *
-     * @return array
-     */
-    public function getFields()
-    {
-        return isset($this->config['fields']) ? $this->config['fields'] : [];
-    }
-
-    /**
-     * Return Data Source children
-     *
-     * @return array
-     */
-    public function getChildren()
-    {
-        return isset($this->config['children']) ? $this->config['children'] : [];
-    }
-
-    /**
-     * Return Data Source label
-     *
-     * @return string
-     */
-    public function getLabel()
-    {
-        return $this->config['label'];
-    }
-
-    /**
-     * Reset the Collection to the first element
-     *
-     * @return mixed
-     */
-    public function rewind()
-    {
-        return reset($this->config['fields']);
-    }
-
-    /**
-     * Return the current element
-     *
-     * @return mixed
-     */
-    public function current()
-    {
-        return current($this->config['fields']);
-    }
-
-    /**
-     * Return the key of the current element
-     *
-     * @return string
-     */
-    public function key()
-    {
-        return key($this->config['fields']);
-    }
-
-    /**
-     * Move forward to next element
-     *
-     * @return mixed
-     */
-    public function next()
-    {
-        return next($this->config['fields']);
-    }
-
-    /**
-     * Checks if current position is valid
-     *
-     * @return bool
-     */
-    public function valid()
-    {
-        return (bool)$this->key();
-    }
-
-    /**
-     * Returns price class by code
-     *
-     * @param string $code
-     * @return string|array
-     */
-    public function get($code)
-    {
-        return isset($this->config['fields'][$code]) ? $this->config['fields'][$code] : false;
-    }
-
-    /**
-     * The value to set.
-     *
-     * @param string $offset
-     * @param string $value
-     * @return void
-     */
-    public function offsetSet($offset, $value)
-    {
-        if ($offset === null) {
-            $this->config['fields'][] = $value;
-        } else {
-            $this->config['fields'][$offset] = $value;
-        }
-    }
-
-    /**
-     * The return value will be casted to boolean if non-boolean was returned.
-     *
-     * @param string $offset
-     * @return bool
-     */
-    public function offsetExists($offset)
-    {
-        return isset($this->config['fields'][$offset]);
-    }
-
-    /**
-     * The offset to unset.
-     *
-     * @param string $offset
-     * @return void
-     */
-    public function offsetUnset($offset)
-    {
-        unset($this->config['fields'][$offset]);
-    }
-
-    /**
-     * The offset to retrieve.
-     *
-     * @param string $offset
-     * @return string
-     */
-    public function offsetGet($offset)
-    {
-        return isset($this->config['fields'][$offset]) ? $this->config['fields'][$offset] : null;
-    }
-
-    /**
-     * @return void
-     */
-    protected function initAttributes()
-    {
-        if (empty($this->attributes)) {
-            foreach ($this->config['fields'] as $field) {
-                if (isset($field['source']) && $field['source'] == 'eav') {
-                    $attribute = $this->dataSet->getEntity()->getAttribute($field['name']);
-                    if ($attribute) {
-                        $this->attributes[$field['name']] = $attribute->getData();
-                        $options = [];
-                        if ($attribute->usesSource()) {
-                            $options = $attribute->getSource()->getAllOptions();
-                        }
-                        $this->attributes[$field['name']]['options'] = $options;
-                        $this->attributes[$field['name']]['is_required'] = $attribute->getIsRequired();
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * @param string $name
-     * @param array $field
-     * @return void
-     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
-     * @SuppressWarnings(PHPMD.NPathComplexity)
-     * @SuppressWarnings(PHPMD.UnusedLocalVariable)
-     */
-    protected function prepare($name, array & $field)
-    {
-        if ($name == self::CHILD_DATA_SOURCES) {
-            foreach ($field as $childName => $childConfig) {
-                $field[$childName] = $this->manager->getMetadata($childName);
-            }
-            return;
-        }
-
-        $options = [];
-        if (isset($field['source'])) {
-            if ($field['source'] == 'option') {
-                $rawOptions = $this->manager->getData(
-                    $field['reference']['target']
-                );
-                $options[] = [
-                    'label' => __('Please, select...'),
-                    'value' => null,
-                ];
-                foreach ($rawOptions as $rawOption) {
-                    $options[] = [
-                        'label' => $rawOption[$field['reference']['neededField']],
-                        'value' => $rawOption[$field['reference']['targetField']],
-
-                    ];
-                }
-            }
-        } else {
-            if (isset($field['optionProvider'])) {
-                list($source, $method) = explode('::', $field['optionProvider']);
-                $sourceModel = $this->universalFactory->create($source);
-                $options = $sourceModel->$method();
-            }
-        }
-
-        $attributeCodes = [
-            'options' => ['eav_map' => 'options', 'default' => $options],
-            'dataType' => ['eav_map' => 'frontend_input', 'default' => 'text'],
-            'filterType' => ['default' => 'input_filter'],
-            'formElement' => ['default' => 'input'],
-            'displayArea' => ['default' => 'body'],
-            'visible' => ['eav_map' => 'is_visible', 'default' => true],
-            'required' => ['eav_map' => 'is_required', 'default' => false],
-            'label' => ['eav_map' => 'frontend_label'],
-            'sortOrder' => ['eav_map' => 'sort_order'],
-            'notice' => ['eav_map' => 'note'],
-            'default' => ['eav_map' => 'default_value'],
-            'unique' => [],
-            'description' => [],
-            'constraints' => [],
-            'customEntry' => [],
-            'size' => ['eav_map' => 'scope_multiline_count'],
-            'tooltip' => [],
-            'fieldGroup' => [],
-        ];
-
-        foreach ($attributeCodes as $code => $info) {
-            if (!isset($field[$code])) {
-                if (isset($this->attributes[$name]) && isset($info['eav_map'])) {
-                    $field[$code] = $this->attributes[$name][$info['eav_map']];
-                } elseif (empty($field[$code]) && !empty($info['default'])) {
-                    $field[$code] = $info['default'];
-                }
-            }
-        }
-
-        if (isset($field['required']) && $field['required']) {
-            $field['constraints']['validate']['required-entry'] = true;
-        }
-    }
-}
diff --git a/app/code/Magento/Ui/TemplateEngine/Xhtml.php b/app/code/Magento/Ui/TemplateEngine/Xhtml.php
new file mode 100644
index 0000000000000000000000000000000000000000..e4a7765e90f79c0e2ad0223177707d0ed528c18c
--- /dev/null
+++ b/app/code/Magento/Ui/TemplateEngine/Xhtml.php
@@ -0,0 +1,93 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\TemplateEngine;
+
+use Magento\Ui\TemplateEngine\Xhtml\Result;
+use Magento\Ui\TemplateEngine\Xhtml\Template;
+use Magento\Ui\TemplateEngine\Xhtml\Compiler;
+use Magento\Ui\TemplateEngine\Xhtml\ResultFactory;
+use Magento\Framework\View\Element\BlockInterface;
+use Magento\Framework\View\TemplateEngineInterface;
+use Magento\Ui\TemplateEngine\Xhtml\CompilerFactory;
+use Magento\Ui\TemplateEngine\Xhtml\TemplateFactory;
+use Magento\Framework\View\Element\UiComponent\Config\Provider\Template as TemplateProvider;
+
+/**
+ * Class Xhtml
+ */
+class Xhtml implements TemplateEngineInterface
+{
+    const INSTANCE_NAME = 'Magento\Ui\Content\Template\Type\Xhtml\Template';
+
+    /**
+     * @var TemplateProvider
+     */
+    protected $templateProvider;
+
+    /**
+     * @var ResultFactory
+     */
+    protected $resultFactory;
+
+    /**
+     * @var TemplateFactory
+     */
+    protected $templateFactory;
+
+    /**
+     * @var CompilerFactory
+     */
+    protected $compilerFactory;
+
+    /**
+     * Constructor
+     *
+     * @param TemplateProvider $templateProvider
+     * @param ResultFactory $resultFactory
+     * @param TemplateFactory $templateFactory
+     * @param CompilerFactory $compilerFactory
+     */
+    public function __construct(
+        TemplateProvider $templateProvider,
+        ResultFactory $resultFactory,
+        TemplateFactory $templateFactory,
+        CompilerFactory $compilerFactory
+    ) {
+        $this->templateProvider = $templateProvider;
+        $this->resultFactory = $resultFactory;
+        $this->templateFactory = $templateFactory;
+        $this->compilerFactory = $compilerFactory;
+    }
+
+    /**
+     * Render template
+     *
+     * Render the named template in the context of a particular block and with
+     * the data provided in $vars.
+     *
+     * @param \Magento\Framework\View\Element\BlockInterface $block
+     * @param string $templateFile
+     * @param array $dictionary
+     * @return Result
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function render(BlockInterface $block, $templateFile, array $dictionary = [])
+    {
+        /** @var Template $template */
+        $template = $this->templateFactory->create(['content' => $this->templateProvider->getTemplate($templateFile)]);
+
+        /** @var Result $result */
+        $result = $this->resultFactory->create(
+            [
+                'template' => $template,
+                'compiler' => $this->compilerFactory->create(),
+                'component' => $block
+            ]
+        );
+
+        return $result;
+    }
+}
diff --git a/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler.php b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler.php
new file mode 100644
index 0000000000000000000000000000000000000000..68830d2a6574ffa1cd1bc82579cff98f56ea7a90
--- /dev/null
+++ b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler.php
@@ -0,0 +1,175 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\TemplateEngine\Xhtml;
+
+use Magento\Framework\Object;
+use Magento\Framework\View\Element\UiComponentInterface;
+use Magento\Ui\TemplateEngine\Xhtml\Compiler\TextInterface;
+use Magento\Ui\TemplateEngine\Xhtml\Compiler\CdataInterface;
+use Magento\Ui\TemplateEngine\Xhtml\Compiler\CommentInterface;
+use Magento\Ui\TemplateEngine\Xhtml\Compiler\AttributeInterface;
+use Magento\Ui\TemplateEngine\Xhtml\Compiler\Element\ElementInterface;
+
+/**
+ * Class Compiler
+ */
+class Compiler
+{
+    const PATTERN_TAG = '|@|';
+
+    /**
+     * @var TextInterface
+     */
+    protected $compilerText;
+
+    /**
+     * @var AttributeInterface
+     */
+    protected $compilerAttribute;
+
+    /**
+     * @var CdataInterface
+     */
+    protected $compilerCdata;
+
+    /**
+     * @var CommentInterface
+     */
+    protected $compilerComment;
+
+    /**
+     * @var ElementInterface[]
+     */
+    protected $elementCompilers;
+
+    /**
+     * Postprocessing data
+     *
+     * @var array
+     */
+    protected $data;
+
+    /**
+     * Constructor
+     *
+     * @param TextInterface $compilerText
+     * @param AttributeInterface $compilerAttribute
+     * @param AttributeInterface|CdataInterface $compilerCdata
+     * @param CommentInterface $compilerComment
+     * @param ElementInterface[] $elementCompilers
+     */
+    public function __construct(
+        TextInterface $compilerText,
+        AttributeInterface $compilerAttribute,
+        CdataInterface $compilerCdata,
+        CommentInterface $compilerComment,
+        array $elementCompilers
+    ) {
+        $this->compilerText = $compilerText;
+        $this->compilerAttribute = $compilerAttribute;
+        $this->compilerCdata = $compilerCdata;
+        $this->compilerComment = $compilerComment;
+        $this->elementCompilers = $elementCompilers;
+    }
+
+    /**
+     * The compilation of the template and filling in the data
+     *
+     * @param \DOMNode $node
+     * @param UiComponentInterface $component
+     * @param Object $context
+     * @return void
+     */
+    public function compile(\DOMNode $node, UiComponentInterface $component, Object $context)
+    {
+        switch ($node->nodeType) {
+            case XML_TEXT_NODE:
+                $this->compilerText->compile($node, $component);
+                break;
+            case XML_CDATA_SECTION_NODE:
+                $this->compilerCdata->compile($node, $component);
+                break;
+            case XML_COMMENT_NODE:
+                $this->compilerComment->compile($node, $component);
+                break;
+            default:
+                /** @var \DomElement $node */
+                if ($node->hasAttributes()) {
+                    foreach ($node->attributes as $attribute) {
+                        $this->compilerAttribute->compile($attribute, $component);
+                    }
+                }
+                $compiler = $this->getElementCompiler($node->nodeName);
+                if (null !== $compiler) {
+                    $compiler->compile($this, $node, $component, $context);
+                } else if ($node->hasChildNodes()) {
+                    foreach ($this->getChildNodes($node) as $child) {
+                        $this->compile($child, $component, $context);
+                    }
+                }
+        }
+    }
+
+    /**
+     * Run postprocessing contents template
+     *
+     * @param string $content
+     * @return string
+     */
+    public function postprocessing($content)
+    {
+        return preg_replace_callback(
+            '#' . preg_quote(static::PATTERN_TAG) . '(.+?)' . preg_quote(static::PATTERN_TAG) . '#',
+            function ($match) {
+                return isset($this->data[$match[1]]) ? $this->data[$match[1]] : '';
+            },
+            $content
+        );
+    }
+
+    /**
+     * Set postprocessing data
+     *
+     * @param string $key
+     * @param string $content
+     * @return void
+     */
+    public function setPostprocessingData($key, $content)
+    {
+        $this->data[$key] = $content;
+    }
+
+    /**
+     * Get child nodes
+     *
+     * @param \DOMElement $node
+     * @return \DOMElement[]
+     */
+    protected function getChildNodes(\DOMElement $node)
+    {
+        $childNodes = [];
+        foreach ($node->childNodes as $child) {
+            $childNodes[] = $child;
+        }
+
+        return $childNodes;
+    }
+
+    /**
+     * Get element compiler by name
+     *
+     * @param string $name
+     * @return ElementInterface
+     */
+    protected function getElementCompiler($name)
+    {
+        if (isset($this->elementCompilers[$name])) {
+            return $this->elementCompilers[$name];
+        }
+
+        return null;
+    }
+}
diff --git a/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Attribute.php b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Attribute.php
new file mode 100644
index 0000000000000000000000000000000000000000..f1ab640960831615310268cc4d99e6dc39fcd415
--- /dev/null
+++ b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Attribute.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\TemplateEngine\Xhtml\Compiler;
+
+use Magento\Framework\View\Element\UiComponentInterface;
+use Magento\Ui\TemplateEngine\Xhtml\Compiler\Directive\DirectiveInterface;
+
+/**
+ * Class Attribute
+ */
+class Attribute implements AttributeInterface
+{
+    /**
+     * @var DirectiveInterface[]
+     */
+    protected $directivePool;
+
+    /**
+     * Constructor
+     *
+     * @param DirectiveInterface[] $directivePool
+     */
+    public function __construct(array $directivePool)
+    {
+        $this->directivePool = $directivePool;
+    }
+
+    /**
+     * Compiles the Element node
+     *
+     * @param \DOMAttr $node
+     * @param UiComponentInterface $component
+     * @return void
+     */
+    public function compile(\DOMAttr $node, UiComponentInterface $component)
+    {
+        foreach ($this->directivePool as $directive) {
+            $node->value = preg_replace_callback(
+                $directive->getPattern(),
+                function ($match) use ($directive, $component) {
+                    return $directive->execute($match, $component);
+                },
+                $node->value
+            );
+        }
+    }
+}
diff --git a/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/AttributeInterface.php b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/AttributeInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..274d43bcde56dd2f793d0b5a2fd01abae047c9f6
--- /dev/null
+++ b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/AttributeInterface.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\TemplateEngine\Xhtml\Compiler;
+
+use Magento\Framework\View\Element\UiComponentInterface;
+
+/**
+ * Interface AttributeInterface
+ */
+interface AttributeInterface
+{
+    /**
+     * Compiles the Element node
+     *
+     * @param \DOMAttr $node
+     * @param UiComponentInterface $component
+     * @return void
+     */
+    public function compile(\DOMAttr $node, UiComponentInterface $component);
+}
diff --git a/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Cdata.php b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Cdata.php
new file mode 100644
index 0000000000000000000000000000000000000000..785a86eb5c2b36a46691383b702b7dd1c39a556b
--- /dev/null
+++ b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Cdata.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\TemplateEngine\Xhtml\Compiler;
+
+use Magento\Framework\View\Element\UiComponentInterface;
+
+/**
+ * Class Cdata
+ */
+class Cdata implements CdataInterface
+{
+    /**
+     * Compiles the CData Section node
+     *
+     * @param \DOMCdataSection $node
+     * @param UiComponentInterface $component
+     * @return void
+     */
+    public function compile(\DOMCdataSection $node, UiComponentInterface $component)
+    {
+        //
+    }
+}
diff --git a/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/CdataInterface.php b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/CdataInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..d37d9460fc2f8a49cbef9689a53776918e3fa2d4
--- /dev/null
+++ b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/CdataInterface.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\TemplateEngine\Xhtml\Compiler;
+
+use Magento\Framework\View\Element\UiComponentInterface;
+
+/**
+ * Interface CdataInterface
+ */
+interface CdataInterface
+{
+    /**
+     * Compiles the CData Section node
+     *
+     * @param \DOMCdataSection $node
+     * @param UiComponentInterface $component
+     * @return void
+     */
+    public function compile(\DOMCdataSection $node, UiComponentInterface $component);
+}
diff --git a/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Comment.php b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Comment.php
new file mode 100644
index 0000000000000000000000000000000000000000..2ad634611ab74b0d762947a1ac54b8695bd37768
--- /dev/null
+++ b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Comment.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\TemplateEngine\Xhtml\Compiler;
+
+use Magento\Framework\View\Element\UiComponentInterface;
+
+/**
+ * Class Comment
+ */
+class Comment implements CommentInterface
+{
+    /**
+     * Compiles the Comment node
+     *
+     * @param \DOMComment $node
+     * @param UiComponentInterface $component
+     * @return void
+     */
+    public function compile(\DOMComment $node, UiComponentInterface $component)
+    {
+        //
+    }
+}
diff --git a/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/CommentInterface.php b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/CommentInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..19a2d6569c977a056e22cd69322475616f736acb
--- /dev/null
+++ b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/CommentInterface.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\TemplateEngine\Xhtml\Compiler;
+
+use Magento\Framework\View\Element\UiComponentInterface;
+
+/**
+ * Interface CommentInterface
+ */
+interface CommentInterface
+{
+    /**
+     * Compiles the Comment node
+     *
+     * @param \DOMComment $node
+     * @param UiComponentInterface $component
+     * @return void
+     */
+    public function compile(\DOMComment $node, UiComponentInterface $component);
+}
diff --git a/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Directive/CallableMethod.php b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Directive/CallableMethod.php
new file mode 100644
index 0000000000000000000000000000000000000000..ef14461f3610f8b3fc914a646b58ba62a73f2122
--- /dev/null
+++ b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Directive/CallableMethod.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\TemplateEngine\Xhtml\Compiler\Directive;
+
+use Magento\Framework\View\Element\UiComponentInterface;
+
+/**
+ * Class CallableMethod
+ */
+class CallableMethod implements DirectiveInterface
+{
+    /**
+     * Execute directive
+     *
+     * @param array $directive
+     * @param UiComponentInterface $component
+     * @return string
+     */
+    public function execute($directive, UiComponentInterface $component)
+    {
+        $object = $component;
+        $result = '';
+        foreach (explode('.', $directive[1]) as $method) {
+            $methodName = substr($method, 0, strpos($method, '('));
+            if (is_callable([$object, $methodName])) {
+                $result = $object->$methodName();
+                if (is_scalar($result)) {
+                    break;
+                }
+                $object = $result;
+                continue;
+            }
+            break;
+        }
+
+        return $result;
+    }
+
+    /**
+     * Get regexp search pattern
+     *
+     * @return string
+     */
+    public function getPattern()
+    {
+        return '#\{\{((?:[\w_0-9]+\(\)){1}(?:(?:\.[\w_0-9]+\(\))+)?)\}\}#';
+    }
+}
diff --git a/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Directive/DirectiveInterface.php b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Directive/DirectiveInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..b367a6b84f7b3edb47869b967a88e66dd84a6cf1
--- /dev/null
+++ b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Directive/DirectiveInterface.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\TemplateEngine\Xhtml\Compiler\Directive;
+
+use Magento\Framework\View\Element\UiComponentInterface;
+
+/**
+ * Interface DirectiveInterface
+ */
+interface DirectiveInterface
+{
+    /**
+     * Execute directive
+     *
+     * @param array $directive
+     * @param UiComponentInterface $component
+     * @return string
+     */
+    public function execute($directive, UiComponentInterface $component);
+
+    /**
+     * Get regexp search pattern
+     *
+     * @return string
+     */
+    public function getPattern();
+}
diff --git a/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Directive/Variable.php b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Directive/Variable.php
new file mode 100644
index 0000000000000000000000000000000000000000..b903855c821912ed3ec9d19eb1feb575c0e8c017
--- /dev/null
+++ b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Directive/Variable.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\TemplateEngine\Xhtml\Compiler\Directive;
+
+use Magento\Framework\View\Element\UiComponentInterface;
+
+/**
+ * Class Variable
+ */
+class Variable implements DirectiveInterface
+{
+    /**
+     * Execute directive
+     *
+     * @param array $directive
+     * @param UiComponentInterface $component
+     * @return string
+     */
+    public function execute($directive, UiComponentInterface $component)
+    {
+        return $component->getData($directive[1]);
+    }
+
+    /**
+     * Get regexp search pattern
+     *
+     * @return string
+     */
+    public function getPattern()
+    {
+        return '#\{\{([^\}\(]+)\}\}#';
+    }
+}
diff --git a/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Element/Content.php b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Element/Content.php
new file mode 100644
index 0000000000000000000000000000000000000000..1b31288c66fd8d397a64a2ee9e766fa6008856f1
--- /dev/null
+++ b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Element/Content.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\TemplateEngine\Xhtml\Compiler\Element;
+
+use Magento\Framework\Object;
+use Magento\Ui\TemplateEngine\Xhtml\Compiler;
+use Magento\Framework\View\Element\UiComponentInterface;
+
+/**
+ * Class Content
+ */
+class Content implements ElementInterface
+{
+    /**
+     * Compiles the Element node
+     *
+     * @param Compiler $compiler
+     * @param \DOMElement $node
+     * @param UiComponentInterface $component
+     * @param Object $context
+     * @return void
+     */
+    public function compile(
+        Compiler $compiler,
+        \DOMElement $node,
+        UiComponentInterface $component,
+        Object $context
+    ) {
+        $name = $node->getAttribute('name');
+        $content = (string)$component->renderChildComponent($name);
+        $name .= '_' . sprintf('%x', crc32(spl_object_hash($context)));
+        if (!empty($content)) {
+            $compiler->setPostprocessingData($name, $content);
+            $newNode = $node->ownerDocument->createTextNode(
+                Compiler::PATTERN_TAG . $name . Compiler::PATTERN_TAG
+            );
+            $node->parentNode->replaceChild($newNode, $node);
+        } else {
+            $node->parentNode->removeChild($node);
+        }
+    }
+}
diff --git a/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Element/ElementInterface.php b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Element/ElementInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..9ce4c9f74583636d568a83ac45456ecdffb8222c
--- /dev/null
+++ b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Element/ElementInterface.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\TemplateEngine\Xhtml\Compiler\Element;
+
+use Magento\Framework\Object;
+use Magento\Ui\TemplateEngine\Xhtml\Compiler;
+use Magento\Framework\View\Element\UiComponentInterface;
+
+/**
+ * Interface ElementInterface
+ */
+interface ElementInterface
+{
+    /**
+     * Compiles the Element node
+     *
+     * @param Compiler $compiler
+     * @param \DOMElement $node
+     * @param UiComponentInterface $component
+     * @param Object $context
+     * @return void
+     */
+    public function compile(
+        Compiler $compiler,
+        \DOMElement $node,
+        UiComponentInterface $component,
+        Object $context
+    );
+}
diff --git a/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Element/Form.php b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Element/Form.php
new file mode 100644
index 0000000000000000000000000000000000000000..513be2d1daf676ed9c433c82a2f23cbce0f3d588
--- /dev/null
+++ b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Element/Form.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\TemplateEngine\Xhtml\Compiler\Element;
+
+use Magento\Framework\Object;
+use Magento\Ui\TemplateEngine\Xhtml\Compiler;
+use Magento\Framework\View\Element\UiComponentInterface;
+
+/**
+ * Class Form
+ */
+class Form implements ElementInterface
+{
+    /**
+     * Compiles the Element node
+     *
+     * @param Compiler $compiler
+     * @param \DOMElement $node
+     * @param UiComponentInterface $component
+     * @param Object $context
+     * @return void
+     */
+    public function compile(
+        Compiler $compiler,
+        \DOMElement $node,
+        UiComponentInterface $component,
+        Object $context
+    ) {
+        foreach ($this->getChildNodes($node) as $child) {
+            $compiler->compile($child, $component, $context);
+        }
+    }
+
+    /**
+     * Get child nodes
+     *
+     * @param \DOMElement $node
+     * @return \DOMElement[]
+     */
+    protected function getChildNodes(\DOMElement $node)
+    {
+        $childNodes = [];
+        foreach ($node->childNodes as $child) {
+            $childNodes[] = $child;
+        }
+
+        return $childNodes;
+    }
+}
diff --git a/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Element/Render.php b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Element/Render.php
new file mode 100644
index 0000000000000000000000000000000000000000..9118a5e6b6aef4cd9a00cea1e21ec38234334660
--- /dev/null
+++ b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Element/Render.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\TemplateEngine\Xhtml\Compiler\Element;
+
+use Magento\Framework\Object;
+use Magento\Ui\TemplateEngine\Xhtml\Compiler;
+use Magento\Ui\TemplateEngine\Xhtml\Result;
+use Magento\Framework\View\Element\UiComponentInterface;
+
+/**
+ * Class Render
+ */
+class Render implements ElementInterface
+{
+    /**
+     * Compiles the Element node
+     *
+     * @param Compiler $compiler
+     * @param \DOMElement $node
+     * @param UiComponentInterface $component
+     * @param Object $context
+     * @return void
+     */
+    public function compile(
+        Compiler $compiler,
+        \DOMElement $node,
+        UiComponentInterface $component,
+        Object $context
+    ) {
+        $result = $component->renderChildComponent($node->getAttribute('name'));
+        if ($result instanceof Result) {
+            $node->parentNode->replaceChild($result->getDocumentElement(), $node);
+        } else if (!empty($result) && is_scalar($result)) {
+            $newFragment = $node->ownerDocument->createDocumentFragment();
+            $newFragment->appendXML($result);
+            $node->parentNode->replaceChild($newFragment, $node);
+            $node->parentNode->removeChild($node);
+        } else {
+            $node->parentNode->removeChild($node);
+        }
+    }
+}
diff --git a/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Text.php b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Text.php
new file mode 100644
index 0000000000000000000000000000000000000000..5bdfe50622c2a5b13000b10e9848265fc46e847f
--- /dev/null
+++ b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Text.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\TemplateEngine\Xhtml\Compiler;
+
+use Magento\Framework\View\Element\UiComponentInterface;
+use Magento\Ui\TemplateEngine\Xhtml\Compiler\Directive\DirectiveInterface;
+
+/**
+ * Class Text
+ */
+class Text implements TextInterface
+{
+    /**
+     * @var DirectiveInterface[]
+     */
+    protected $directivePool;
+
+    /**
+     * Constructor
+     *
+     * @param DirectiveInterface[] $directivePool
+     */
+    public function __construct(array $directivePool)
+    {
+        $this->directivePool = $directivePool;
+    }
+
+    /**
+     * Compiles the Element node
+     *
+     * @param \DOMText $node
+     * @param UiComponentInterface $component
+     * @return void
+     */
+    public function compile(\DOMText $node, UiComponentInterface $component)
+    {
+        $result = '';
+        foreach ($this->directivePool as $directive) {
+            $result = preg_replace_callback(
+                $directive->getPattern(),
+                function ($match) use ($directive, $component) {
+                    return $directive->execute($match, $component);
+                },
+                $node->textContent
+            );
+        }
+
+        $newNode = $node->ownerDocument->createTextNode($result);
+        $node->parentNode->replaceChild($newNode, $node);
+    }
+}
diff --git a/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/TextInterface.php b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/TextInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..1f1ffc41586164cbf0da8b960007b0c27c998476
--- /dev/null
+++ b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/TextInterface.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\TemplateEngine\Xhtml\Compiler;
+
+use Magento\Framework\View\Element\UiComponentInterface;
+
+/**
+ * Interface TextInterface
+ */
+interface TextInterface
+{
+    /**
+     * Compiles the Element node
+     *
+     * @param \DOMText $node
+     * @param UiComponentInterface $component
+     * @return void
+     */
+    public function compile(\DOMText $node, UiComponentInterface $component);
+}
diff --git a/app/code/Magento/Ui/TemplateEngine/Xhtml/Result.php b/app/code/Magento/Ui/TemplateEngine/Xhtml/Result.php
new file mode 100644
index 0000000000000000000000000000000000000000..2ad357022989fe9d7a4c9bd04d71d0faef71e151
--- /dev/null
+++ b/app/code/Magento/Ui/TemplateEngine/Xhtml/Result.php
@@ -0,0 +1,114 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\TemplateEngine\Xhtml;
+
+use Magento\Ui\Component\Layout\Generator\Structure;
+use Magento\Framework\View\Element\UiComponentInterface;
+
+/**
+ * Class Result
+ */
+class Result
+{
+    /**
+     * @var Template
+     */
+    protected $template;
+
+    /**
+     * @var Compiler
+     */
+    protected $compiler;
+
+    /**
+     * @var UiComponentInterface
+     */
+    protected $component;
+
+    /**
+     * @var Structure
+     */
+    protected $structure;
+
+    /**
+     * Constructor
+     *
+     * @param Template $template
+     * @param Compiler $compiler
+     * @param UiComponentInterface $component
+     * @param Structure $structure
+     */
+    public function __construct(
+        Template $template,
+        Compiler $compiler,
+        UiComponentInterface $component,
+        Structure $structure
+    ) {
+        $this->template = $template;
+        $this->compiler = $compiler;
+        $this->component = $component;
+        $this->structure = $structure;
+    }
+
+    /**
+     * Get result document root element \DOMElement
+     *
+     * @return \DOMElement
+     */
+    public function getDocumentElement()
+    {
+        return $this->template->getDocumentElement();
+    }
+
+    /**
+     * Append layout configuration
+     *
+     * @return void
+     */
+    public function appendLayoutConfiguration()
+    {
+        $layoutConfiguration = $this->wrapContent(json_encode($this->structure->generate($this->component)));
+        $this->template->append($layoutConfiguration);
+    }
+
+    /**
+     * Returns the string representation
+     *
+     * @return string
+     */
+    public function __toString()
+    {
+        try {
+            $templateRootElement = $this->getDocumentElement();
+            foreach ($templateRootElement->attributes as $name => $attribute) {
+                if ('noNamespaceSchemaLocation' === $name) {
+                    $this->getDocumentElement()->removeAttributeNode($attribute);
+                    break;
+                }
+            }
+            $templateRootElement->removeAttributeNS('http://www.w3.org/2001/XMLSchema-instance', 'xsi');
+            $this->compiler->compile($templateRootElement, $this->component, $this->component);
+            $this->appendLayoutConfiguration();
+            $result = $this->compiler->postprocessing($this->template->__toString());
+        } catch (\Exception $e) {
+            $result = '';
+        }
+        return $result;
+    }
+
+    /**
+     * Wrap content
+     *
+     * @param string $content
+     * @return string
+     */
+    protected function wrapContent($content)
+    {
+        return '<script type="text/x-magento-init"><![CDATA['
+        . '{"*": {"Magento_Ui/js/core/app": ' . str_replace(['<![CDATA[', ']]>'], '', $content) . '}}'
+        . ']]></script>';
+    }
+}
diff --git a/app/code/Magento/Ui/TemplateEngine/Xhtml/Template.php b/app/code/Magento/Ui/TemplateEngine/Xhtml/Template.php
new file mode 100644
index 0000000000000000000000000000000000000000..52cc35f0cf461c943598ba3206fdebe6ea26b824
--- /dev/null
+++ b/app/code/Magento/Ui/TemplateEngine/Xhtml/Template.php
@@ -0,0 +1,72 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\TemplateEngine\Xhtml;
+
+/**
+ * Class Template
+ */
+class Template
+{
+    const XML_VERSION = '1.0';
+
+    const XML_ENCODING = 'UTF-8';
+
+    /**
+     * @var \DOMElement
+     */
+    protected $templateNode;
+
+    /**
+     * Constructor
+     *
+     * @param string $content
+     */
+    public function __construct($content)
+    {
+        $document = new \DOMDocument(static::XML_VERSION, static::XML_ENCODING);
+        $document->loadXML($content);
+        $this->templateNode = $document->documentElement;
+    }
+
+    /**
+     * Get template root element
+     *
+     * @return \DOMElement
+     */
+    public function getDocumentElement()
+    {
+        return $this->templateNode;
+    }
+
+    /**
+     * Append
+     *
+     * @param string $content
+     * @return void
+     */
+    public function append($content)
+    {
+        $newFragment = $this->templateNode->ownerDocument->createDocumentFragment();
+        $newFragment->appendXML($content);
+        $this->templateNode->appendChild($newFragment);
+    }
+
+    /**
+     * Returns the string representation
+     *
+     * @return string
+     */
+    public function __toString()
+    {
+        try {
+            $this->templateNode->ownerDocument->normalizeDocument();
+            $result = $this->templateNode->ownerDocument->saveHTML();
+        } catch (\Exception $e) {
+            $result = '';
+        }
+        return $result;
+    }
+}
diff --git a/app/code/Magento/Ui/Test/Unit/Component/Control/ActionPoolTest.php b/app/code/Magento/Ui/Test/Unit/Component/Control/ActionPoolTest.php
index 461515aafe6c82463b6cde76ca5823502422b171..eaae007216af0aa226ff98336e22c727190102a0 100644
--- a/app/code/Magento/Ui/Test/Unit/Component/Control/ActionPoolTest.php
+++ b/app/code/Magento/Ui/Test/Unit/Component/Control/ActionPoolTest.php
@@ -127,18 +127,20 @@ class ActionPoolTest extends \PHPUnit_Framework_TestCase
             ->method('setChild')
             ->with($this->key, $toolbarContainerMock)
             ->willReturnSelf();
-        $this->assertNull($this->actionPool->add($this->key, $data, $this->uiComponentInterfaceMock));
+        $this->actionPool->add($this->key, $data, $this->uiComponentInterfaceMock);
     }
 
     public function testRemove()
     {
-        $this->assertNull($this->actionPool->remove($this->key));
+        $this->testAdd();
+        $this->actionPool->remove($this->key);
     }
 
     public function testUpdate()
     {
+        $this->testAdd();
         $data = ['id' => 'id'];
         $this->items[$this->key]->expects($this->any())->method('setData')->with($data)->willReturnSelf();
-        $this->assertNull($this->actionPool->update($this->key, $data));
+        $this->actionPool->update($this->key, $data);
     }
 }
diff --git a/app/code/Magento/Ui/Test/Unit/Component/Control/ActionTest.php b/app/code/Magento/Ui/Test/Unit/Component/Control/ActionTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..be25a5957f10d22e90fc5f2b91be11910b60b342
--- /dev/null
+++ b/app/code/Magento/Ui/Test/Unit/Component/Control/ActionTest.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\Test\Unit\Component\Control;
+
+use Magento\Ui\Component\Control\Action;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+
+/**
+ * Class ActionTest
+ */
+class ActionTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Action
+     */
+    protected $action;
+
+    /**
+     * @var ObjectManager
+     */
+    protected $objectManager;
+
+    /**
+     * Set up
+     */
+    public function setUp()
+    {
+        $this->objectManager = new ObjectManager($this);
+
+        $this->action = $this->objectManager->getObject('Magento\Ui\Component\Control\Action');
+    }
+
+    /**
+     * Run test getComponentName method
+     *
+     * @return void
+     */
+    public function testGetComponentName()
+    {
+        $this->assertTrue($this->action->getComponentName() === Action::NAME);
+    }
+}
diff --git a/app/code/Magento/Ui/Test/Unit/Component/Control/ButtonTest.php b/app/code/Magento/Ui/Test/Unit/Component/Control/ButtonTest.php
index 998e677f7e9df92ebdf92df4ae708fa8346e80ae..84284dea69d092dc4b6553734067a846412f83b2 100644
--- a/app/code/Magento/Ui/Test/Unit/Component/Control/ButtonTest.php
+++ b/app/code/Magento/Ui/Test/Unit/Component/Control/ButtonTest.php
@@ -59,7 +59,7 @@ class ButtonTest extends \PHPUnit_Framework_TestCase
     public function testGetAttributesHtml()
     {
         $expected = 'type="button" class="action- scalable classValue disabled" '
-            . 'onclick="setLocation(\'url2\');" disabled="disabled" data-attributeKey="attributeValue" ';
+            . 'onclick="location.href = \'url2\';" disabled="disabled" data-attributeKey="attributeValue" ';
         $this->button->setDisabled(true);
         $this->button->setData('url', 'url2');
         $this->button->setData('class', 'classValue');
@@ -98,12 +98,12 @@ class ButtonTest extends \PHPUnit_Framework_TestCase
     {
         return [
             [null, null, '', null],
-            [null, null, 'get_url', 'setLocation(\'get_url\');'],
+            [null, null, 'get_url', 'location.href = \'get_url\';'],
             ['on_click', null, null, 'on_click'],
             ['on_click', 'url', 'get_url', 'on_click'],
             ['on_click', null, '', 'on_click'],
-            [null, 'url', 'get_url', 'setLocation(\'url\');'],
-            [null, 'url', '', 'setLocation(\'url\');'],
+            [null, 'url', 'get_url', 'location.href = \'url\';'],
+            [null, 'url', '', 'location.href = \'url\';'],
         ];
     }
 }
diff --git a/app/code/Magento/Ui/Test/Unit/Component/Control/ContainerTest.php b/app/code/Magento/Ui/Test/Unit/Component/Control/ContainerTest.php
index 72b28b39c7f42637fa77d4d0ffb2b3a194c637bd..9251da5b69dffd7adee6d34dd9fff76c7babe17a 100644
--- a/app/code/Magento/Ui/Test/Unit/Component/Control/ContainerTest.php
+++ b/app/code/Magento/Ui/Test/Unit/Component/Control/ContainerTest.php
@@ -17,7 +17,7 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
         $blockName = $nameInLayout . '-' . $id . '-button';
         $expectedHtml = 'test html';
 
-        $blockButtonMock = $this->getMock(Container::DEFAULT_BUTTON, [], [], '', false);
+        $blockButtonMock = $this->getMock(Container::DEFAULT_CONTROL, [], [], '', false);
         $blockButtonMock->expects($this->once())->method('toHtml')->willReturn($expectedHtml);
 
         $contextMock = $this->getMock('Magento\Framework\View\Element\Template\Context', [], [], '', false);
@@ -32,7 +32,7 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
         $layoutMock = $this->getMock('Magento\Framework\View\Layout', [], [], '', false);
         $layoutMock->expects($this->once())
             ->method('createBlock')
-            ->with(Container::DEFAULT_BUTTON, $blockName)
+            ->with(Container::DEFAULT_CONTROL, $blockName)
             ->willReturn($blockButtonMock);
         $contextMock->expects($this->any())->method('getLayout')->willReturn($layoutMock);
 
diff --git a/app/code/Magento/Ui/Test/Unit/Component/Control/LinkTest.php b/app/code/Magento/Ui/Test/Unit/Component/Control/LinkTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..1615690f8674f3668f502e6b45328c535286fe74
--- /dev/null
+++ b/app/code/Magento/Ui/Test/Unit/Component/Control/LinkTest.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\Test\Unit\Component\Control;
+
+use Magento\Ui\Component\Control\Link;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+
+/**
+ * Class LinkTest
+ */
+class LinkTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Link
+     */
+    protected $link;
+
+    /**
+     * @var ObjectManager
+     */
+    protected $objectManager;
+
+    /**
+     * Set up
+     */
+    public function setUp()
+    {
+        $this->objectManager = new ObjectManager($this);
+
+        $this->link = $this->objectManager->getObject('Magento\Ui\Component\Control\Link');
+    }
+
+    /**
+     * Run test getComponentName method
+     *
+     * @return void
+     */
+    public function testGetComponentName()
+    {
+        $this->assertTrue($this->link->getComponentName() === Link::NAME);
+    }
+}
diff --git a/app/code/Magento/Ui/Test/Unit/Component/FilterPoolTest.php b/app/code/Magento/Ui/Test/Unit/Component/FilterPoolTest.php
deleted file mode 100644
index f12d71763da6ffb834c31e627825ed606ad993c8..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/Test/Unit/Component/FilterPoolTest.php
+++ /dev/null
@@ -1,408 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-namespace Magento\Ui\Test\Unit\Component;
-
-use \Magento\Ui\Component\FilterPool;
-
-use Magento\Framework\View\Element\Template;
-use Magento\Framework\View\Element\Template\Context as TemplateContext;
-use Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface;
-use Magento\Framework\View\Element\UiComponent\ConfigFactory;
-use Magento\Framework\View\Element\UiComponent\Context;
-use Magento\Ui\Component\Filter\FilterPool as FilterPoolProvider;
-use Magento\Ui\ContentType\ContentTypeFactory;
-
-/**
- * Class ViewTest
- */
-class FilterPoolTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * Filter var
-     */
-    const FILTER_VAR = 'filter';
-
-    /**
-     * @var TemplateContext|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $contextMock;
-
-    /**
-     * @var Context|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $renderContextMock;
-
-    /**
-     * @var ContentTypeFactory|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $contentTypeFactoryMock;
-
-    /**
-     * @var ConfigFactory|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $configFactoryMock;
-
-    /**
-     * @var ConfigBuilderInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $configBuilderMock;
-
-    /**
-     * @var \Magento\Ui\DataProvider\Factory|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $dataProviderFactoryMock;
-
-    /**
-     * @var \Magento\Ui\DataProvider\Manager|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $dataProviderManagerMock;
-
-    /**
-     * @var FilterPoolProvider|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $filterPoolProviderMock;
-
-    /**
-     * @var FilterPool
-     */
-    protected $filterPool;
-
-    /**
-     * Set up
-     *
-     * @return void
-     */
-    protected function setUp()
-    {
-        $this->contextMock = $this->getMock(
-            'Magento\Framework\View\Element\Template\Context',
-            [],
-            [],
-            '',
-            false
-        );
-        $this->renderContextMock = $this->getMock(
-            'Magento\Framework\View\Element\UiComponent\Context',
-            ['getNamespace', 'getStorage', 'getRequestParam'],
-            [],
-            '',
-            false
-        );
-        $this->contentTypeFactoryMock = $this->getMock(
-            'Magento\Ui\ContentType\ContentTypeFactory',
-            [],
-            [],
-            '',
-            false
-        );
-        $this->configFactoryMock = $this->getMock(
-            'Magento\Framework\View\Element\UiComponent\ConfigFactory',
-            ['create'],
-            [],
-            '',
-            false
-        );
-        $this->configBuilderMock = $this->getMockForAbstractClass(
-            'Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface',
-            [],
-            '',
-            false
-        );
-        $this->dataProviderFactoryMock = $this->getMock(
-            'Magento\Ui\DataProvider\Factory',
-            [],
-            [],
-            '',
-            false
-        );
-        $this->dataProviderManagerMock = $this->getMock(
-            'Magento\Ui\DataProvider\Manager',
-            [],
-            [],
-            '',
-            false
-        );
-        $this->filterPoolProviderMock = $this->getMock(
-            'Magento\Ui\Component\Filter\FilterPool',
-            ['getFilter'],
-            [],
-            '',
-            false
-        );
-
-        $this->filterPool = new FilterPool(
-            $this->contextMock,
-            $this->renderContextMock,
-            $this->contentTypeFactoryMock,
-            $this->configFactoryMock,
-            $this->configBuilderMock,
-            $this->dataProviderFactoryMock,
-            $this->dataProviderManagerMock,
-            $this->filterPoolProviderMock
-        );
-    }
-
-    /**
-     * Run test prepare method
-     *
-     * @return void
-     * @SuppressWarnings(PHPMD.UnusedLocalVariable)
-     */
-    public function testPrepare()
-    {
-        /**
-         * @var \Magento\Framework\View\Element\UiComponent\ConfigInterface
-         * |\PHPUnit_Framework_MockObject_MockObject $configurationMock
-         */
-        $configurationMock = $this->getMockForAbstractClass(
-            'Magento\Framework\View\Element\UiComponent\ConfigInterface',
-            ['getParentName'],
-            '',
-            false
-        );
-        /**
-         * @var \Magento\Framework\View\Element\UiComponent\ConfigStorageInterface
-         * |\PHPUnit_Framework_MockObject_MockObject $configStorageMock
-         */
-        $configStorageMock = $this->getMockForAbstractClass(
-            'Magento\Framework\View\Element\UiComponent\ConfigStorageInterface',
-            ['addComponentsData', 'getDataCollection', 'getMeta'],
-            '',
-            false
-        );
-        /**
-         * @var \Magento\Framework\Data\Collection|\PHPUnit_Framework_MockObject_MockObject $dataCollectionMock
-         */
-        $dataCollectionMock = $this->getMock(
-            'Magento\Framework\Data\Collection',
-            ['setOrder'],
-            [],
-            '',
-            false
-        );
-
-        $this->renderContextMock->expects($this->at(0))
-            ->method('getNamespace')
-            ->will($this->returnValue('namespace'));
-        $this->renderContextMock->expects($this->at(1))
-            ->method('getNamespace')
-            ->will($this->returnValue('namespace'));
-        $this->configFactoryMock->expects($this->any())
-            ->method('create')
-            ->will($this->returnValue($configurationMock));
-        $this->renderContextMock->expects($this->any())
-            ->method('getStorage')
-            ->will($this->returnValue($configStorageMock));
-        $configStorageMock->expects($this->at(0))
-            ->method('getDataCollection')
-            ->will($this->returnValue($dataCollectionMock));
-        $configStorageMock->expects($this->at(1))
-            ->method('getDataCollection')
-            ->will($this->returnValue($dataCollectionMock));
-
-        $metaData = [
-            'field-1' => 'value-1',
-            'field-2' => 'value-2',
-            'field-3' => 'value-3',
-            'field-4' => 'value-4',
-        ];
-        $meta = [
-            'fields' => $metaData,
-        ];
-        $filters = $metaData;
-
-        $configStorageMock->expects($this->any())
-            ->method('getMeta')
-            ->will($this->returnValue($meta));
-        $this->renderContextMock->expects($this->once())
-            ->method('getRequestParam')
-            ->with(static::FILTER_VAR);
-
-        $filterMock = $this->getMockForAbstractClass(
-            'Magento\Ui\Component\Filter\FilterInterface',
-            ['getCondition'],
-            '',
-            false
-        );
-
-        $this->filterPoolProviderMock->expects($this->any())
-            ->method('getFilter')
-            ->will($this->returnValue($filterMock));
-        $filterMock->expects($this->any())
-            ->method('getCondition')
-            ->will($this->returnValue(true));
-
-        $dataCollectionMock->expects($this->any())
-            ->method('addFieldToFilter');
-
-        $this->assertNull($this->filterPool->prepare());
-    }
-
-    /**
-     * Run test getFields method
-     *
-     * @return void
-     */
-    public function _testGetFields()
-    {
-        /** @var \Magento\Ui\Component\FilterPool|\PHPUnit_Framework_MockObject_MockObject $filterPool */
-        $filterPool = $this->getMock(
-            'Magento\Ui\Component\FilterPool',
-            ['getParentName'],
-            [
-                $this->contextMock,
-                $this->renderContextMock,
-                $this->contentTypeFactoryMock,
-                $this->configFactoryMock,
-                $this->configBuilderMock,
-                $this->dataProviderFactoryMock,
-                $this->dataProviderManagerMock,
-                $this->filterPoolProviderMock
-            ],
-            '',
-            false
-        );
-        $filterPool->expects($this->any())
-            ->method('getParentName')
-            ->willReturn('parent');
-
-        $result = [
-            'field-1' => ['filterable' => 1],
-            'field-4' => ['filterable' => 1],
-        ];
-        $meta = [
-            'fields' => [
-                'field-1' => ['filterable' => true],
-                'field-2' => ['filterable' => false],
-                'field-3' => ['filterable' => false],
-                'field-4' => ['filterable' => true],
-            ],
-        ];
-        /**
-         * @var \Magento\Framework\View\Element\UiComponent\ConfigInterface
-         * |\PHPUnit_Framework_MockObject_MockObject $configurationMock
-         */
-        $configMock = $this->getMockForAbstractClass(
-            'Magento\Framework\View\Element\UiComponent\ConfigInterface',
-            [],
-            '',
-            false
-        );
-        /**
-         * @var \Magento\Framework\View\Element\UiComponent\ConfigStorageInterface
-         * |\PHPUnit_Framework_MockObject_MockObject $configStorageMock
-         */
-        $configStorageMock = $this->getMockForAbstractClass(
-            'Magento\Framework\View\Element\UiComponent\ConfigStorageInterface',
-            ['addComponentsData', 'getDataCollection', 'getMeta'],
-            '',
-            false
-        );
-
-        $this->filterPool->setConfig($configMock);
-
-        $this->renderContextMock->expects($this->any())
-            ->method('getStorage')
-            ->will($this->returnValue($configStorageMock));
-        $configStorageMock->expects($this->any())
-            ->method('getMeta')
-            ->will($this->returnValue($meta));
-
-        $this->assertEquals($result, $filterPool->getFields());
-    }
-
-    /**
-     * Run test getActiveFilters method
-     *
-     * @return void
-     */
-    public function _testGetActiveFilters()
-    {
-        $result = [
-            'field-1' => [
-                'title' => 'title-1',
-                'current_display_value' => 'value-1',
-            ],
-            'field-2' => [
-                'title' => 'title-2',
-                'current_display_value' => 'value-2',
-            ],
-            'field-3' => [
-                'title' => 'title-3',
-                'current_display_value' => 'value-3',
-            ],
-            'field-4' => [
-                'title' => 'title-4',
-                'current_display_value' => 'value-4',
-            ],
-        ];
-        $meta = [
-            'fields' => [
-                'field-1' => [
-                    'filter_type' => true,
-                    'title' => 'title-1',
-                ],
-                'field-2' => [
-                    'filter_type' => true,
-                    'title' => 'title-2',
-                ],
-                'field-3' => [
-                    'filter_type' => true,
-                    'title' => 'title-3',
-                ],
-                'field-4' => [
-                    'filter_type' => true,
-                    'title' => 'title-4',
-                ],
-            ],
-        ];
-        $filters = [
-            'field-1' => 'value-1',
-            'field-2' => 'value-2',
-            'field-3' => 'value-3',
-            'field-4' => 'value-4',
-        ];
-
-        /**
-         * @var \Magento\Framework\View\Element\UiComponent\ConfigInterface
-         * |\PHPUnit_Framework_MockObject_MockObject $configurationMock
-         */
-        $configMock = $this->getMockForAbstractClass(
-            'Magento\Framework\View\Element\UiComponent\ConfigInterface',
-            [],
-            '',
-            false
-        );
-        /**
-         * @var \Magento\Framework\View\Element\UiComponent\ConfigStorageInterface
-         * |\PHPUnit_Framework_MockObject_MockObject $configStorageMock
-         */
-        $configStorageMock = $this->getMockForAbstractClass(
-            'Magento\Framework\View\Element\UiComponent\ConfigStorageInterface',
-            ['addComponentsData', 'getDataCollection', 'getMeta'],
-            '',
-            false
-        );
-
-        $this->filterPool->setConfig($configMock);
-
-        $this->renderContextMock->expects($this->any())
-            ->method('getStorage')
-            ->will($this->returnValue($configStorageMock));
-        $configStorageMock->expects($this->any())
-            ->method('getMeta')
-            ->will($this->returnValue($meta));
-        $this->dataHelperMock->expects($this->once())
-            ->method('prepareFilterString')
-            ->will($this->returnValue($filters));
-        $this->renderContextMock->expects($this->once())
-            ->method('getRequestParam')
-            ->with(static::FILTER_VAR);
-
-        $this->assertEquals($result, $this->filterPool->getActiveFilters());
-    }
-}
diff --git a/app/code/Magento/Ui/Test/Unit/Component/FilterTest.php b/app/code/Magento/Ui/Test/Unit/Component/FilterTest.php
deleted file mode 100644
index 656070849515a734268911a185eb1f9d18aae239..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/Test/Unit/Component/FilterTest.php
+++ /dev/null
@@ -1,193 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\Test\Unit\Component;
-
-use Magento\Framework\View\Element\Template;
-use Magento\Framework\View\Element\Template\Context as TemplateContext;
-use Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface;
-use Magento\Framework\View\Element\UiComponent\ConfigFactory;
-use Magento\Framework\View\Element\UiComponent\Context;
-use Magento\Ui\Component\Filter\FilterPool as FilterPoolProvider;
-use Magento\Ui\ContentType\ContentTypeFactory;
-
-/**
- * Class FilterTest
- */
-class FilterTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var TemplateContext||\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $contextMock;
-
-    /**
-     * @var Context|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $renderContextMock;
-
-    /**
-     * @var ContentTypeFactory|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $contentTypeFactoryMock;
-
-    /**
-     * @var ConfigFactory|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $configFactoryMock;
-
-    /**
-     * @var ConfigBuilderInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $configBuilderMock;
-
-    /**
-     * @var \Magento\Ui\DataProvider\Factory|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $dataProviderFactoryMock;
-
-    /**
-     * @var \Magento\Ui\DataProvider\Manager|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $dataProviderManagerMock;
-
-    /**
-     * @var \Magento\Backend\Helper\Data|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $dataHelperMock;
-
-    /**
-     * @var FilterPoolProvider|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $filterPoolMock;
-
-    /**
-     * @var \Magento\Ui\Component\FilterPool
-     */
-    protected $filter;
-
-    /**
-     * Set up
-     *
-     * @return void
-     */
-    protected function setUp()
-    {
-        $this->contextMock = $this->getMock(
-            'Magento\Framework\View\Element\Template\Context',
-            [],
-            [],
-            '',
-            false
-        );
-        $this->renderContextMock = $this->getMock(
-            'Magento\Framework\View\Element\UiComponent\Context',
-            ['getNamespace', 'getStorage', 'getRequestParam'],
-            [],
-            '',
-            false
-        );
-        $this->contentTypeFactoryMock = $this->getMock(
-            'Magento\Ui\ContentType\ContentTypeFactory',
-            [],
-            [],
-            '',
-            false
-        );
-        $this->configFactoryMock = $this->getMock(
-            'Magento\Framework\View\Element\UiComponent\ConfigFactory',
-            ['create'],
-            [],
-            '',
-            false
-        );
-        $this->configBuilderMock = $this->getMockForAbstractClass(
-            'Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface',
-            [],
-            '',
-            false
-        );
-        $this->dataProviderFactoryMock = $this->getMock(
-            'Magento\Ui\DataProvider\Factory',
-            [],
-            [],
-            '',
-            false
-        );
-        $this->dataProviderManagerMock = $this->getMock(
-            'Magento\Ui\DataProvider\Manager',
-            [],
-            [],
-            '',
-            false
-        );
-        $this->filterPoolMock = $this->getMock(
-            'Magento\Ui\Component\Filter\FilterPool',
-            ['getFilter'],
-            [],
-            '',
-            false
-        );
-
-        $this->filter = new \Magento\Ui\Component\FilterPool(
-            $this->contextMock,
-            $this->renderContextMock,
-            $this->contentTypeFactoryMock,
-            $this->configFactoryMock,
-            $this->configBuilderMock,
-            $this->dataProviderFactoryMock,
-            $this->dataProviderManagerMock,
-            $this->filterPoolMock
-        );
-    }
-
-    /**
-     * Run test prepare method
-     *
-     * @return void
-     */
-    public function testPrepare()
-    {
-        /**
-         * @var \Magento\Framework\View\Element\UiComponent\ConfigInterface
-         * |\PHPUnit_Framework_MockObject_MockObject $configurationMock
-         */
-        $configurationMock = $this->getMockForAbstractClass(
-            'Magento\Framework\View\Element\UiComponent\ConfigInterface',
-            [],
-            '',
-            false
-        );
-        /**
-         * @var \Magento\Framework\View\Element\UiComponent\ConfigStorageInterface
-         * |\PHPUnit_Framework_MockObject_MockObject $configStorageMock
-         */
-        $configStorageMock = $this->getMockForAbstractClass(
-            'Magento\Framework\View\Element\UiComponent\ConfigStorageInterface',
-            ['addComponentsData', 'getDataCollection', 'getMeta'],
-            '',
-            false
-        );
-
-        $this->renderContextMock->expects($this->at(0))
-            ->method('getNamespace')
-            ->will($this->returnValue('namespace'));
-        $this->renderContextMock->expects($this->at(1))
-            ->method('getNamespace')
-            ->will($this->returnValue('namespace'));
-        $this->configFactoryMock->expects($this->any())
-            ->method('create')
-            ->will($this->returnValue($configurationMock));
-
-        $this->renderContextMock->expects($this->any())
-            ->method('getStorage')
-            ->will($this->returnValue($configStorageMock));
-        $configStorageMock->expects($this->once())
-            ->method('addComponentsData')
-            ->with($configurationMock);
-
-        $this->assertNull($this->filter->prepare());
-    }
-}
diff --git a/app/code/Magento/Ui/Test/Unit/Component/Listing/Columns/ColumnTest.php b/app/code/Magento/Ui/Test/Unit/Component/Listing/Columns/ColumnTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..98005246955763c90120fd66e06ff8f9eabb0a1a
--- /dev/null
+++ b/app/code/Magento/Ui/Test/Unit/Component/Listing/Columns/ColumnTest.php
@@ -0,0 +1,164 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\Test\Unit\Component\Listing\Columns;
+
+use Magento\Ui\Component\Listing\Columns\Column;
+use Magento\Framework\View\Element\UiComponentFactory;
+use Magento\Framework\View\Element\UiComponentInterface;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+use Magento\Framework\View\Element\UiComponent\ContextInterface;
+use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface;
+
+/**
+ * Class ColumnTest
+ */
+class ColumnTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var ContextInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $contextMock;
+
+    /**
+     * @var ObjectManager
+     */
+    protected $objectManager;
+
+    /**
+     * Set up
+     */
+    public function setUp()
+    {
+        $this->objectManager = new ObjectManager($this);
+
+        $this->contextMock = $this->getMockForAbstractClass(
+            'Magento\Framework\View\Element\UiComponent\ContextInterface',
+            [],
+            '',
+            false,
+            true,
+            true,
+            []
+        );
+    }
+
+    /**
+     * Run test getComponentName method
+     *
+     * @return void
+     */
+    public function testGetComponentName()
+    {
+        $column = $this->objectManager->getObject(
+            'Magento\Ui\Component\Listing\Columns\Column',
+            [
+                'context' => $this->contextMock,
+                'data' => [
+                    'js_config' => [
+                        'extends' => 'test_config_extends'
+                    ],
+                    'config' => [
+                        'dataType' => 'testType'
+                    ]
+                ]
+            ]
+        );
+
+        $this->assertEquals($column->getComponentName(), Column::NAME . '.testType');
+    }
+
+    /**
+     * Run test prepareItems method
+     *
+     * @return void
+     */
+    public function testPrepareItems()
+    {
+        $testItems = ['item1','item2', 'item3'];
+        $column = $this->objectManager->getObject('Magento\Ui\Component\Listing\Columns\Column');
+
+        $this->assertEquals($testItems, $column->prepareItems($testItems));
+    }
+
+    /**
+     * Run test prepare method
+     *
+     * @return void
+     */
+    public function testPrepare()
+    {
+        $data = [
+            'name' => 'test_name',
+            'js_config' => ['extends' => 'test_config_extends'],
+            'config' => ['dataType' => 'test_type', 'sortable' => true]
+        ];
+
+        /** @var UiComponentFactory|\PHPUnit_Framework_MockObject_MockObject $uiComponentFactoryMock */
+        $uiComponentFactoryMock = $this->getMock(
+            'Magento\Framework\View\Element\UiComponentFactory',
+            [],
+            [],
+            '',
+            false
+        );
+
+        /** @var UiComponentInterface|\PHPUnit_Framework_MockObject_MockObject $wrappedComponentMock */
+        $wrappedComponentMock = $this->getMockForAbstractClass(
+            'Magento\Framework\View\Element\UiComponentInterface',
+            [],
+            '',
+            false
+        );
+        /** @var DataProviderInterface|\PHPUnit_Framework_MockObject_MockObject $dataProviderMock */
+        $dataProviderMock = $this->getMockForAbstractClass(
+            'Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface',
+            [],
+            '',
+            false
+        );
+
+        $this->contextMock->expects($this->atLeastOnce())
+            ->method('getNamespace')
+            ->willReturn('test_namespace');
+        $this->contextMock->expects($this->atLeastOnce())
+            ->method('getDataProvider')
+            ->willReturn($dataProviderMock);
+        $this->contextMock->expects($this->atLeastOnce())
+            ->method('getRequestParam')
+            ->with('sorting')
+            ->willReturn(['field' => 'test_name', 'direction' => 'asc']);
+        $this->contextMock->expects($this->atLeastOnce())
+            ->method('addComponentDefinition')
+            ->with(Column::NAME . '.test_type', ['extends' => 'test_config_extends']);
+
+        $dataProviderMock->expects($this->once())
+            ->method('addOrder')
+            ->with('test_name', 'ASC');
+
+        $uiComponentFactoryMock->expects($this->once())
+            ->method('create')
+            ->with('test_name', 'test_type', array_merge(['context' => $this->contextMock], $data))
+            ->willReturn($wrappedComponentMock);
+
+        $wrappedComponentMock->expects($this->once())
+            ->method('getContext')
+            ->willReturn($this->contextMock);
+        $wrappedComponentMock->expects($this->once())
+            ->method('prepare');
+
+        /** @var Column $column */
+        $column = $this->objectManager->getObject(
+            'Magento\Ui\Component\Listing\Columns\Column',
+            [
+                'context' => $this->contextMock,
+                'uiComponentFactory' => $uiComponentFactoryMock,
+                'data' => $data
+            ]
+        );
+
+        $column->prepare();
+    }
+}
diff --git a/app/code/Magento/Ui/Test/Unit/Component/Listing/ColumnsTest.php b/app/code/Magento/Ui/Test/Unit/Component/Listing/ColumnsTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..f6769ba8e306e3f761cf54f135779d0c2815d502
--- /dev/null
+++ b/app/code/Magento/Ui/Test/Unit/Component/Listing/ColumnsTest.php
@@ -0,0 +1,136 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\Test\Unit\Component\Listing;
+
+use Magento\Ui\Component\Listing\Columns;
+use Magento\Ui\Component\Listing\Columns\Column;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+use Magento\Framework\View\Element\UiComponent\ContextInterface;
+use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface;
+
+/**
+ * Class ColumnsTest
+ */
+class ColumnsTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var ContextInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $contextMock;
+
+    /**
+     * @var ObjectManager
+     */
+    protected $objectManager;
+
+    /**
+     * Set up
+     */
+    public function setUp()
+    {
+        $this->objectManager = new ObjectManager($this);
+
+        $this->contextMock = $this->getMockForAbstractClass(
+            'Magento\Framework\View\Element\UiComponent\ContextInterface',
+            [],
+            '',
+            false,
+            true,
+            true,
+            []
+        );
+    }
+
+    /**
+     * Run test getComponentName method
+     *
+     * @return void
+     */
+    public function testGetComponentName()
+    {
+        $columns = $this->objectManager->getObject(
+            'Magento\Ui\Component\Listing\Columns',
+            [
+                'context' => $this->contextMock,
+                'data' => [
+                    'js_config' => [
+                        'extends' => 'test_config_extends'
+                    ],
+                    'config' => [
+                        'dataType' => 'testType'
+                    ]
+                ]
+            ]
+        );
+
+        $this->assertEquals($columns->getComponentName(), Columns::NAME);
+    }
+
+    /**
+     * Run test prepare method
+     *
+     * @return void
+     */
+    public function testPrepare()
+    {
+        /** @var Column|\PHPUnit_Framework_MockObject_MockObject $componentMock */
+        $columnMock = $this->getMock(
+            'Magento\Ui\Component\Listing\Columns\Column',
+            [],
+            [],
+            '',
+            false
+        );
+        /** @var DataProviderInterface|\PHPUnit_Framework_MockObject_MockObject $dataProviderMock */
+        $dataProviderMock = $this->getMockForAbstractClass(
+            'Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface',
+            [],
+            '',
+            false
+        );
+
+        $data = [
+            'name' => 'test_name',
+            'js_config' => ['extends' => 'test_config_extends'],
+            'config' => ['dataType' => 'test_type', 'sortable' => true]
+        ];
+
+        $this->contextMock->expects($this->once())
+            ->method('getDataProvider')
+            ->willReturn($dataProviderMock);
+        $this->contextMock->expects($this->once())
+            ->method('addComponentDefinition')
+            ->with('columns', ['extends' => 'test_config_extends']);
+
+        $dataProviderMock->expects($this->once())
+            ->method('getFieldMetaInfo')
+            ->with('test_name', 'test_column_name')
+            ->willReturn(['test_meta' => 'test_meta_value']);
+
+        $columnMock->expects($this->once())
+            ->method('getName')
+            ->willReturn('test_column_name');
+        $columnMock->expects($this->once())
+            ->method('getData')
+            ->with('config')
+            ->willReturn(['test_config_data' => 'test_config_value']);
+        $columnMock->expects($this->once())
+            ->method('setData')
+            ->with('config', ['test_config_data' => 'test_config_value', 'test_meta' => 'test_meta_value']);
+
+        /** @var Columns $columns */
+        $columns = $this->objectManager->getObject(
+            'Magento\Ui\Component\Listing\Columns',
+            [
+                'components' => [$columnMock],
+                'context' => $this->contextMock,
+                'data' => $data
+            ]
+        );
+
+        $columns->prepare();
+    }
+}
diff --git a/app/code/Magento/Ui/Test/Unit/Component/ListingTest.php b/app/code/Magento/Ui/Test/Unit/Component/ListingTest.php
index e5f795227c825879d26bb72cd441cdb7c32eaa22..dcc49cf83f36d8c2a6734adf26bb8d5726357137 100644
--- a/app/code/Magento/Ui/Test/Unit/Component/ListingTest.php
+++ b/app/code/Magento/Ui/Test/Unit/Component/ListingTest.php
@@ -3,200 +3,218 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-
 namespace Magento\Ui\Test\Unit\Component;
 
-use \Magento\Ui\Component\Listing;
-
-use Magento\Framework\View\Element\Template\Context;
-use Magento\Ui\Component\Control\ActionPool;
-use Magento\Ui\Component\Listing\OptionsFactory;
-use Magento\Ui\Component\Listing\RowPool;
-use Magento\Ui\Context\ConfigurationFactory;
+use Magento\Ui\Component\Listing;
+use Magento\Ui\Component\Listing\Columns;
+use Magento\Ui\Component\Listing\Columns\Column;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+use Magento\Framework\View\Element\UiComponent\ContextInterface;
+use Magento\Framework\View\Element\UiComponent\DataSourceInterface;
+use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface;
 
 /**
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ * Class ListingTest
  */
 class ListingTest extends \PHPUnit_Framework_TestCase
 {
     /**
-     * @var ActionPool|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $actionPool;
-
-    /**
-     * @var OptionsFactory|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $optionsFactory;
-
-    /**
-     * @var RowPool|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $rowPool;
-
-    /**
-     * @var Context
-     */
-    protected $templateContext;
-
-    /**
-     * @var \Magento\Framework\Stdlib\DateTime\Timezone|\PHPUnit_Framework_MockObject_MockObject
+     * @var ContextInterface|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $localeDate;
+    protected $contextMock;
 
     /**
-     * @var \Magento\Framework\UrlInterface|\PHPUnit_Framework_MockObject_MockObject
+     * @var ObjectManager
      */
-    protected $urlBuilder;
+    protected $objectManager;
 
     /**
-     * @var \Magento\Framework\View\Element\UiComponent\ConfigFactory|\PHPUnit_Framework_MockObject_MockObject
+     * Set up
      */
-    protected $configurationFactory;
+    public function setUp()
+    {
+        $this->objectManager = new ObjectManager($this);
 
-    /**
-     * @var \Magento\Framework\View\Element\UiComponent\Context |\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $renderContext;
+        $this->contextMock = $this->getMockForAbstractClass(
+            'Magento\Framework\View\Element\UiComponent\ContextInterface',
+            [],
+            '',
+            false,
+            true,
+            true,
+            []
+        );
+    }
 
     /**
-     * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager
+     * Run test getComponentName method
+     *
+     * @return void
      */
-    protected $objectManagerHelper;
+    public function testGetComponentName()
+    {
+        /** @var Listing $listing */
+        $listing = $this->objectManager->getObject(
+            'Magento\Ui\Component\Listing',
+            [
+                'context' => $this->contextMock,
+                'data' => []
+            ]
+        );
 
-    /**
-     * @var \Magento\Ui\Context\Configuration |\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $configuration;
+        $this->assertTrue($listing->getComponentName() === Listing::NAME);
+    }
 
     /**
-     * @var \Magento\Ui\Context\ConfigurationStorage |\PHPUnit_Framework_MockObject_MockObject
+     * Run test prepare method
+     *
+     * @return void
      */
-    protected $configStorage;
+    public function testPrepare()
+    {
+        $buttons = [
+            'button1' => 'button1',
+            'button2' => 'button2'
+        ];
+        /** @var Listing $listing */
+        $listing = $this->objectManager->getObject(
+            'Magento\Ui\Component\Listing',
+            [
+                'context' => $this->contextMock,
+                'data' => [
+                    'js_config' => [
+                        'extends' => 'test_config_extends',
+                        'testData' => 'testValue',
+                    ],
+                    'buttons' => $buttons
+                ]
+            ]
+        );
 
-    /**
-     * @var \Magento\Ui\ContentType\ContentTypeFactory |\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $contentTypeFactory;
+        $this->contextMock->expects($this->once())
+            ->method('getNamespace')
+            ->willReturn(Listing::NAME);
+        $this->contextMock->expects($this->once())
+            ->method('addComponentDefinition')
+            ->with($listing->getComponentName(), ['testData' => 'testValue']);
+        $this->contextMock->expects($this->once())
+            ->method('addButtons')
+            ->with($buttons, $listing);
+
+        $listing->prepare();
+    }
 
     /**
-     * @var Listing
+     * Run test getDataSourceData method
+     *
+     * @return void
+     *
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
      */
-    protected $listingView;
-
-    public function setUp()
+    public function testGetDataSourceData()
     {
-        $this->objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
-        $this->actionPool = $this->getMock('\Magento\Ui\Component\Control\ActionPool', [], [], '', false);
-        $this->optionsFactory = $this->getMock('\Magento\Ui\Component\Listing\OptionsFactory', [], [], '', false);
-        $this->rowPool = $this->getMock('\Magento\Ui\Component\Listing\RowPool', [], [], '', false);
-        $this->renderContext = $this->getMock('\Magento\Framework\View\Element\UiComponent\Context', [], [], '', false);
-        $this->templateContext = $this->getMock(
-            'Magento\Framework\View\Element\Template\Context',
-            [],
+        $result = [
+            [
+                'type' => 'test_component_name',
+                'name' => 'test_name',
+                'dataScope' => 'test_namespace',
+                'config' => [
+                    'data' => [
+                        'items' => ['data']
+                    ],
+                    'totalCount' => 20,
+                    'testConfig' => 'testConfigValue',
+                    'params' => [
+                        'namespace' => 'test_namespace'
+                    ]
+                ]
+            ]
+        ];
+
+        /** @var DataSourceInterface|\PHPUnit_Framework_MockObject_MockObject $dataSourceMock */
+        $dataSourceMock = $this->getMockForAbstractClass(
+            'Magento\Framework\View\Element\UiComponent\DataSourceInterface',
             [],
             '',
             false
         );
-        $this->configStorage = $this->getMock(
-            'Magento\Ui\Context\ConfigurationStorage',
-            [],
+        /** @var DataProviderInterface|\PHPUnit_Framework_MockObject_MockObject $dataProviderMock */
+        $dataProviderMock = $this->getMockForAbstractClass(
+            'Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface',
             [],
             '',
             false
         );
-        $this->localeDate = $this->getMock('Magento\Framework\Stdlib\DateTime\Timezone', [], [], '', false);
-        $this->urlBuilder = $this->getMock('Magento\Backend\Model\Url', ['getUrl'], [], '', false);
-        $this->templateContext->expects($this->once())
-            ->method('getLocaleDate')
-            ->willReturn($this->localeDate);
-        $this->templateContext->expects($this->once())
-            ->method('getUrlBuilder')
-            ->willReturn($this->urlBuilder);
-        $this->contentTypeFactory = $this->getMock('Magento\Ui\ContentType\ContentTypeFactory', [], [], '', false);
-        $this->configurationFactory = $this->getMock(
-            'Magento\Framework\View\Element\UiComponent\ConfigFactory',
+        /** @var Columns|\PHPUnit_Framework_MockObject_MockObject $columnsMock */
+        $columnsMock = $this->getMock(
+            'Magento\Ui\Component\Listing\Columns',
             [],
             [],
             '',
             false
         );
-        $configurationBuilder = $this->getMock(
-            'Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface',
-            ['toJson'],
+        /** @var Column|\PHPUnit_Framework_MockObject_MockObject $columnMock */
+        $columnMock = $this->getMock(
+            'Magento\Ui\Component\Listing\Columns\Column',
+            [],
             [],
             '',
             false
         );
-        $this->configuration = $this->getMock('Magento\Ui\Context\Configuration', [], [], '', false);
-        $this->renderContext->expects($this->any())
-            ->method('getStorage')
-            ->willReturn($this->configStorage);
 
-        $this->listingView = $this->objectManagerHelper->getObject(
-            '\Magento\Ui\Component\Listing',
+        /** @var Listing $listing */
+        $listing = $this->objectManager->getObject(
+            'Magento\Ui\Component\Listing',
             [
-                'context' => $this->templateContext,
-                'renderContext' => $this->renderContext,
-                'contentTypeFactory' => $this->contentTypeFactory,
-                'configFactory' => $this->configurationFactory,
-                'configBuilder' => $configurationBuilder,
-                'optionsFactory' => $this->optionsFactory,
-                'actionPool' => $this->actionPool,
-                'dataProviderRowPool' => $this->rowPool
+                'context' => $this->contextMock,
+                'components' => [$dataSourceMock, $columnsMock],
+                'data' => [
+                    'js_config' => [
+                        'extends' => 'test_config_extends',
+                        'testData' => 'testValue',
+                    ]
+                ]
             ]
         );
-    }
-
-    protected function prepareMeta()
-    {
-        $meta = ['fields' => [['data_type' => 'date', 'options_provider' => 'provider', 'options' => ['option1']]]];
-        $this->listingView->setData('meta', $meta);
-        $this->localeDate->expects($this->any())
-            ->method('getDateTimeFormat')
-            ->with(\IntlDateFormatter::MEDIUM)
-            ->willReturn('format_type');
-        $options = $this->getMock('Magento\Cms\Ui\DataProvider\Page\Options\PageLayout', [], [], '', false);
-        $this->optionsFactory->expects($this->any())
-            ->method('create')
-            ->with('provider')
-            ->willReturn($options);
-        $options->expects($this->any())
-            ->method('getOptions')
-            ->with(['option1'])
-            ->willReturn(['option1']);
-    }
-
-    public function testPrepare()
-    {
-        $this->prepareMeta();
-        $config = [
-            'page_actions' => [
-                'add' => [
-                    'name' => 'add',
-                    'label' => __('Add New'),
-                    'class' => 'primary',
-                    'url' => 'http://some.url',
-                ],
-            ],
-        ];
 
-        $this->urlBuilder->expects($this->at(0))
-            ->method('getUrl')
-            ->with('*/*/new')
-            ->willReturn('http://mage.local/category/new');
-        $dataCollection = $this->getMock('Magento\Framework\Data\CollectionDataSourceInterface', [], [], '', false);
-        $this->listingView->setData('configuration', $config);
-        $this->listingView->setData('name', 'someName');
-        $this->listingView->setData('dataSource', $dataCollection);
-        $this->actionPool->expects($this->once())
-            ->method('add')
-            ->with('add', $config['page_actions']['add'], $this->listingView);
-
-        $this->configurationFactory->expects($this->once())
-            ->method('create')
-            ->willReturn($this->configuration);
-
-        $this->assertNull($this->listingView->prepare());
+        $columnsMock->expects($this->once())
+            ->method('getChildComponents')
+            ->willReturn([$columnMock]);
+
+        $dataSourceMock->expects($this->any())
+            ->method('getDataProvider')
+            ->willReturn($dataProviderMock);
+        $dataProviderMock->expects($this->once())
+            ->method('getData')
+            ->willReturn(['items' => ['data']]);
+
+        $columnMock->expects($this->once())
+            ->method('prepareItems')
+            ->with(['data']);
+
+        $dataSourceMock->expects($this->once())
+            ->method('getComponentName')
+            ->willReturn('test_component_name');
+        $dataSourceMock->expects($this->once())
+            ->method('getName')
+            ->willReturn('test_name');
+        $dataSourceMock->expects($this->once())
+            ->method('getContext')
+            ->willReturn($this->contextMock);
+
+        $this->contextMock->expects($this->any())
+            ->method('getNamespace')
+            ->willReturn('test_namespace');
+
+        $dataProviderMock->expects($this->once())
+            ->method('count')
+            ->willReturn(20);
+
+        $dataSourceMock->expects($this->once())
+            ->method('getData')
+            ->with('config')
+            ->willReturn(['testConfig' => 'testConfigValue']);
+
+        $this->assertEquals($listing->getDataSourceData(), $result);
     }
 }
diff --git a/app/code/Magento/Ui/Test/Unit/Component/MassAction/Columns/ColumnTest.php b/app/code/Magento/Ui/Test/Unit/Component/MassAction/Columns/ColumnTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..43b9271d4e013ab291e2e0b0346298456ef6be12
--- /dev/null
+++ b/app/code/Magento/Ui/Test/Unit/Component/MassAction/Columns/ColumnTest.php
@@ -0,0 +1,126 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\Test\Unit\Component\MassAction\Columns;
+
+use Magento\Ui\Component\MassAction\Columns\Column;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+use Magento\Framework\View\Element\UiComponent\ContextInterface;
+
+/**
+ * Class ColumnTest
+ */
+class ColumnTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var ContextInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $contextMock;
+
+    /**
+     * @var Column
+     */
+    protected $column;
+
+    /**
+     * @var ObjectManager
+     */
+    protected $objectManager;
+
+    /**
+     * Set up
+     */
+    public function setUp()
+    {
+        $this->objectManager = new ObjectManager($this);
+
+        $this->contextMock = $this->getMockForAbstractClass(
+            'Magento\Framework\View\Element\UiComponent\ContextInterface',
+            [],
+            '',
+            false,
+            true,
+            true,
+            []
+        );
+
+        $this->column = $this->objectManager->getObject(
+            'Magento\Ui\Component\MassAction\Columns\Column',
+            [
+                'context' => $this->contextMock,
+                'data' => [
+                    'js_config' => [
+                        'extends' => 'test_config_extends'
+                    ]
+                ]
+            ]
+        );
+    }
+
+    /**
+     * Run test getComponentName method
+     *
+     * @return void
+     */
+    public function testGetComponentName()
+    {
+        $this->assertTrue($this->column->getComponentName() === Column::NAME);
+    }
+
+    /**
+     * Run test prepareItems method
+     *
+     * @return void
+     */
+    public function testPrepareItems()
+    {
+        $testItems = ['item1','item2', 'item3'];
+
+        $this->assertEquals($testItems, $this->column->prepareItems($testItems));
+    }
+
+    /**
+     * Run test prepare method
+     *
+     * @return void
+     */
+    public function testPrepare()
+    {
+        $this->column = $this->objectManager->getObject(
+            'Magento\Ui\Component\MassAction\Columns\Column',
+            [
+                'context' => $this->contextMock,
+                'data' => [
+                    'js_config' => []
+                ]
+            ]
+        );
+
+        $this->contextMock->expects($this->once())
+            ->method('getNamespace')
+            ->willReturn('test_namespace');
+        $this->contextMock->expects($this->once())
+            ->method('addComponentDefinition')
+            ->with($this->column->getComponentName(), ['extends' => 'test_namespace']);
+
+        $this->column->prepare();
+    }
+
+    /**
+     * Run test prepare method
+     *
+     * @return void
+     */
+    public function testPrepareExtendsFromConfig()
+    {
+        $this->contextMock->expects($this->never())
+            ->method('getNamespace');
+        $this->contextMock->expects($this->once())
+            ->method('addComponentDefinition')
+            ->with($this->column->getComponentName(), ['extends' => 'test_config_extends']);
+
+        $this->column->prepare();
+    }
+}
diff --git a/app/code/Magento/Ui/Test/Unit/Component/MassActionTest.php b/app/code/Magento/Ui/Test/Unit/Component/MassActionTest.php
deleted file mode 100644
index f66f2d6a9de87f2d2fadb1c858ee6b9d2b40de4f..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/Test/Unit/Component/MassActionTest.php
+++ /dev/null
@@ -1,174 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\Test\Unit\Component;
-
-use \Magento\Ui\Component\MassAction;
-
-use Magento\Framework\View\Element\Template;
-use Magento\Framework\View\Element\Template\Context as TemplateContext;
-use Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface;
-use Magento\Framework\View\Element\UiComponent\ConfigFactory;
-use Magento\Framework\View\Element\UiComponent\Context;
-use Magento\Ui\ContentType\ContentTypeFactory;
-
-class MassActionTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var TemplateContext||\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $contextMock;
-
-    /**
-     * @var Context|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $renderContextMock;
-
-    /**
-     * @var ContentTypeFactory|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $contentTypeFactoryMock;
-
-    /**
-     * @var ConfigFactory|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $configFactoryMock;
-
-    /**
-     * @var ConfigBuilderInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $configBuilderMock;
-
-    /**
-     * @var \Magento\Ui\DataProvider\Factory|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $dataProviderFactoryMock;
-
-    /**
-     * @var \Magento\Ui\DataProvider\Manager|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $dataProviderManagerMock;
-
-    /**
-     * @var MassAction
-     */
-    protected $view;
-
-    /**
-     * Set up
-     *
-     * @return void
-     */
-    protected function setUp()
-    {
-        $this->contextMock = $this->getMock(
-            'Magento\Framework\View\Element\Template\Context',
-            [],
-            [],
-            '',
-            false
-        );
-        $this->renderContextMock = $this->getMock(
-            'Magento\Framework\View\Element\UiComponent\Context',
-            ['getNamespace', 'getStorage', 'getRequestParam'],
-            [],
-            '',
-            false
-        );
-        $this->contentTypeFactoryMock = $this->getMock(
-            'Magento\Ui\ContentType\ContentTypeFactory',
-            [],
-            [],
-            '',
-            false
-        );
-        $this->configFactoryMock = $this->getMock(
-            'Magento\Framework\View\Element\UiComponent\ConfigFactory',
-            ['create'],
-            [],
-            '',
-            false
-        );
-        $this->configBuilderMock = $this->getMockForAbstractClass(
-            'Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface',
-            [],
-            '',
-            false
-        );
-        $this->dataProviderFactoryMock = $this->getMock(
-            'Magento\Ui\DataProvider\Factory',
-            [],
-            [],
-            '',
-            false
-        );
-        $this->dataProviderManagerMock = $this->getMock(
-            'Magento\Ui\DataProvider\Manager',
-            [],
-            [],
-            '',
-            false
-        );
-
-        $this->view = new MassAction(
-            $this->contextMock,
-            $this->renderContextMock,
-            $this->contentTypeFactoryMock,
-            $this->configFactoryMock,
-            $this->configBuilderMock,
-            $this->dataProviderFactoryMock,
-            $this->dataProviderManagerMock
-        );
-    }
-
-    /**
-     * Run test prepare method
-     *
-     * @return void
-     */
-    public function testPrepare()
-    {
-        /**
-         * @var \Magento\Framework\View\Element\UiComponent\ConfigInterface
-         * |\PHPUnit_Framework_MockObject_MockObject $configurationMock
-         */
-        $configurationMock = $this->getMockForAbstractClass(
-            'Magento\Framework\View\Element\UiComponent\ConfigInterface',
-            [],
-            '',
-            false
-        );
-        /**
-         * @var \Magento\Framework\View\Element\UiComponent\ConfigStorageInterface
-         * |\PHPUnit_Framework_MockObject_MockObject $configStorageMock
-         */
-        $configStorageMock = $this->getMockForAbstractClass(
-            'Magento\Framework\View\Element\UiComponent\ConfigStorageInterface',
-            ['addComponentsData', 'getDataCollection'],
-            '',
-            false
-        );
-
-        $this->renderContextMock->expects($this->at(0))
-            ->method('getNamespace')
-            ->will($this->returnValue('namespace'));
-        $this->renderContextMock->expects($this->at(1))
-            ->method('getNamespace')
-            ->will($this->returnValue('namespace'));
-        $this->configFactoryMock->expects($this->any())
-            ->method('create')
-            ->will($this->returnValue($configurationMock));
-
-        $this->renderContextMock->expects($this->any())
-            ->method('getStorage')
-            ->will($this->returnValue($configStorageMock));
-
-        $configStorageMock->expects($this->once())
-            ->method('addComponentsData')
-            ->with($configurationMock);
-
-        $this->assertNull($this->view->prepare());
-    }
-}
diff --git a/app/code/Magento/Ui/Test/Unit/Component/PagingTest.php b/app/code/Magento/Ui/Test/Unit/Component/PagingTest.php
index e8cd28a27665a09b164e93c2f76c58e72ffd1ed7..fd4c63c3b28870ad1a60068d66ee86eb52c6291a 100644
--- a/app/code/Magento/Ui/Test/Unit/Component/PagingTest.php
+++ b/app/code/Magento/Ui/Test/Unit/Component/PagingTest.php
@@ -5,182 +5,164 @@
  */
 namespace Magento\Ui\Test\Unit\Component;
 
-use \Magento\Ui\Component\Paging;
-
-use Magento\Framework\View\Asset\Repository;
-use Magento\Framework\View\Element\Template;
-use Magento\Framework\View\Element\Template\Context as TemplateContext;
-use Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface;
-use Magento\Framework\View\Element\UiComponent\ConfigFactory;
-use Magento\Framework\View\Element\UiComponent\Context;
-use Magento\Ui\ContentType\ContentTypeFactory;
+use Magento\Ui\Component\Paging;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+use Magento\Framework\View\Element\UiComponent\ContextInterface;
+use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface;
 
+/**
+ * Class PagingTest
+ */
 class PagingTest extends \PHPUnit_Framework_TestCase
 {
     /**
-     * @var Paging
-     */
-    protected $view;
-
-    /**
-     * @var ConfigBuilderInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $configurationBuilderMock;
-
-    /**
-     * @var TemplateContext|\PHPUnit_Framework_MockObject_MockObject
+     * @var ContextInterface|\PHPUnit_Framework_MockObject_MockObject
      */
     protected $contextMock;
 
     /**
-     * @var Context|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $renderContextMock;
-
-    /**
-     * @var ContentTypeFactory|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $contentTypeFactoryMock;
-
-    /**
-     * @var ConfigFactory|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $configFactoryMock;
-
-    /**
-     * @var ConfigBuilderInterface|\PHPUnit_Framework_MockObject_MockObject
+     * @var ObjectManager
      */
-    protected $configBuilderMock;
+    protected $objectManager;
 
     /**
-     * @var \Magento\Ui\DataProvider\Factory|\PHPUnit_Framework_MockObject_MockObject
+     * Set up
      */
-    protected $dataProviderFactoryMock;
-
-    /**
-     * @var \Magento\Ui\DataProvider\Manager|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $dataProviderManagerMock;
-
-    /**
-     * @var Repository|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $assetRepoMock;
-
     public function setUp()
     {
-        $this->renderContextMock = $this->getMock(
-            'Magento\Framework\View\Element\UiComponent\Context',
-            ['getNamespace', 'getStorage', 'getRequestParam'],
-            [],
-            '',
-            false
-        );
-        $this->contextMock = $this->getMock(
-            'Magento\Framework\View\Element\Template\Context',
-            ['getAssetRepository'],
-            [],
-            '',
-            false
-        );
-        $this->contentTypeFactoryMock = $this->getMock('Magento\Ui\ContentType\ContentTypeFactory', [], [], '', false);
-        $this->configurationBuilderMock = $this->getMockForAbstractClass(
-            'Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface'
-        );
-        $this->assetRepoMock = $this->getMock('Magento\Framework\View\Asset\Repository', [], [], '', false);
-        $this->contextMock->expects($this->any())->method('getAssetRepository')->willReturn($this->assetRepoMock);
+        $this->objectManager = new ObjectManager($this);
 
-        $this->configFactoryMock = $this->getMock(
-            'Magento\Framework\View\Element\UiComponent\ConfigFactory',
-            ['create'],
-            [],
-            '',
-            false
-        );
-        $this->configBuilderMock = $this->getMockForAbstractClass(
-            'Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface',
-            [],
-            '',
-            false
-        );
-        $this->dataProviderFactoryMock = $this->getMock(
-            'Magento\Ui\DataProvider\Factory',
-            [],
-            [],
-            '',
-            false
-        );
-        $this->dataProviderManagerMock = $this->getMock(
-            'Magento\Ui\DataProvider\Manager',
-            [],
+        $this->contextMock = $this->getMockForAbstractClass(
+            'Magento\Framework\View\Element\UiComponent\ContextInterface',
             [],
             '',
-            false
+            false,
+            true,
+            true,
+            []
         );
+    }
 
-        $this->view = new \Magento\Ui\Component\Paging(
-            $this->contextMock,
-            $this->renderContextMock,
-            $this->contentTypeFactoryMock,
-            $this->configFactoryMock,
-            $this->configBuilderMock,
-            $this->dataProviderFactoryMock,
-            $this->dataProviderManagerMock
+    /**
+     * Run test getComponentName method
+     *
+     * @return void
+     */
+    public function testGetComponentName()
+    {
+        /** @var Paging $listing */
+        $paging = $this->objectManager->getObject(
+            'Magento\Ui\Component\Paging',
+            [
+                'context' => $this->contextMock,
+                'data' => []
+            ]
         );
+
+        $this->assertTrue($paging->getComponentName() === Paging::NAME);
     }
 
+    /**
+     * Run test prepare method
+     *
+     * @return void
+     */
     public function testPrepare()
     {
-        $paramsSize = 20;
-        $paramsPage = 1;
-        $nameSpace = 'namespace';
-        $configurationMock = $this->getMockForAbstractClass(
-            'Magento\Framework\View\Element\UiComponent\ConfigInterface',
-            ['getData'],
-            '',
-            false
-        );
-        $this->renderContextMock->expects($this->any())->method('getNamespace')->willReturn($nameSpace);
-        $this->configFactoryMock->expects($this->once())->method('create')->willReturn($configurationMock);
-
-        $storageMock = $this->getMockForAbstractClass(
-            'Magento\Framework\View\Element\UiComponent\ConfigStorageInterface'
+        $resultData = [
+            'js_config' => [
+                'extends' => 'test_config_extends',
+                'testData' => 'testValue'
+            ],
+            'config' => [
+                'options' => [
+                    [
+                        'value' => 20,
+                        'label' => 20
+                    ],
+                    [
+                        'value' => 30,
+                        'label' => 30
+                    ],
+                    [
+                        'value' => 50,
+                        'label' => 50
+                    ],
+                    [
+                        'value' => 100,
+                        'label' => 100
+                    ],
+                    [
+                        'value' => 200,
+                        'label' => 200
+                    ],
+                    [
+                        'value' => 20,
+                        'label' => 'options1'
+                    ],
+                    [
+                        'value' => 40,
+                        'label' => 'options2'
+                    ],
+                ],
+                'pageSize' => 20,
+                'current' => 2
+            ]
+        ];
+
+        /** @var Paging $paging */
+        $paging = $this->objectManager->getObject(
+            'Magento\Ui\Component\Paging',
+            [
+                'context' => $this->contextMock,
+                'data' => [
+                    'js_config' => [
+                        'extends' => 'test_config_extends',
+                        'testData' => 'testValue',
+                    ],
+                    'config' => [
+                        'options' => [
+                            'options1' => [
+                                'label' => 'options1',
+                                'value' => '20'
+                            ],
+                            'options2' => [
+                                'label' => 'options2',
+                                'value' => '40'
+                            ]
+                        ],
+                        'current' => 2,
+                        'pageSize' => 20
+                    ]
+                ]
+            ]
         );
-        $dataCollectionMock = $this->getMockForAbstractClass(
-            '\Magento\Framework\Data\CollectionDataSourceInterface',
+        /** @var DataProviderInterface|\PHPUnit_Framework_MockObject_MockObject $dataProviderMock */
+        $dataProviderMock = $this->getMockForAbstractClass(
+            'Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface',
             [],
             '',
-            false,
-            true,
-            true,
-            ['setPageSize', 'setCurPage']
+            false
         );
 
-        $this->renderContextMock->expects($this->any())->method('getStorage')->willReturn($storageMock);
-
-        $storageMock->expects($this->once())->method('getDataCollection')->willReturn($dataCollectionMock);
+        $this->contextMock->expects($this->once())
+            ->method('getRequestParam')
+            ->with('paging')
+            ->willReturn(['pageSize' => 5, 'current' => 3]);
+        $this->contextMock->expects($this->once())
+            ->method('getDataProvider')
+            ->willReturn($dataProviderMock);
 
-        $configurationMock->expects($this->at(0))->method('getData')->with('current')->willReturn($paramsPage);
+        $dataProviderMock->expects($this->once())
+            ->method('setLimit')
+            ->with(3, 5);
 
-        $configurationMock->expects($this->at(1))->method('getData')->with('pageSize')->willReturn($paramsSize);
-        $this->renderContextMock->expects($this->atLeastOnce())
-            ->method('getRequestParam')
-            ->willReturnMap(
-                [
-                    ['page', $paramsPage, $paramsPage],
-                    ['limit', $paramsSize, $paramsSize],
-                ]
-            );
+        $this->contextMock->expects($this->once())
+            ->method('addComponentDefinition')
+            ->with($paging->getComponentName(), ['extends' => 'test_config_extends', 'testData' => 'testValue']);
 
-        $dataCollectionMock->expects($this->any())
-            ->method('setPageSize')
-            ->with($paramsSize)
-            ->willReturnSelf();
-        $dataCollectionMock->expects($this->any())
-            ->method('setCurPage')
-            ->with($paramsPage)
-            ->willReturnSelf();
+        $paging->prepare();
 
-        $this->assertNull($this->view->prepare());
+        $this->assertEquals($paging->getData(), $resultData);
     }
 }
diff --git a/app/code/Magento/Ui/Test/Unit/Component/SortingTest.php b/app/code/Magento/Ui/Test/Unit/Component/SortingTest.php
deleted file mode 100644
index 5c7f02a31dc63b71f9b1db2fea3080a8fbef7972..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/Test/Unit/Component/SortingTest.php
+++ /dev/null
@@ -1,211 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\Test\Unit\Component;
-
-use \Magento\Ui\Component\Sorting;
-
-use Magento\Framework\View\Element\Template;
-use Magento\Framework\View\Element\Template\Context as TemplateContext;
-use Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface;
-use Magento\Framework\View\Element\UiComponent\ConfigFactory;
-use Magento\Framework\View\Element\UiComponent\Context;
-use Magento\Ui\ContentType\ContentTypeFactory;
-
-class SortingTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var TemplateContext||\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $contextMock;
-
-    /**
-     * @var Context|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $renderContextMock;
-
-    /**
-     * @var ContentTypeFactory|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $contentTypeFactoryMock;
-
-    /**
-     * @var ConfigFactory|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $configFactoryMock;
-
-    /**
-     * @var ConfigBuilderInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $configBuilderMock;
-
-    /**
-     * @var \Magento\Ui\DataProvider\Factory|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $dataProviderFactoryMock;
-
-    /**
-     * @var \Magento\Ui\DataProvider\Manager|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $dataProviderManagerMock;
-
-    /**
-     * @var Sorting
-     */
-    protected $view;
-
-    /**
-     * Set up
-     *
-     * @return void
-     */
-    protected function setUp()
-    {
-        $this->contextMock = $this->getMock(
-            'Magento\Framework\View\Element\Template\Context',
-            [],
-            [],
-            '',
-            false
-        );
-        $this->renderContextMock = $this->getMock(
-            'Magento\Framework\View\Element\UiComponent\Context',
-            ['getNamespace', 'getStorage', 'getRequestParam'],
-            [],
-            '',
-            false
-        );
-        $this->contentTypeFactoryMock = $this->getMock(
-            'Magento\Ui\ContentType\ContentTypeFactory',
-            [],
-            [],
-            '',
-            false
-        );
-        $this->configFactoryMock = $this->getMock(
-            'Magento\Framework\View\Element\UiComponent\ConfigFactory',
-            ['create'],
-            [],
-            '',
-            false
-        );
-        $this->configBuilderMock = $this->getMockForAbstractClass(
-            'Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface',
-            [],
-            '',
-            false
-        );
-        $this->dataProviderFactoryMock = $this->getMock(
-            'Magento\Ui\DataProvider\Factory',
-            [],
-            [],
-            '',
-            false
-        );
-        $this->dataProviderManagerMock = $this->getMock(
-            'Magento\Ui\DataProvider\Manager',
-            [],
-            [],
-            '',
-            false
-        );
-
-        $this->view = new Sorting(
-            $this->contextMock,
-            $this->renderContextMock,
-            $this->contentTypeFactoryMock,
-            $this->configFactoryMock,
-            $this->configBuilderMock,
-            $this->dataProviderFactoryMock,
-            $this->dataProviderManagerMock
-        );
-    }
-
-    /**
-     * Run test prepare method
-     *
-     * @return void
-     */
-    public function testPrepare()
-    {
-        /**
-         * @var \Magento\Framework\View\Element\UiComponent\ConfigInterface
-         * |\PHPUnit_Framework_MockObject_MockObject $configurationMock
-         */
-        $configurationMock = $this->getMockForAbstractClass(
-            'Magento\Framework\View\Element\UiComponent\ConfigInterface',
-            [],
-            '',
-            false
-        );
-        /**
-         * @var \Magento\Framework\View\Element\UiComponent\ConfigStorageInterface
-         * |\PHPUnit_Framework_MockObject_MockObject $configStorageMock
-         */
-        $configStorageMock = $this->getMockForAbstractClass(
-            'Magento\Framework\View\Element\UiComponent\ConfigStorageInterface',
-            ['addComponentsData', 'getDataCollection'],
-            '',
-            false
-        );
-
-        $dataCollectionMock = $this->getMockForAbstractClass(
-            'Magento\Framework\Api\CriteriaInterface',
-            ['addOrder'],
-            '',
-            false
-        );
-
-        $this->renderContextMock->expects($this->at(0))
-            ->method('getNamespace')
-            ->will($this->returnValue('namespace'));
-        $this->renderContextMock->expects($this->at(1))
-            ->method('getNamespace')
-            ->will($this->returnValue('namespace'));
-        $this->configFactoryMock->expects($this->any())
-            ->method('create')
-            ->will($this->returnValue($configurationMock));
-
-        $this->renderContextMock->expects($this->any())
-            ->method('getStorage')
-            ->will($this->returnValue($configStorageMock));
-
-        $configStorageMock->expects($this->once())
-            ->method('addComponentsData')
-            ->with($configurationMock);
-
-        $configurationMock->expects($this->at(0))
-            ->method('getData')
-            ->with('field')
-            ->will($this->returnValue('field'));
-
-        $configurationMock->expects($this->at(1))
-            ->method('getData')
-            ->with('direction')
-            ->will($this->returnValue('direction'));
-
-        $this->renderContextMock->expects($this->any())
-            ->method('getStorage')
-            ->will($this->returnValue($configStorageMock));
-
-        $configStorageMock->expects($this->once())
-            ->method('getDataCollection')
-            ->will($this->returnValue($dataCollectionMock));
-
-        $dataCollectionMock->expects($this->once())
-            ->method('addOrder')
-            ->with('field', 'FIELD');
-
-        $this->renderContextMock->expects($this->any())
-            ->method('getRequestParam')
-            ->will($this->returnValue('field'));
-
-        $this->renderContextMock->expects($this->any())
-            ->method('getRequestParam')
-            ->will($this->returnValue('direction'));
-
-        $this->assertNull($this->view->prepare());
-    }
-}
diff --git a/app/code/Magento/Ui/Test/Unit/ContentType/Builder/ConfigJsonTest.php b/app/code/Magento/Ui/Test/Unit/ContentType/Builder/ConfigJsonTest.php
deleted file mode 100644
index 47e6d0ad983f69d450086e0e6689cb625dfe214b..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/Test/Unit/ContentType/Builder/ConfigJsonTest.php
+++ /dev/null
@@ -1,36 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\Test\Unit\ContentType\Builder;
-
-use \Magento\Ui\ContentType\Builder\ConfigJson;
-
-/**
- * Class ConfigJsonTest
- */
-class ConfigJsonTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var ConfigJson
-     */
-    protected $builder;
-
-    public function testToJson()
-    {
-        $this->builder = new ConfigJson();
-        $result = ['name' => 'resultName', 'parent_name' => 'resultParentName'];
-        $configurationMock = $this->getMock(
-            'Magento\Ui\Context\Configuration',
-            ['getData', 'getName', 'getParentName'],
-            [],
-            '',
-            false
-        );
-        $configurationMock->expects($this->once())->method('getData')->willReturn($result);
-        $configurationMock->expects($this->once())->method('getName')->willReturn($result['name']);
-        $configurationMock->expects($this->once())->method('getParentName')->willReturn($result['parent_name']);
-        $this->assertEquals(json_encode($result), $this->builder->toJson($configurationMock));
-    }
-}
diff --git a/app/code/Magento/Ui/Test/Unit/ContentType/Builder/ConfigStorageJsonTest.php b/app/code/Magento/Ui/Test/Unit/ContentType/Builder/ConfigStorageJsonTest.php
deleted file mode 100644
index 22511628d15e2631c499c186dbb91b0bf291d5fe..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/Test/Unit/ContentType/Builder/ConfigStorageJsonTest.php
+++ /dev/null
@@ -1,99 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\Test\Unit\ContentType\Builder;
-
-use \Magento\Ui\ContentType\Builder\ConfigStorageJson;
-
-/**
- * Class ConfigStorageJsonTest
- */
-class ConfigStorageJsonTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var ConfigStorageJson
-     */
-    protected $builder;
-
-    public function testToJson()
-    {
-        $this->builder = new ConfigStorageJson();
-        $name = 'name';
-        $data = [];
-        $parentName = 'parentName';
-        $dataSource = [
-            'data' => null,
-        ];
-        $result = [
-            'config' => ['components' => [$name => $data], 'globalData' => ['globalData']],
-            'meta' => null,
-            'name' => $name,
-            'parent_name' => $parentName,
-            'data' => null,
-            'dump' => ['extenders' => []],
-        ];
-
-        $rootComponentMock = $this->getMock(
-            'Magento\Ui\Context\Configuration',
-            ['getName', 'getParentName', 'getData'],
-            [],
-            '',
-            false
-        );
-        $storageMock = $this->getMock(
-            'Magento\Ui\Context\ConfigurationStorage',
-            ['getComponentsData', 'getGlobalData', 'getMeta', 'getDataSource'],
-            [],
-            '',
-            false
-        );
-
-        $storageMock->expects($this->once())
-            ->method('getComponentsData')
-            ->with($parentName)
-            ->will($this->returnValue($rootComponentMock));
-        $rootComponentMock->expects($this->any())->method('getName')->willReturn($result['name']);
-        $rootComponentMock->expects($this->once())->method('getParentName')->willReturn($result['parent_name']);
-        $rootComponentMock->expects($this->once())
-            ->method('getData')
-            ->willReturn($data);
-        $storageMock->expects($this->once())->method('getGlobalData')->willReturn($result['config']);
-        $storageMock->expects($this->once())->method('getDataSource')->will($this->returnValue($dataSource));
-
-        $this->assertEquals(json_encode($result), $this->builder->toJson($storageMock, $parentName));
-    }
-
-    public function testToJsonNoParentName()
-    {
-        $this->builder = new ConfigStorageJson();
-        $data = [];
-        $dataSource = [
-            'data' => $data,
-        ];
-        $result = [
-            'config' => ['components' => ['name' => $data], 'globalData' => ['globalData']],
-            'meta' => null,
-            'data' => [],
-            'dump' => ['extenders' => []],
-        ];
-        $componentsMock = $this->getMock('Magento\Ui\Context\Configuration', ['getData'], [], '', false);
-        $storageMock = $this->getMock(
-            'Magento\Ui\Context\ConfigurationStorage',
-            ['getComponentsData', 'getGlobalData', 'getMeta', 'getDataSource'],
-            [],
-            '',
-            false
-        );
-
-        $storageMock->expects($this->once())->method('getComponentsData')->will($this->returnValue($componentsMock));
-        $componentsMock->expects($this->any())->method('getData')->willReturn($data);
-
-        $storageMock->expects($this->once())->method('getMeta')->will($this->returnValue($result['meta']));
-        $storageMock->expects($this->once())->method('getDataSource')->will($this->returnValue($dataSource));
-        $storageMock->expects($this->once())->method('getGlobalData')->willReturn($result['config']);
-
-        $this->assertEquals(json_encode($result), $this->builder->toJson($storageMock));
-    }
-}
diff --git a/app/code/Magento/Ui/Test/Unit/ContentType/ContentTypeFactoryTest.php b/app/code/Magento/Ui/Test/Unit/ContentType/ContentTypeFactoryTest.php
deleted file mode 100644
index 3f1c82345fcdb2706a63ef4c3a42849ca16a6441..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/Test/Unit/ContentType/ContentTypeFactoryTest.php
+++ /dev/null
@@ -1,68 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\Test\Unit\ContentType;
-
-use \Magento\Ui\ContentType\ContentTypeFactory;
-
-/**
- * Class ContentTypeFactoryTest
- */
-class ContentTypeFactoryTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var ContentTypeFactory
-     */
-    protected $contentTypeFactory;
-
-    /**
-     * @param $type
-     * @param @expected
-     * @dataProvider getDataProvider
-     */
-    public function testGet($type, $contentRender, $expected)
-    {
-        $objectManagerMock = $this->getMock('Magento\Framework\ObjectManagerInterface');
-        $this->contentTypeFactory = new ContentTypeFactory($objectManagerMock);
-        $objectManagerMock->expects($this->once())->method('get')->with($expected)->willReturn($contentRender);
-        $this->assertInstanceOf($expected, $this->contentTypeFactory->get($type));
-    }
-
-    /**
-     * @expectedException \InvalidArgumentException
-     */
-    public function testGetTypeException()
-    {
-        $objectManagerMock = $this->getMock('Magento\Framework\ObjectManagerInterface');
-        $this->contentTypeFactory = new ContentTypeFactory($objectManagerMock);
-        $this->contentTypeFactory->get('bad_type');
-    }
-
-    /**
-     * @expectedException \InvalidArgumentException
-     */
-    public function testGetInstanceException()
-    {
-        $objectManagerMock = $this->getMock('Magento\Framework\ObjectManagerInterface');
-        $this->contentTypeFactory = new ContentTypeFactory($objectManagerMock);
-        $objectManagerMock->expects($this->once())->method('get')->willReturnSelf();
-        $this->contentTypeFactory->get();
-    }
-
-    /**
-     * @return array
-     */
-    public function getDataProvider()
-    {
-        $htmlMock = $this->getMock('Magento\Ui\ContentType\Html', [], [], '', false);
-        $jsonMock = $this->getMock('Magento\Ui\ContentType\Json', [], [], '', false);
-        $xmlMock = $this->getMock('Magento\Ui\ContentType\Xml', [], [], '', false);
-        return [
-            ['html', $htmlMock, 'Magento\Ui\ContentType\Html'],
-            ['json', $jsonMock, 'Magento\Ui\ContentType\Json'],
-            ['xml', $xmlMock, 'Magento\Ui\ContentType\Xml']
-        ];
-    }
-}
diff --git a/app/code/Magento/Ui/Test/Unit/ContentType/HtmlTest.php b/app/code/Magento/Ui/Test/Unit/ContentType/HtmlTest.php
deleted file mode 100644
index e9485bff9816cfe6704329d76202e4bf172ccf32..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/Test/Unit/ContentType/HtmlTest.php
+++ /dev/null
@@ -1,86 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\Test\Unit\ContentType;
-
-use \Magento\Ui\ContentType\Html;
-
-/**
- * Class HtmlTest
- */
-class HtmlTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var Html
-     */
-    protected $html;
-
-    /**
-     * @var \Magento\Framework\View\FileSystem|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $filesystemMock;
-
-    /**
-     * @var \Magento\Framework\View\TemplateEnginePool|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $templateEnginePoolMock;
-
-    /**
-     * @var \Magento\Framework\View\Element\UiComponentInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $viewInterfaceMock;
-
-    public function setUp()
-    {
-        $this->filesystemMock = $this->getMock(
-            'Magento\Framework\View\FileSystem',
-            ['getTemplateFileName'],
-            [],
-            '',
-            false
-        );
-        $this->templateEnginePoolMock = $this->getMock(
-            'Magento\Framework\View\TemplateEnginePool',
-            ['get'],
-            [],
-            '',
-            false
-        );
-        $this->html = new Html($this->filesystemMock, $this->templateEnginePoolMock);
-        $this->viewInterfaceMock = $this->getMockForAbstractClass(
-            'Magento\Framework\View\Element\UiComponentInterface'
-        );
-    }
-
-    public function testRender()
-    {
-        $template = 'test_template';
-        $result = 'result';
-        $path = 'path';
-        $this->viewInterfaceMock = $this->getMockForAbstractClass(
-            'Magento\Framework\View\Element\UiComponentInterface'
-        );
-        $templateEngineMock = $this->getMockForAbstractClass('Magento\Framework\View\TemplateEngineInterface');
-
-        $this->templateEnginePoolMock->expects($this->once())
-            ->method('get')
-            ->willReturn($templateEngineMock);
-        $this->filesystemMock->expects($this->once())
-            ->method('getTemplateFileName')
-            ->with($template)
-            ->willReturn($path);
-        $templateEngineMock->expects($this->once())
-            ->method('render')
-            ->with($this->viewInterfaceMock, $path)
-            ->willReturn($result);
-
-        $this->assertEquals($result, $this->html->render($this->viewInterfaceMock, $template));
-    }
-
-    public function testRenderEmpty()
-    {
-        $this->assertEquals('', $this->html->render($this->viewInterfaceMock, ''));
-    }
-}
diff --git a/app/code/Magento/Ui/Test/Unit/Context/ConfigurationStorageTest.php b/app/code/Magento/Ui/Test/Unit/Context/ConfigurationStorageTest.php
deleted file mode 100644
index bd2419521963bc29c6de5cbad8069356857f06c4..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/Test/Unit/Context/ConfigurationStorageTest.php
+++ /dev/null
@@ -1,157 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-namespace Magento\Ui\Test\Unit\Context;
-
-use \Magento\Ui\Context\ConfigurationStorage;
-use \Magento\Ui\Context\Configuration;
-use Magento\Framework\Data\Collection as DataCollection;
-
-/**
- * Class ConfigurationStorageTest
- * @package Magento\Ui
- */
-class ConfigurationStorageTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var array
-     */
-    protected $componentStorage = [];
-
-    /**
-     * @var array
-     */
-    protected $dataStorage = [];
-
-    /**
-     * @var array
-     */
-    protected $metaStorage = [];
-
-    /**
-     * @var DataCollection[]
-     */
-    protected $collectionStorage = [];
-
-    /**
-     * @var array
-     */
-    protected $cloudDataStorage = [];
-
-    /**
-     * @var ConfigurationStorage
-     */
-    protected $configurationStorage;
-
-    public function setUp()
-    {
-        $this->configurationStorage = new ConfigurationStorage();
-    }
-
-    public function testAddGetComponentsData()
-    {
-        $configuration = ['key' => 'value'];
-        $name = 'myName';
-        $parentName = 'thisParentName';
-        $configurationModel = new Configuration($name, $parentName, $configuration);
-        $this->componentStorage = [$configurationModel->getName() => $configurationModel];
-        $this->configurationStorage->addComponentsData($configurationModel);
-
-        $this->assertEquals($this->componentStorage, $this->configurationStorage->getComponentsData(null));
-        $this->assertEquals(null, $this->configurationStorage->getComponentsData('someKey'));
-        $this->assertEquals($configurationModel, $this->configurationStorage->getComponentsData($name));
-    }
-
-    public function testRemoveComponentsData()
-    {
-        $configuration = ['key' => 'value'];
-        $name = 'myName';
-        $parentName = 'thisParentName';
-        $configurationModel = new Configuration($name, $parentName, $configuration);
-        $this->componentStorage = [$configurationModel->getName() => $configurationModel];
-        $this->configurationStorage->addComponentsData($configurationModel);
-        $this->assertEquals($configurationModel, $this->configurationStorage->getComponentsData($name));
-        $this->configurationStorage->removeComponentsData($configurationModel);
-        $this->assertEquals(null, $this->configurationStorage->getComponentsData($name));
-    }
-
-    public function testAddGetData()
-    {
-        $name = 'myName';
-        $dataSource = [
-            'data' => ['key' => 'value'],
-            'config' => ['key' => 'value'],
-        ];
-        $this->configurationStorage->addDataSource($name, $dataSource);
-        $this->assertEquals([$name => $dataSource], $this->configurationStorage->getDataSource(null));
-        $this->assertEquals(null, $this->configurationStorage->getDataSource('someKey'));
-        $this->assertEquals($dataSource, $this->configurationStorage->getDataSource($name));
-    }
-
-    public function testUpdateRemoveData()
-    {
-        $dataSource = [
-            'data' => ['key' => 'value'],
-            'config' => ['key' => 'value'],
-        ];
-        $key = 'myKey';
-        $this->configurationStorage->addDataSource($key, $dataSource);
-        $this->assertEquals($dataSource, $this->configurationStorage->getDataSource($key));
-        $dataSource = [
-            'data' => ['key1' => 'value1'],
-            'config' => ['key1' => 'value1'],
-        ];
-        $this->configurationStorage->updateDataSource($key, $dataSource);
-        $this->assertEquals($dataSource, $this->configurationStorage->getDataSource($key));
-        $this->configurationStorage->removeDataSource($key);
-        $this->assertEquals(null, $this->configurationStorage->getDataSource($key));
-    }
-
-    public function testAddGetMeta()
-    {
-        $data = ['key' => 'value'];
-        $key = 'myName';
-        $this->configurationStorage->addMeta($key, $data);
-        $this->assertEquals([$key => $data], $this->configurationStorage->getMeta(null));
-        $this->assertEquals(null, $this->configurationStorage->getMeta('someKey'));
-        $this->assertEquals($data, $this->configurationStorage->getMeta($key));
-    }
-
-    public function testUpdateRemoveMeta()
-    {
-        $data = ['key' => 'value'];
-        $key = 'myKey';
-        $this->configurationStorage->addMeta($key, $data);
-        $this->assertEquals($data, $this->configurationStorage->getMeta($key));
-        $data = ['key1' => 'value1'];
-        $this->configurationStorage->updateMeta($key, $data);
-        $this->assertEquals($data, $this->configurationStorage->getMeta($key));
-        $this->configurationStorage->removeMeta($key);
-        $this->assertEquals(null, $this->configurationStorage->getMeta($key));
-    }
-
-    public function testAddGetDataCollection()
-    {
-        $key = 'myName';
-        $dataCollection = $this->getMock('Magento\Framework\Data\CollectionDataSourceInterface', [], [], '', false);
-        $this->configurationStorage->addDataCollection($key, $dataCollection);
-
-        $this->assertEquals([$key => $dataCollection], $this->configurationStorage->getDataCollection(null));
-        $this->assertEquals(null, $this->configurationStorage->getDataCollection('someKey'));
-        $this->assertEquals($dataCollection, $this->configurationStorage->getDataCollection($key));
-    }
-
-    public function testRemoveDataCollection()
-    {
-        $key = 'myName';
-        $dataCollection = $this->getMock('Magento\Framework\Data\CollectionDataSourceInterface', [], [], '', false);
-        $update = clone $dataCollection;
-        $this->configurationStorage->addDataCollection($key, $dataCollection);
-        $this->assertEquals($dataCollection, $this->configurationStorage->getDataCollection($key));
-        $this->configurationStorage->updateDataCollection($key, $update);
-        $this->assertEquals($update, $this->configurationStorage->getDataCollection($key));
-    }
-}
diff --git a/app/code/Magento/Ui/Test/Unit/Context/ConfigurationTest.php b/app/code/Magento/Ui/Test/Unit/Context/ConfigurationTest.php
deleted file mode 100644
index ae2de3bb751f3f62222e4410206f00c9a34205bf..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/Test/Unit/Context/ConfigurationTest.php
+++ /dev/null
@@ -1,71 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-namespace Magento\Ui\Test\Unit\Context;
-
-use \Magento\Ui\Context\Configuration;
-
-class ConfigurationTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var []
-     */
-    protected $configuration;
-
-    /**
-     * @var string
-     */
-    protected $name;
-
-    /**
-     * @var string
-     */
-    protected $parentName;
-
-    /**
-     * @var Configuration
-     */
-    protected $configurationModel;
-
-    public function setUp()
-    {
-        $this->configuration = ['key' => 'value'];
-        $this->name = 'myName';
-        $this->parentName = 'thisParentName';
-        $this->configurationModel = new Configuration($this->name, $this->parentName, $this->configuration);
-    }
-
-    public function testGetData()
-    {
-        $this->assertEquals($this->configuration, $this->configurationModel->getData(null));
-        $this->assertEquals(null, $this->configurationModel->getData('someKey'));
-        $this->assertEquals('value', $this->configurationModel->getData('key'));
-    }
-
-    public function testAddData()
-    {
-        $this->configurationModel->addData('new_key', 'value1');
-        $this->assertEquals('value1', $this->configurationModel->getData('new_key'));
-    }
-
-    public function testUpdateData()
-    {
-        $this->configurationModel->addData('new_key', 'value1');
-        $this->assertEquals('value1', $this->configurationModel->getData('new_key'));
-        $this->configurationModel->updateData('new_key', 'value2');
-        $this->assertEquals('value2', $this->configurationModel->getData('new_key'));
-    }
-
-    public function testGetName()
-    {
-        $this->assertEquals($this->name, $this->configurationModel->getName());
-    }
-
-    public function testGetParentName()
-    {
-        $this->assertEquals($this->parentName, $this->configurationModel->getParentName());
-    }
-}
diff --git a/app/code/Magento/Ui/Test/Unit/Controller/Adminhtml/Index/RenderTest.php b/app/code/Magento/Ui/Test/Unit/Controller/Adminhtml/Index/RenderTest.php
index 9239d619dbb64f5ed10cb6cda9820376c1bdfcfc..f3bc80d217c4d7cdadffd44ae412aa26d777a5fe 100644
--- a/app/code/Magento/Ui/Test/Unit/Controller/Adminhtml/Index/RenderTest.php
+++ b/app/code/Magento/Ui/Test/Unit/Controller/Adminhtml/Index/RenderTest.php
@@ -63,24 +63,31 @@ class RenderTest extends \PHPUnit_Framework_TestCase
 
         $this->requestMock->expects($this->at(0))
             ->method('getParam')
-            ->with('component')
-            ->willReturn($name);
-        $this->requestMock->expects($this->at(1))
-            ->method('getParam')
-            ->with('name')
+            ->with('namespace')
             ->willReturn($name);
         $this->responseMock->expects($this->once())
             ->method('appendBody')
             ->with($renderedData);
 
-        $viewMock = $this->getMock('Magento\Ui\Form\Field', ['render'], [], '', false);
+        /**
+         * @var \Magento\Framework\View\Element\UiComponentInterface|\PHPUnit_Framework_MockObject_MockObject $viewMock
+         */
+        $viewMock = $this->getMockForAbstractClass(
+            'Magento\Framework\View\Element\UiComponentInterface',
+            [],
+            '',
+            false,
+            true,
+            true,
+            ['render']
+        );
         $viewMock->expects($this->once())
             ->method('render')
             ->willReturn($renderedData);
         $this->uiFactoryMock->expects($this->once())
-            ->method('createUiComponent')
+            ->method('create')
             ->willReturn($viewMock);
 
-        $this->assertNull($this->render->execute());
+        $this->render->execute();
     }
 }
diff --git a/app/code/Magento/Ui/Test/Unit/DataProvider/Config/FileResolverTest.php b/app/code/Magento/Ui/Test/Unit/DataProvider/Config/FileResolverTest.php
deleted file mode 100644
index c1518f0b1a7f18b023df12ae17dc91cf3fd4ab68..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/Test/Unit/DataProvider/Config/FileResolverTest.php
+++ /dev/null
@@ -1,50 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Ui\Test\Unit\DataProvider\Config;
-
-use \Magento\Ui\DataProvider\Config\FileResolver;
-
-use Magento\Framework\Filesystem;
-
-class FileResolverTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\Framework\Filesystem\Directory\Read | \PHPUnit_Framework_MockObject_MockObject
-     */
-    private $mockDirectoryRead;
-
-    /**
-     * @var FileResolver
-     */
-    private $fileResolver;
-
-    public function setUp()
-    {
-        $this->mockDirectoryRead = $this->getMockBuilder('Magento\Framework\Filesystem\Directory\Read')
-            ->disableOriginalConstructor()
-            ->getMock();
-        $stubFileIteratorFactory = $this->getMockBuilder('Magento\Framework\Config\FileIteratorFactory')
-            ->disableOriginalConstructor()
-            ->getMock();
-        $stubFilesystem = $this->getMockBuilder('Magento\Framework\Filesystem')
-            ->disableOriginalConstructor()
-            ->getMock();
-        $stubFilesystem->expects($this->any())
-            ->method('getDirectoryRead')
-            ->willReturn($this->mockDirectoryRead);
-        $this->fileResolver = new FileResolver($stubFilesystem, $stubFileIteratorFactory);
-    }
-
-    public function testItAppliesTheFilenamePattern()
-    {
-        $this->mockDirectoryRead->expects($this->once())
-            ->method('search')
-            ->with($this->matchesRegularExpression('#\*\.xml$#'))
-            ->willReturn([]);
-
-        $this->fileResolver->get('*.xml', '');
-    }
-}
diff --git a/app/code/Magento/Ui/composer.json b/app/code/Magento/Ui/composer.json
index ecf417cad0f81fd792b366b6d2f314848fbfcf7b..07c4a7c8ab3910486f2e7369f3f7b47d30eb6f3b 100644
--- a/app/code/Magento/Ui/composer.json
+++ b/app/code/Magento/Ui/composer.json
@@ -3,13 +3,13 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
-        "magento/module-eav": "0.74.0-beta6",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
+        "magento/module-eav": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Ui/etc/di.xml b/app/code/Magento/Ui/etc/di.xml
index 55a44cd9d4df72096e6fc157f80ba2cedd56d11a..b5684f5734d9b6e641b01f26aaee55b92befa5ea 100644
--- a/app/code/Magento/Ui/etc/di.xml
+++ b/app/code/Magento/Ui/etc/di.xml
@@ -6,20 +6,250 @@
  */
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
-    <preference for="Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface" type="Magento\Ui\ContentType\Builder\ConfigJson" />
-    <preference for="Magento\Framework\View\Element\UiComponent\ConfigStorageBuilderInterface" type="Magento\Ui\ContentType\Builder\ConfigStorageJson" />
-    <preference for="Magento\Framework\View\Element\UiComponent\ConfigInterface" type="Magento\Ui\Context\Configuration" />
-    <preference for="Magento\Framework\View\Element\UiComponent\ConfigStorageInterface" type="Magento\Ui\Context\ConfigurationStorage" />
-    <preference for="Magento\Ui\Component\Control\ActionPoolInterface" type="Magento\Ui\Component\Control\ActionPool" />
+    <preference for="Magento\Framework\View\Element\UiComponent\ContainerInterface" type="Magento\Ui\Component\Wrapper\UiComponent" />
+    <preference for="Magento\Framework\View\Element\UiComponent\Control\ActionPoolInterface" type="Magento\Ui\Component\Control\ActionPool" />
+    <preference for="Magento\Framework\Data\Argument\InterpreterInterface" type="Magento\Framework\Data\Argument\Interpreter\Composite" />
+    <preference for="Magento\Framework\Config\ConverterInterface" type="Magento\Framework\View\Element\UiComponent\Config\Converter" />
+    <preference for="Magento\Framework\View\Element\UiComponent\Config\ManagerInterface" type="Magento\Framework\View\Element\UiComponent\Config\Manager" />
+    <preference for="Magento\Framework\View\Element\UiComponent\ContextInterface" type="Magento\Framework\View\Element\UiComponent\Context" />
+    <preference for="Magento\Framework\View\Element\UiComponent\LayoutInterface" type="Magento\Ui\Component\Layout\Generic"/>
+    <type name="Magento\Framework\View\Element\UiComponent\TemplateAdapter" shared="false" />
+    <type name="Magento\Framework\View\TemplateEngineFactory">
+        <arguments>
+            <argument name="engines" xsi:type="array">
+                <item name="xhtml" xsi:type="string">Magento\Ui\TemplateEngine\Xhtml</item>
+            </argument>
+        </arguments>
+    </type>
+    <type name="Magento\Ui\TemplateEngine\Xhtml">
+        <arguments>
+            <argument name="compiler" xsi:type="object">Magento\Ui\TemplateEngine\Xhtml\Compiler</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Framework\View\Element\UiComponent\ContentType\ContentTypeFactory">
+        <arguments>
+            <argument name="types" xsi:type="array">
+                <item name="html" xsi:type="string">Magento\Framework\View\Element\UiComponent\ContentType\Html</item>
+                <item name="json" xsi:type="string">Magento\Framework\View\Element\UiComponent\ContentType\Json</item>
+                <item name="xml" xsi:type="string">Magento\Framework\View\Element\UiComponent\ContentType\Xml</item>
+            </argument>
+        </arguments>
+    </type>
+    <type name="Magento\Ui\TemplateEngine\Xhtml\Compiler\Text">
+        <arguments>
+            <argument name="directivePool" xsi:type="array">
+                <item name="variable" xsi:type="object">Magento\Ui\TemplateEngine\Xhtml\Compiler\Directive\Variable</item>
+                <item name="callableMethod" xsi:type="object">Magento\Ui\TemplateEngine\Xhtml\Compiler\Directive\CallableMethod</item>
+            </argument>
+        </arguments>
+    </type>
+    <type name="Magento\Ui\TemplateEngine\Xhtml\Compiler\Attribute">
+        <arguments>
+            <argument name="directivePool" xsi:type="array">
+                <item name="variable" xsi:type="object">Magento\Ui\TemplateEngine\Xhtml\Compiler\Directive\Variable</item>
+                <item name="callableMethod" xsi:type="object">Magento\Ui\TemplateEngine\Xhtml\Compiler\Directive\CallableMethod</item>
+            </argument>
+        </arguments>
+    </type>
+    <type name="Magento\Ui\TemplateEngine\Xhtml\Compiler" shared="false">
+        <arguments>
+            <argument name="compilerText" xsi:type="object">Magento\Ui\TemplateEngine\Xhtml\Compiler\Text</argument>
+            <argument name="compilerAttribute" xsi:type="object">Magento\Ui\TemplateEngine\Xhtml\Compiler\Attribute</argument>
+            <argument name="compilerCdata" xsi:type="object">Magento\Ui\TemplateEngine\Xhtml\Compiler\Cdata</argument>
+            <argument name="compilerComment" xsi:type="object">Magento\Ui\TemplateEngine\Xhtml\Compiler\Comment</argument>
+            <argument name="elementCompilers" xsi:type="array">
+                <item name="render" xsi:type="object">Magento\Ui\TemplateEngine\Xhtml\Compiler\Element\Render</item>
+                <item name="content" xsi:type="object">\Magento\Ui\TemplateEngine\Xhtml\Compiler\Element\Content</item>
+                <item name="form" xsi:type="object">Magento\Ui\TemplateEngine\Xhtml\Compiler\Element\Form</item>
+            </argument>
+        </arguments>
+    </type>
+    <virtualType name="uiConfigurationDomMerger" type="Magento\Framework\View\Element\UiComponent\Config\DomMerger">
+        <arguments>
+            <argument name="schemaFileType" xsi:type="string">etc</argument>
+            <argument name="schemaFileModule" xsi:type="string">Magento_Ui</argument>
+            <argument name="schemaFileName" xsi:type="string">ui_configuration.xsd</argument>
+            <argument name="contextXPath" xsi:type="array">
+                <item name="ui_context" xsi:type="string">/</item>
+            </argument>
+            <argument name="idAttributes" xsi:type="array">
+                <item name="attribute_name" xsi:type="string">name</item>
+            </argument>
+        </arguments>
+    </virtualType>
+    <type name="Magento\Framework\View\Element\UiComponent\Config\Manager">
+        <arguments>
+            <argument name="domMerger" xsi:type="object">uiConfigurationDomMerger</argument>
+        </arguments>
+    </type>
+    <virtualType name="uiTemplateDomMerger" type="Magento\Framework\View\Element\UiComponent\Config\DomMerger">
+        <arguments>
+            <argument name="schemaFileType" xsi:type="string">etc</argument>
+            <argument name="schemaFileModule" xsi:type="string">Magento_Ui</argument>
+            <argument name="schemaFileName" xsi:type="string">ui_template.xsd</argument>
+            <argument name="contextXPath" xsi:type="array">
+                <item name="ui_context" xsi:type="string">/</item>
+            </argument>
+            <argument name="idAttributes" xsi:type="array">
+                <item name="attribute_name" xsi:type="string">name</item>
+                <item name="attribute_id" xsi:type="string">id</item>
+            </argument>
+        </arguments>
+    </virtualType>
+    <type name="Magento\Framework\View\Element\UiComponent\Config\Provider\Template">
+        <arguments>
+            <argument name="domMerger" xsi:type="object">uiTemplateDomMerger</argument>
+        </arguments>
+    </type>
+    <virtualType name="uiDefinitionDomMerger" type="Magento\Framework\View\Element\UiComponent\Config\DomMerger">
+        <arguments>
+            <argument name="schemaFileType" xsi:type="string">etc</argument>
+            <argument name="schemaFileModule" xsi:type="string">Magento_Ui</argument>
+            <argument name="schemaFileName" xsi:type="string">ui_definition.xsd</argument>
+            <argument name="contextXPath" xsi:type="array">
+                <item name="ui_context" xsi:type="string">/components</item>
+            </argument>
+            <argument name="idAttributes" xsi:type="array">
+                <item name="attribute_name" xsi:type="string">name</item>
+            </argument>
+            <argument name="isMergeSimpleXMLElement" xsi:type="boolean">true</argument>
+        </arguments>
+    </virtualType>
+    <virtualType name="uiDefinitionFileCollector" type="Magento\Framework\View\Element\UiComponent\Config\FileCollector\AggregatedFileCollector">
+        <arguments>
+            <argument name="searchPattern" xsi:type="string">etc/definition.xml</argument>
+        </arguments>
+    </virtualType>
+    <virtualType name="uiDefinitionReader" type="Magento\Framework\View\Element\UiComponent\Config\Reader">
+        <arguments>
+            <argument name="fileCollector" xsi:type="object">uiDefinitionFileCollector</argument>
+            <argument name="domMerger" xsi:type="object">uiDefinitionDomMerger</argument>
+        </arguments>
+    </virtualType>
+    <type name="Magento\Framework\View\Element\UiComponent\Config\Provider\Component\Definition">
+        <arguments>
+            <argument name="uiReader" xsi:type="object">uiDefinitionReader</argument>
+        </arguments>
+    </type>
     <type name="Magento\Ui\Component\Filter\FilterPool">
         <arguments>
             <argument name="filters" xsi:type="array">
                 <item name="filter_input" xsi:type="string">Magento\Ui\Component\Filter\Type\Input</item>
                 <item name="filter_select" xsi:type="string">Magento\Ui\Component\Filter\Type\Select</item>
                 <item name="filter_range" xsi:type="string">Magento\Ui\Component\Filter\Type\Range</item>
-                <item name="filter_date" xsi:type="string">Magento\Ui\Component\Filter\Type\Date</item>
                 <item name="filter_store" xsi:type="string">Magento\Ui\Component\Filter\Type\Store</item>
             </argument>
         </arguments>
     </type>
+    <type name="Magento\Ui\Component\Layout\LayoutPool">
+        <arguments>
+            <argument name="types" xsi:type="array">
+                <item name="generic" xsi:type="array">
+                    <item name="class" xsi:type="string">Magento\Ui\Component\Layout\Generic</item>
+                    <item name="template" xsi:type="string">templates/layout/generic</item>
+                </item>
+                <item name="tabs" xsi:type="array">
+                    <item name="class" xsi:type="string">Magento\Ui\Component\Layout\Tabs</item>
+                    <item name="template" xsi:type="string">templates/layout/tabs</item>
+                </item>
+            </argument>
+        </arguments>
+    </type>
+    <virtualType name="arrayArgumentInterpreterProxy" type="Magento\Framework\Data\Argument\InterpreterInterface\Proxy">
+        <arguments>
+            <argument name="instanceName" xsi:type="string">Magento\Framework\Data\Argument\Interpreter\ArrayType</argument>
+        </arguments>
+    </virtualType>
+    <virtualType name="configurableObjectArgumentInterpreterProxy" type="Magento\Framework\Data\Argument\InterpreterInterface\Proxy">
+        <arguments>
+            <argument name="instanceName" xsi:type="string">Magento\Framework\View\Element\UiComponent\Argument\Interpreter\ConfigurableObject</argument>
+        </arguments>
+    </virtualType>
+    <type name="Magento\Framework\Data\Argument\Interpreter\Composite">
+        <arguments>
+            <argument name="interpreters" xsi:type="array">
+                <item name="object" xsi:type="object">Magento\Framework\Data\Argument\Interpreter\Object</item>
+                <item name="configurableObject" xsi:type="object">configurableObjectArgumentInterpreterProxy</item>
+                <item name="array" xsi:type="object">arrayArgumentInterpreterProxy</item>
+                <item name="boolean" xsi:type="object">Magento\Framework\Data\Argument\Interpreter\Boolean</item>
+                <item name="number" xsi:type="object">Magento\Framework\Data\Argument\Interpreter\Number</item>
+                <item name="string" xsi:type="object">Magento\Framework\Data\Argument\Interpreter\String</item>
+                <item name="null" xsi:type="object">Magento\Framework\Data\Argument\Interpreter\NullType</item>
+            </argument>
+            <argument name="discriminator" xsi:type="string">xsi:type</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Framework\View\Element\UiComponent\Config\FileCollector\AggregatedFileCollector">
+        <arguments>
+            <argument name="collectorAggregated" xsi:type="object">uiComponentAggregatedCollector</argument>
+        </arguments>
+    </type>
+    <virtualType name="uiComponentAggregatedCollector" type="Magento\Framework\View\Layout\File\Collector\Aggregated">
+        <arguments>
+            <argument name="baseFiles" xsi:type="object">uiComponentAggregatedSourceBaseSorted</argument>
+            <argument name="themeFiles" xsi:type="object">uiComponentAggregatedSourceThemeSorted</argument>
+            <argument name="overrideBaseFiles" xsi:type="object">uiComponentAggregatedSourceOverrideBaseSorted</argument>
+            <argument name="overrideThemeFiles" xsi:type="object">uiComponentAggregatedSourceOverrideThemeSorted</argument>
+        </arguments>
+    </virtualType>
+    <virtualType name="uiComponentAggregatedSourceBase" type="Magento\Framework\View\File\Collector\Base">
+        <arguments>
+            <argument name="subDir" xsi:type="string">ui_component</argument>
+        </arguments>
+    </virtualType>
+    <virtualType shared="false" name="uiComponentAggregatedSourceBaseFiltered" type="Magento\Framework\View\File\Collector\Decorator\ModuleOutput">
+        <arguments>
+            <argument name="subject" xsi:type="object">uiComponentAggregatedSourceBase</argument>
+        </arguments>
+    </virtualType>
+    <virtualType name="uiComponentAggregatedSourceBaseSorted" type="Magento\Framework\View\File\Collector\Decorator\ModuleDependency">
+        <arguments>
+            <argument name="subject" xsi:type="object">uiComponentAggregatedSourceBaseFiltered</argument>
+        </arguments>
+    </virtualType>
+    <virtualType name="uiComponentAggregatedSourceTheme" type="Magento\Framework\View\File\Collector\ThemeModular">
+        <arguments>
+            <argument name="subDir" xsi:type="string">ui_component</argument>
+        </arguments>
+    </virtualType>
+    <virtualType name="uiComponentAggregatedSourceThemeFiltered" type="Magento\Framework\View\File\Collector\Decorator\ModuleOutput">
+        <arguments>
+            <argument name="subject" xsi:type="object">uiComponentAggregatedSourceTheme</argument>
+        </arguments>
+    </virtualType>
+    <virtualType name="uiComponentAggregatedSourceThemeSorted" type="Magento\Framework\View\File\Collector\Decorator\ModuleDependency">
+        <arguments>
+            <argument name="subject" xsi:type="object">uiComponentAggregatedSourceThemeFiltered</argument>
+        </arguments>
+    </virtualType>
+    <virtualType name="uiComponentAggregatedSourceOverrideBase" type="Magento\Framework\View\File\Collector\Override\Base">
+        <arguments>
+            <argument name="subDir" xsi:type="string">layout/override/base</argument>
+        </arguments>
+    </virtualType>
+    <virtualType name="uiComponentAggregatedSourceOverrideBaseFiltered" type="Magento\Framework\View\File\Collector\Decorator\ModuleOutput">
+        <arguments>
+            <argument name="subject" xsi:type="object">uiComponentAggregatedSourceOverrideBase</argument>
+        </arguments>
+    </virtualType>
+    <virtualType name="uiComponentAggregatedSourceOverrideBaseSorted" type="Magento\Framework\View\File\Collector\Decorator\ModuleDependency">
+        <arguments>
+            <argument name="subject" xsi:type="object">uiComponentAggregatedSourceOverrideBaseFiltered</argument>
+        </arguments>
+    </virtualType>
+    <virtualType name="uiComponentAggregatedSourceOverrideTheme" type="Magento\Framework\View\File\Collector\Override\ThemeModular">
+        <arguments>
+            <argument name="subDir" xsi:type="string">layout/override/theme</argument>
+        </arguments>
+    </virtualType>
+    <virtualType name="uiComponentAggregatedSourceOverrideThemeFiltered" type="Magento\Framework\View\File\Collector\Decorator\ModuleOutput">
+        <arguments>
+            <argument name="subject" xsi:type="object">uiComponentAggregatedSourceOverrideTheme</argument>
+        </arguments>
+    </virtualType>
+    <virtualType name="uiComponentAggregatedSourceOverrideThemeSorted" type="Magento\Framework\View\File\Collector\Decorator\ModuleDependency">
+        <arguments>
+            <argument name="subject" xsi:type="object">uiComponentAggregatedSourceOverrideThemeFiltered</argument>
+        </arguments>
+    </virtualType>
 </config>
diff --git a/app/code/Magento/Ui/etc/ui_components.xsd b/app/code/Magento/Ui/etc/ui_components.xsd
new file mode 100644
index 0000000000000000000000000000000000000000..6cd0edbfc363f24af6de5d73fb43ab467ac69737
--- /dev/null
+++ b/app/code/Magento/Ui/etc/ui_components.xsd
@@ -0,0 +1,322 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
+    <!-- Include section -->
+    <xs:include schemaLocation="../../../../../lib/internal/Magento/Framework/Data/etc/argument/types.xsd"/>
+    <!-- Defined the types of components -->
+    <xs:complexType name="layout" xml:base="ui_element">
+        <xs:complexContent>
+            <xs:extension base="ui_element">
+                <xs:choice minOccurs="0" maxOccurs="unbounded">
+                    <xs:group ref="configurable"/>
+                </xs:choice>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="tab">
+        <xs:complexContent>
+            <xs:extension base="ui_element">
+                <xs:choice minOccurs="0" maxOccurs="unbounded">
+                    <xs:group ref="configurable"/>
+                </xs:choice>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="columns">
+        <xs:complexContent>
+            <xs:extension base="ui_element">
+                <xs:choice minOccurs="0" maxOccurs="unbounded">
+                    <xs:group ref="configurable"/>
+                </xs:choice>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="column">
+        <xs:complexContent>
+            <xs:extension base="field">
+                <xs:choice minOccurs="0" maxOccurs="unbounded">
+                    <xs:group ref="configurable"/>
+                </xs:choice>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="dataSource">
+        <xs:complexContent>
+            <xs:extension base="ui_element">
+                <xs:choice minOccurs="0" maxOccurs="unbounded">
+                    <xs:group ref="configurable"/>
+                </xs:choice>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="listing">
+        <xs:complexContent>
+            <xs:extension base="ui_element">
+                <xs:choice minOccurs="0" maxOccurs="unbounded">
+                    <xs:group ref="configurable"/>
+                </xs:choice>
+                <xs:attribute name="sorting" use="optional">
+                    <xs:simpleType>
+                        <xs:restriction base="xs:string">
+                            <xs:enumeration value="true"/>
+                            <xs:enumeration value="false"/>
+                        </xs:restriction>
+                    </xs:simpleType>
+                </xs:attribute>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="paging">
+        <xs:complexContent>
+            <xs:extension base="ui_element">
+                <xs:choice minOccurs="0" maxOccurs="unbounded">
+                    <xs:group ref="configurable"/>
+                </xs:choice>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="filters">
+        <xs:complexContent>
+            <xs:extension base="ui_element">
+                <xs:choice minOccurs="0" maxOccurs="unbounded">
+                    <xs:group ref="configurable"/>
+                </xs:choice>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="filterSelect">
+        <xs:complexContent>
+            <xs:extension base="select"/>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="filterRange">
+        <xs:complexContent>
+            <xs:extension base="input"/>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="filterInput">
+        <xs:complexContent>
+            <xs:extension base="input"/>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="filterDate">
+        <xs:complexContent>
+            <xs:extension base="input"/>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="container">
+        <xs:complexContent>
+            <xs:extension base="ui_element">
+                <xs:choice minOccurs="0" maxOccurs="unbounded">
+                    <xs:group ref="configurable"/>
+                </xs:choice>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="massaction">
+        <xs:complexContent>
+            <xs:extension base="ui_element">
+                <xs:choice minOccurs="0" maxOccurs="unbounded">
+                    <xs:group ref="configurable"/>
+                </xs:choice>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="form">
+        <xs:complexContent>
+            <xs:extension base="ui_element">
+                <xs:choice minOccurs="0" maxOccurs="unbounded">
+                    <xs:group ref="configurable"/>
+                </xs:choice>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="input">
+        <xs:complexContent>
+            <xs:extension base="ui_element">
+                <xs:choice minOccurs="0" maxOccurs="unbounded">
+                    <xs:group ref="configurable"/>
+                </xs:choice>
+                <xs:attribute name="displayZone" use="optional">
+                    <xs:simpleType>
+                        <xs:restriction base="xs:string">
+                            <xs:enumeration value="header"/>
+                            <xs:enumeration value="content"/>
+                        </xs:restriction>
+                    </xs:simpleType>
+                </xs:attribute>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="checkbox">
+        <xs:complexContent>
+            <xs:extension base="input"/>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="select">
+        <xs:complexContent>
+            <xs:extension base="input"/>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="multiselect">
+        <xs:complexContent>
+            <xs:extension base="select"/>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="textarea">
+        <xs:complexContent>
+            <xs:extension base="ui_element">
+                <xs:choice minOccurs="0" maxOccurs="unbounded">
+                    <xs:group ref="configurable"/>
+                </xs:choice>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="fieldset">
+        <xs:complexContent>
+            <xs:extension base="ui_element">
+                <xs:choice minOccurs="0" maxOccurs="unbounded">
+                    <xs:element name="field" type="field" />
+                    <xs:element name="container" type="container" />
+                    <xs:group ref="configurable"/>
+                </xs:choice>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="field">
+        <xs:complexContent>
+            <xs:extension base="ui_element">
+                <xs:choice minOccurs="0" maxOccurs="unbounded">
+                    <xs:group ref="configurable"/>
+                </xs:choice>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="dataTypeText">
+        <xs:complexContent>
+            <xs:extension base="ui_element">
+                <xs:choice minOccurs="0" maxOccurs="unbounded">
+                    <xs:group ref="configurable"/>
+                </xs:choice>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="dataTypeBoolean">
+        <xs:complexContent>
+            <xs:extension base="ui_element">
+                <xs:choice minOccurs="0" maxOccurs="unbounded">
+                    <xs:group ref="configurable"/>
+                </xs:choice>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="dataTypeNumber">
+        <xs:complexContent>
+            <xs:extension base="ui_element">
+                <xs:choice minOccurs="0" maxOccurs="unbounded">
+                    <xs:group ref="configurable"/>
+                </xs:choice>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="dataTypePrice">
+        <xs:complexContent>
+            <xs:extension base="ui_element">
+                <xs:choice minOccurs="0" maxOccurs="unbounded">
+                    <xs:group ref="configurable"/>
+                </xs:choice>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="dataTypeMedia">
+        <xs:complexContent>
+            <xs:extension base="ui_element">
+                <xs:choice minOccurs="0" maxOccurs="unbounded">
+                    <xs:group ref="configurable"/>
+                </xs:choice>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="dataTypeDate">
+        <xs:complexContent>
+            <xs:extension base="ui_element">
+                <xs:choice minOccurs="0" maxOccurs="unbounded">
+                    <xs:group ref="configurable"/>
+                </xs:choice>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="dataTypeEmail">
+        <xs:complexContent>
+            <xs:extension base="ui_element">
+                <xs:choice minOccurs="0" maxOccurs="unbounded">
+                    <xs:group ref="configurable"/>
+                </xs:choice>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="nav">
+        <xs:complexContent>
+            <xs:extension base="ui_element">
+                <xs:choice minOccurs="0" maxOccurs="unbounded">
+                    <xs:group ref="configurable"/>
+                </xs:choice>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="actions">
+        <xs:complexContent>
+            <xs:extension base="ui_element">
+                <xs:choice minOccurs="0" maxOccurs="unbounded">
+                    <xs:group ref="configurable"/>
+                </xs:choice>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <!-- Global groups -->
+    <xs:group name="configurable">
+        <xs:sequence>
+            <xs:element type="argumentType" name="argument" minOccurs="0" maxOccurs="unbounded">
+                <xs:key name="configurableArgumentItemName">
+                    <xs:selector xpath="item"/>
+                    <xs:field xpath="@name"/>
+                </xs:key>
+            </xs:element>
+        </xs:sequence>
+    </xs:group>
+    <!-- Global types -->
+    <xs:complexType name="constant">
+        <xs:complexContent>
+            <xs:extension base="argumentType"/>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="ui_element">
+        <xs:attribute type="xs:string" name="name" use="optional"/>
+        <xs:attribute type="xs:boolean" name="disabled" use="optional"/>
+        <xs:attribute type="xs:string" name="layout" use="optional"/>
+        <xs:attribute type="xs:string" name="dataSource" use="optional"/>
+        <xs:attribute type="xs:string" name="class" use="optional"/>
+    </xs:complexType>
+    <!-- Simple types -->
+    <xs:simpleType name="referenceAttributeType">
+        <xs:annotation>
+            <xs:documentation>The value should only be {[a-z_-]+} since it is used as a reference to a database field.</xs:documentation>
+        </xs:annotation>
+        <xs:restriction base="xs:string">
+            <xs:pattern value="[a-z_-]+" />
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="textAttributeType">
+        <xs:annotation>
+            <xs:documentation>Any text value</xs:documentation>
+        </xs:annotation>
+        <xs:restriction base="xs:string">
+            <xs:pattern value="[A-Za-z0-9,_.\\: -]+" />
+        </xs:restriction>
+    </xs:simpleType>
+</xs:schema>
diff --git a/app/code/Magento/Ui/etc/ui_configuration.xsd b/app/code/Magento/Ui/etc/ui_configuration.xsd
new file mode 100644
index 0000000000000000000000000000000000000000..84f16e2db35d60bc40b48e4eeeb4b45c58ff59ca
--- /dev/null
+++ b/app/code/Magento/Ui/etc/ui_configuration.xsd
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
+    <xs:annotation>
+        <xs:appinfo>The definition of a configuration item components</xs:appinfo>
+        <xs:documentation>The definition of a configuration item components</xs:documentation>
+    </xs:annotation>
+    <!-- Include section -->
+    <xs:include schemaLocation="ui_components.xsd"/>
+    <!-- Components list -->
+    <xs:element type="formConfiguration" name="form"/>
+    <xs:element type="listingConfiguration" name="listing"/>
+    <!-- Custom configuration -->
+    <xs:complexType name="containerConfiguration">
+        <xs:complexContent>
+            <xs:extension base="container">
+                <xs:choice minOccurs="0" maxOccurs="unbounded">
+                    <xs:element type="paging" name="paging"/>
+                    <xs:element type="filtersConfiguration" name="filters"/>
+                    <xs:element type="massaction" name="massaction"/>
+                    <xs:element type="columnsConfiguration" name="columns"/>
+                    <xs:element type="containerConfiguration" name="container"/>
+                    <xs:element name="field" type="field" />
+                </xs:choice>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="fieldsetConfiguration">
+        <xs:complexContent>
+            <xs:extension base="container">
+                <xs:choice minOccurs="0" maxOccurs="unbounded">
+                    <xs:element type="containerConfiguration" name="container"/>
+                    <xs:element name="field" type="field" />
+                </xs:choice>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="listingConfiguration">
+        <xs:complexContent>
+            <xs:extension base="listing">
+                <xs:choice minOccurs="0" maxOccurs="unbounded">
+                    <xs:element type="paging" name="paging"/>
+                    <xs:element type="filtersConfiguration" name="filters"/>
+                    <xs:element type="massaction" name="massaction"/>
+                    <xs:element type="dataSource" name="dataSource"/>
+                    <xs:element type="columnsConfiguration" name="columns"/>
+                    <xs:element type="containerConfiguration" name="container"/>
+                </xs:choice>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="formConfiguration">
+        <xs:complexContent>
+            <xs:extension base="form">
+                <xs:choice minOccurs="0" maxOccurs="unbounded">
+                    <xs:element name="fieldset" type="fieldsetConfiguration" />
+                    <xs:element name="field" type="field" />
+                    <xs:element type="dataSource" name="dataSource"/>
+                </xs:choice>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="columnsConfiguration">
+        <xs:complexContent>
+            <xs:extension base="columns">
+                <xs:choice minOccurs="0" maxOccurs="unbounded">
+                    <xs:element name="column" type="column" />
+                </xs:choice>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="filtersConfiguration">
+        <xs:complexContent>
+            <xs:extension base="filters">
+                <xs:choice minOccurs="0" maxOccurs="unbounded">
+                    <xs:element name="filterDate" type="filterDate" />
+                    <xs:element name="filterInput" type="filterInput" />
+                    <xs:element name="filterRange" type="filterRangeConfiguration" />
+                    <xs:element name="filterSelect" type="filterSelect" />
+                    <xs:element name="containerConfiguration" type="container" />
+                </xs:choice>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="filterRangeConfiguration">
+        <xs:complexContent>
+            <xs:extension base="filterRange">
+                <xs:choice minOccurs="0" maxOccurs="unbounded">
+                    <xs:element name="filterDate" type="filterDate" />
+                    <xs:element name="filterInput" type="filterInput" />
+                    <xs:element name="filterSelect" type="filterSelect" />
+                </xs:choice>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+</xs:schema>
diff --git a/app/code/Magento/Ui/etc/ui_definition.xsd b/app/code/Magento/Ui/etc/ui_definition.xsd
new file mode 100644
index 0000000000000000000000000000000000000000..fc279745827db502f0c3504c96a8e521ec102dc3
--- /dev/null
+++ b/app/code/Magento/Ui/etc/ui_definition.xsd
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
+    <!-- Include section -->
+    <xs:include schemaLocation="ui_components.xsd"/>
+    <!-- Definition the document element -->
+    <xs:element name="components" type="definition"/>
+    <!-- Registering components in the system -->
+    <xs:complexType name="definition">
+        <xs:annotation>
+            <xs:appinfo>Registering components in the system and basic setup</xs:appinfo>
+            <xs:documentation>Registering components in the system and basic setup</xs:documentation>
+        </xs:annotation>
+        <xs:all>
+            <!-- Components list -->
+            <xs:element type="tab" name="tab"/>
+            <xs:element type="dataSource" name="dataSource"/>
+            <xs:element type="paging" name="paging"/>
+            <xs:element type="massaction" name="massaction"/>
+            <xs:element type="listingDefinition" name="listing"/>
+            <xs:element type="formDefinition" name="form"/>
+            <xs:element type="fieldset" name="fieldset"/>
+            <xs:element type="field" name="field"/>
+            <xs:element type="filters" name="filters"/>
+            <xs:element type="columns" name="columns"/>
+            <xs:element type="column" name="column"/>
+            <xs:element type="filterSelect" name="filterSelect"/>
+            <xs:element type="filterRange" name="filterRange"/>
+            <xs:element type="filterInput" name="filterInput"/>
+            <xs:element type="filterDate" name="filterDate"/>
+            <xs:element type="container" name="container"/>
+            <xs:element type="input" name="input"/>
+            <xs:element type="checkbox" name="checkbox"/>
+            <xs:element type="select" name="select"/>
+            <xs:element type="multiselect" name="multiselect"/>
+            <xs:element type="textarea" name="textarea"/>
+            <xs:element type="dataTypeText" name="text"/>
+            <xs:element type="dataTypeBoolean" name="boolean"/>
+            <xs:element type="dataTypeNumber" name="number"/>
+            <xs:element type="dataTypePrice" name="price"/>
+            <xs:element type="dataTypeMedia" name="media"/>
+            <xs:element type="dataTypeDate" name="date"/>
+            <xs:element type="dataTypeEmail" name="email"/>
+            <xs:element type="nav" name="nav"/>
+            <xs:element type="actions" name="actions"/>
+        </xs:all>
+    </xs:complexType>
+    <!-- Custom configuration -->
+    <xs:complexType name="listingDefinition">
+        <xs:complexContent>
+            <xs:extension base="listing">
+                <xs:choice minOccurs="0" maxOccurs="unbounded">
+                    <xs:element type="dataSource" name="dataSource"/>
+                    <xs:element type="paging" name="paging"/>
+                    <xs:element type="massaction" name="massaction"/>
+                    <xs:element type="columns" name="columns"/>
+                    <xs:element type="filters" name="filters"/>
+                </xs:choice>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="formDefinition">
+        <xs:complexContent>
+            <xs:extension base="form">
+                <xs:choice minOccurs="0" maxOccurs="unbounded">
+                    <xs:element type="fieldset" name="fieldset"/>
+                    <xs:element type="dataSource" name="dataSource"/>
+                </xs:choice>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+</xs:schema>
diff --git a/app/code/Magento/Ui/etc/ui_template.xsd b/app/code/Magento/Ui/etc/ui_template.xsd
new file mode 100644
index 0000000000000000000000000000000000000000..ef5b731067363469152765f0a5579edb76e129d6
--- /dev/null
+++ b/app/code/Magento/Ui/etc/ui_template.xsd
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
+    <xs:element name="form">
+        <xs:complexType >
+            <xs:sequence>
+                <xs:any minOccurs="0" maxOccurs="unbounded" processContents="lax" />
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+    <xs:element name="div" >
+        <xs:complexType >
+            <xs:sequence>
+                <xs:any minOccurs="0" maxOccurs="unbounded" processContents="lax" />
+            </xs:sequence>
+            <xs:anyAttribute processContents="lax" />
+        </xs:complexType>
+    </xs:element>
+</xs:schema>
diff --git a/app/code/Magento/Ui/view/base/layout/ui_components.xml b/app/code/Magento/Ui/view/base/layout/ui_components.xml
deleted file mode 100644
index d8d2be00aa0e54a757831b1d04d749dca4a29ae1..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/layout/ui_components.xml
+++ /dev/null
@@ -1,245 +0,0 @@
-<?xml version="1.0"?>
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/layout_generic.xsd">
-    <block class="Magento\Ui\Component\Listing" name="listing">
-        <arguments>
-            <argument name="content_template" xsi:type="string">Magento_Ui::listing/horizontal_grid.phtml</argument>
-            <argument name="save_parameters_in_session" xsi:type="string">1</argument>
-            <argument name="client_root" xsi:type="string">mui/index/render</argument>
-        </arguments>
-        <container label="Listing Head" name="listing_head"/>
-        <container label="Listing Before" name="listing_before">
-            <ui_component name="sorting" component="component_sorting" />
-            <ui_component name="paging" component="component_paging" />
-            <ui_component name="filters" component="component_filter_pool" />
-            <ui_component name="massactions" component="component_control_massaction" />
-        </container>
-    </block>
-    <block class="Magento\Ui\Component\Paging" name="component_paging">
-        <arguments>
-            <argument name="content_template" xsi:type="string">Magento_Ui::paging/default.phtml</argument>
-        </arguments>
-    </block>
-    <block class="Magento\Ui\Component\FilterPool" name="component_filter_pool">
-        <arguments>
-            <argument name="content_template" xsi:type="string">Magento_Ui::filter_pool/default.phtml</argument>
-            <argument name="config" xsi:type="array">
-                <item name="types" xsi:type="array">
-                    <item name="filter_date" xsi:type="array">
-                        <item name="dateFormat" xsi:type="string">mm/dd/yyyy</item>
-                    </item>
-                    <item name="filter_input" xsi:type="array"/>
-                    <item name="filter_select" xsi:type="array"/>
-                    <item name="filter_range" xsi:type="array"/>
-                </item>
-            </argument>
-        </arguments>
-    </block>
-    <block class="Magento\Ui\Component\Filter\Type\Select" name="filter_select" />
-    <block class="Magento\Ui\Component\Filter\Type\Range" name="filter_range" />
-    <block class="Magento\Ui\Component\Filter\Type\Input" name="filter_input" />
-    <block class="Magento\Ui\Component\Filter\Type\Date" name="filter_date" />
-
-    <block class="Magento\Ui\Component\Sorting" name="component_sorting">
-        <arguments>
-            <argument name="content_template" xsi:type="string">Magento_Ui::sorting/default.phtml</argument>
-            <argument name="config" xsi:type="array">
-                <item name="direction" xsi:type="string">asc</item>
-            </argument>
-        </arguments>
-    </block>
-
-    <block class="Magento\Ui\Component\MassAction" name="component_control_massaction">
-        <arguments>
-            <argument name="content_template" xsi:type="string">Magento_Ui::listingcontainer/massaction/default.phtml</argument>
-        </arguments>
-    </block>
-
-    <block class="Magento\Ui\Component\Control\Action" name="actions" />
-
-    <block class="Magento\Ui\Component\Form\Element\Input" name="input">
-        <arguments>
-            <argument name="js_config" xsi:type="array">
-                <item name="component" xsi:type="string">Magento_Ui/js/form/element/abstract</item>
-                <item name="config" xsi:type="array">
-                    <item name="input_type" xsi:type="string">input</item>
-                </item>
-            </argument>
-        </arguments>
-    </block>
-    <block class="Magento\Ui\Component\Form\Element\Input" name="checkbox">
-        <arguments>
-            <argument name="input_type" xsi:type="string">checkbox</argument>
-            <argument name="js_config" xsi:type="array">
-                <item name="component" xsi:type="string">Magento_Ui/js/form/element/boolean</item>
-                <item name="config" xsi:type="array">
-                    <item name="input_type" xsi:type="string">checkbox</item>
-                </item>
-            </argument>
-        </arguments>
-    </block>
-    <block class="Magento\Ui\Component\Form\Element\Select" name="select">
-        <arguments>
-            <argument name="js_config" xsi:type="array">
-                <item name="component" xsi:type="string">Magento_Ui/js/form/element/select</item>
-                <item name="config" xsi:type="array">
-                    <item name="input_type" xsi:type="string">select</item>
-                </item>
-            </argument>
-        </arguments>
-    </block>
-    <block class="Magento\Ui\Component\Form\Element\Select" name="multiselect">
-        <arguments>
-            <argument name="js_config" xsi:type="array">
-                <item name="component" xsi:type="string">Magento_Ui/js/form/element/multiselect</item>
-                <item name="config" xsi:type="array">
-                    <item name="input_type" xsi:type="string">multiselect</item>
-                    <item name="template" xsi:type="string">ui/form/element/multiselect</item>
-                </item>
-            </argument>
-        </arguments>
-    </block>
-    <block class="Magento\Ui\Component\Form\Element\Textarea" name="textarea">
-        <arguments>
-            <argument name="js_config" xsi:type="array">
-                <item name="component" xsi:type="string">Magento_Ui/js/form/element/textarea</item>
-                <item name="config" xsi:type="array">
-                    <item name="input_type" xsi:type="string">textarea</item>
-                </item>
-            </argument>
-        </arguments>
-    </block>
-
-    <block class="Magento\Ui\Component\Form\Element\DataType\Text" name="text" />
-    <block class="Magento\Ui\Component\Form\Element\DataType\Number" name="number" />
-    <block class="Magento\Ui\Component\Form\Element\DataType\Price" name="price" />
-    <block class="Magento\Ui\Component\Form\Element\DataType\Media" name="media">
-        <arguments>
-            <argument name="js_config" xsi:type="array">
-                <item name="extends" xsi:type="string">input</item>
-                <item name="config" xsi:type="array">
-                    <item name="input_type" xsi:type="string">media</item>
-                </item>
-            </argument>
-        </arguments>
-    </block>
-    <block class="Magento\Ui\Component\Form\Element\DataType\Date" name="date">
-        <arguments>
-            <argument name="js_config" xsi:type="array">
-                <item name="extends" xsi:type="string">input</item>
-                <item name="component" xsi:type="string">Magento_Ui/js/form/element/date</item>
-                <item name="config" xsi:type="array">
-                    <item name="input_type" xsi:type="string">date</item>
-                </item>
-            </argument>
-        </arguments>
-    </block>
-    <block class="Magento\Ui\Component\Form\Element\DataType\Boolean" name="boolean">
-        <arguments>
-            <argument name="js_config" xsi:type="array">
-                <item name="extends" xsi:type="string">input</item>
-                <item name="config" xsi:type="array">
-                    <item name="input_type" xsi:type="string">select</item>
-                </item>
-            </argument>
-        </arguments>
-    </block>
-    <block class="Magento\Ui\Component\Form\Element\DataType\Email" name="email">
-        <arguments>
-            <argument name="js_config" xsi:type="array">
-                <item name="extends" xsi:type="string">input</item>
-                <item name="config" xsi:type="array">
-                    <item name="input_type" xsi:type="string">email</item>
-                </item>
-            </argument>
-        </arguments>
-    </block>
-
-    <block class="Magento\Ui\Component\Form" name="form">
-        <arguments>
-            <argument name="content_template" xsi:type="string">Magento_Ui::form/default.phtml</argument>
-            <argument name="save_url" xsi:type="string">mui/form/save</argument>
-            <argument name="validate_url" xsi:type="string">mui/form/validate</argument>
-            <argument name="layout" xsi:type="array">
-                <item name="type" xsi:type="string">tabs</item>
-            </argument>
-            <argument name="js_config" xsi:type="array">
-                <item name="component" xsi:type="string">Magento_Ui/js/form</item>
-            </argument>
-        </arguments>
-    </block>
-    <block class="Magento\Ui\Component\Form\Fieldset" name="fieldset">
-        <arguments>
-            <argument name="content_template" xsi:type="string">Magento_Ui::form/fieldset/default.phtml</argument>
-            <argument name="js_config" xsi:type="array">
-                <item name="component" xsi:type="string">Magento_Ui/js/form/components/fieldset</item>
-            </argument>
-        </arguments>
-    </block>
-    <block class="Magento\Ui\Component\Layout\Tabs" name="tabs">
-        <arguments>
-            <argument name="content_template" xsi:type="string">Magento_Ui::layout/tabs/default.phtml</argument>
-            <argument name="js_config" xsi:type="array">
-                <item name="component" xsi:type="string">Magento_Ui/js/form/components/tabs</item>
-            </argument>
-        </arguments>
-    </block>
-    <block class="Magento\Ui\Component\Layout\Tabs\Tab" name="tab">
-        <arguments>
-            <argument name="content_template" xsi:type="string">Magento_Ui::layout/tabs/tab/default.phtml</argument>
-            <argument name="js_config" xsi:type="array">
-                <item name="component" xsi:type="string">Magento_Ui/js/form/components/area</item>
-            </argument>
-        </arguments>
-    </block>
-    <block class="Magento\Ui\Component\Layout\Group" name="group">
-        <arguments>
-            <argument name="content_template" xsi:type="string">Magento_Ui::layout/group/default.phtml</argument>
-            <argument name="js_config" xsi:type="array">
-                <item name="component" xsi:type="string">Magento_Ui/js/form/components/group</item>
-            </argument>
-        </arguments>
-    </block>
-    <block class="Magento\Ui\Component\Layout\Tabs\Nav" name="nav">
-        <arguments>
-            <argument name="content_template" xsi:type="string">Magento_Ui::layout/tabs/nav/default.phtml</argument>
-            <argument name="js_config" xsi:type="array">
-                <item name="component" xsi:type="string">Magento_Ui/js/form/components/tab_group</item>
-                <item name="config" xsi:type="array">
-                    <item name="template" xsi:type="string">ui/tab</item>
-                </item>
-            </argument>
-        </arguments>
-    </block>
-    <block class="Magento\Ui\Component\Container\Content" name="html_content">
-        <arguments>
-            <argument name="content_template" xsi:type="string">Magento_Ui::container/content/default.phtml</argument>
-            <argument name="js_config" xsi:type="array">
-                <item name="component" xsi:type="string">Magento_Ui/js/form/components/html</item>
-            </argument>
-        </arguments>
-    </block>
-
-    <block class="Magento\Ui\Component\Form\Collection" name="collection">
-        <arguments>
-            <argument name="content_template" xsi:type="string">Magento_Ui::form/collection/default.phtml</argument>
-            <argument name="js_config" xsi:type="array">
-                <item name="component" xsi:type="string">Magento_Ui/js/form/components/collection</item>
-            </argument>
-        </arguments>
-    </block>
-
-    <block class="Magento\Ui\Component\Form\Element\Input" name="post_code">
-        <arguments>
-            <argument name="js_config" xsi:type="array">
-                <item name="component" xsi:type="string">Magento_Ui/js/form/element/post-code</item>
-                <item name="dependentFiled" xsi:type="string">country_id</item>
-            </argument>
-        </arguments>
-    </block>
-</layout>
diff --git a/app/code/Magento/Ui/view/base/requirejs-config.js b/app/code/Magento/Ui/view/base/requirejs-config.js
index 8f1227f8bf26407d0418aeecfead532701ba900c..50196fbadd38064a068d4850c11b6da7e74e31ad 100644
--- a/app/code/Magento/Ui/view/base/requirejs-config.js
+++ b/app/code/Magento/Ui/view/base/requirejs-config.js
@@ -7,5 +7,11 @@ var config = {
     paths: {
         'ui/template': 'Magento_Ui/templates',
         'i18n': 'Magento_Ui/js/lib/i18n'
+    },
+    map: {
+        '*': {
+            uiComponent: 'Magento_Ui/js/lib/component/main',
+            uiRegistry: 'Magento_Ui/js/lib/registry/registry'
+        }
     }
 };
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/templates/context/default.phtml b/app/code/Magento/Ui/view/base/templates/context/default.phtml
index ecd62351fb8d098b71c2dc9a6c611893be33c01d..e05848ba175c40b7cc3e95ef5e37472730bd3a96 100644
--- a/app/code/Magento/Ui/view/base/templates/context/default.phtml
+++ b/app/code/Magento/Ui/view/base/templates/context/default.phtml
@@ -3,10 +3,5 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-/**
- * @var \Magento\Ui\Context\DataProvider $block
- */
 ?>
-<script type="application/json">
-    <?php echo $block->getAsJson(); ?>
-</script>
+<script data-mage-init='{ "Magento_Ui/js/core/app": "" }' type="application/json"></script>
diff --git a/app/code/Magento/Ui/view/base/templates/filter_pool/active.phtml b/app/code/Magento/Ui/view/base/templates/filter_pool/active.phtml
deleted file mode 100644
index f4419a7023e503893ffa2d07219e20f1900997d2..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/templates/filter_pool/active.phtml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-// @codingStandardsIgnoreFile
-
-/**
- * @var \Magento\Ui\Component\Filter $block
- */
-?>
-<strong class="item-label" data-bind-="text: $t(filter.title)"><?php echo $block->getData('label') ?></strong>
-<span class="item-value" data-bind-="text: $t(filter.output)"><?php echo $block->getData('current_display_value') ?></span>
-<button data-bind-="click: $parent.onClear(filter)" type="button" class="action action-remove"><span data-bind-="text: $t('Remove')"></span></button>
diff --git a/app/code/Magento/Ui/view/base/templates/filter_pool/default.phtml b/app/code/Magento/Ui/view/base/templates/filter_pool/default.phtml
deleted file mode 100644
index caec2660f677e5534558308e33021b753a8639e6..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/templates/filter_pool/default.phtml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-/**
- * @var \Magento\Ui\Component\FilterPool $block
- */
-?>
-<script type="text/x-magento-init">
-    {
-        "*": {
-            "Magento_Ui/js/listing/filter": <?php echo $block->getConfigBuilder()->toJson($block->getConfig()); ?>
-        }
-    }
-</script>
-<div data-bind="scope: '<?php echo $block->getParentName(); ?>:<?php echo $block->getName(); ?>'">
-    <!-- ko template: 'ui/filter' --><!-- /ko -->
-</div>
diff --git a/app/code/Magento/Ui/view/base/templates/form/default.phtml b/app/code/Magento/Ui/view/base/templates/form/default.phtml
index 7c51b5cb65711b8067c4abc21e1ee53d6f738754..3f42ae43172860c4eb6769bf949c7255f97e2dc6 100644
--- a/app/code/Magento/Ui/view/base/templates/form/default.phtml
+++ b/app/code/Magento/Ui/view/base/templates/form/default.phtml
@@ -6,20 +6,13 @@
 /**
  * @var \Magento\Ui\Component\Form $block
  */
-$formConfig = $block->getRenderContext()->getConfigBuilder()->toJsonNew($block->getRenderContext()->getStorage());
+echo $block->renderChildComponent('before_form');
 ?>
-<script type="text/x-magento-init">
-    {
-        "*": {
-            "Magento_Ui/js/core/app": <?php echo $formConfig; ?>
-        }
-    }
-</script>
-<div data-role="spinner" data-component="<?php echo $block->getDataScope(); ?>.areas" class="grid-loading-mask">
-    <div class="spinner">
-        <span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span>
-    </div>
+<div data-role="spinner" data-component="<?php echo $block->getName(); ?>.areas" class="admin__data-grid-loading-mask">
+    <div class="grid-loader"></div>
 </div>
-<div data-bind="scope: '<?php echo $block->getDataScope(); ?>.areas'">
+<div data-bind="scope: '<?php echo $block->getName(); ?>.areas'" class="entry-edit form-inline">
     <!-- ko template: getTemplate() --><!-- /ko -->
 </div>
+<?php
+echo $block->renderChildComponent('after_form');
diff --git a/app/code/Magento/Ui/view/base/templates/form/fieldset/default.phtml b/app/code/Magento/Ui/view/base/templates/form/fieldset/default.phtml
deleted file mode 100644
index 0d814d882b5f9ca4524523847e639d1680bf7516..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/templates/form/fieldset/default.phtml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-// @codingStandardsIgnoreFile
-
-/**
- * @var \Magento\Ui\Component\Form\Fieldset $block
- */
-$children = $block->getChildren();
-$content = $block->getContent();
-$ajaxUrl = $block->getAjaxUrl();
-?>
-<div class="admin__fieldset-wrapper-title" tabindex="3" data-bind="click: onClick, keyboard: { 13: toggle }">
-    <strong class="title">
-        <span data-bind="text: label"><?php echo $block->getData('config/label'); ?></span>
-    </strong>
-</div>
-
-<div class="admin__fieldset-wrapper-content">
-    <fieldset id="<?php echo $block->getData('index'); ?>" class="admin__fieldset">
-        <?php if (!empty($content)): ?>
-            <?php echo $content; ?>
-        <?php endif; ?>
-        <?php if (is_array($children) && !$ajaxUrl): ?>
-            <?php foreach ($children as $childName): ?>
-                <?php $childElement = $block->getLayoutElement($childName);?>
-                <p><?php echo $block->renderElement('group', $childElement); ?></p>
-            <?php endforeach; ?>
-        <?php endif; ?>
-    </fieldset>
-</div>
diff --git a/app/code/Magento/Ui/view/base/templates/label/default.phtml b/app/code/Magento/Ui/view/base/templates/label/default.phtml
index b1cf43ddc16f714217fc24f76de9a8920d0fd27e..d9937521b97202e4c3358982b6f31661cc89a959 100644
--- a/app/code/Magento/Ui/view/base/templates/label/default.phtml
+++ b/app/code/Magento/Ui/view/base/templates/label/default.phtml
@@ -3,9 +3,6 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-/**
- * @var \Magento\Ui\Component\AbstractView $block
- */
 ?>
 <span>
     <?php echo $block->getData('label'); ?>
diff --git a/app/code/Magento/Ui/view/base/templates/layout/group/default.phtml b/app/code/Magento/Ui/view/base/templates/layout/group/default.phtml
deleted file mode 100644
index c3a67828419eda7d3fd5465d6b45acd1181dd23f..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/templates/layout/group/default.phtml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-// @codingStandardsIgnoreFile
-
-/**
- * @var \Magento\Ui\Component\Layout\Group $block
- */
-
-?>
-<div class="admin__field <?php echo $block->getIsRequired()?>" data-bind="css: {'required': required}">
-    <label class="admin__field-label" data-bind="attr: { for: <?php echo $block->getData('index')?> }" for="R1WKK">
-        <span data-bind="text: element.label"><?php echo $block->getData('label')?></span>
-    </label>
-    <div class="admin__field-control">
-        <?php if ($block->getChildren()): ?>
-            <?php foreach ($block->getChildren() as $child): ?>
-            <?php echo $block->renderElement($child['dataType'], ['field_config' => $child]); ?>
-            <?php endforeach; ?>
-        <?php endif;?>
-    </div>
-</div>
diff --git a/app/code/Magento/Ui/view/base/templates/layout/tabs/nav/default.phtml b/app/code/Magento/Ui/view/base/templates/layout/tabs/nav/default.phtml
index 46f9c9a8f0ec5672b8b8bed3a9b48fefa7d58bf6..471cf5f85bb6c48b670f61871040913c100a4ded 100644
--- a/app/code/Magento/Ui/view/base/templates/layout/tabs/nav/default.phtml
+++ b/app/code/Magento/Ui/view/base/templates/layout/tabs/nav/default.phtml
@@ -7,11 +7,6 @@
  * @var \Magento\Ui\Component\Layout\Tabs\Nav $block
  */
 ?>
-<div data-role="spinner" data-component="<?php echo $block->getDataScope(); ?>.sections" class="grid-loading-mask">
-    <div class="spinner">
-        <span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span>
-    </div>
-</div>
 <div data-bind="scope: '<?php echo $block->getDataScope(); ?>.sections' " class="ui-tabs">
     <!-- ko template: getTemplate() --><!-- /ko -->
 </div>
diff --git a/app/code/Magento/Ui/view/base/templates/listing/horizontal_grid.phtml b/app/code/Magento/Ui/view/base/templates/listing/horizontal_grid.phtml
deleted file mode 100644
index 32f2356edd984294bd88fc9387e1a8bf7376aee6..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/templates/listing/horizontal_grid.phtml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-?>
-<?php
-/**
- * @var \Magento\Ui\Component\Listing $block
- */
-?>
-<script type="text/x-magento-init">
-{
-    "*": {
-        "Magento_Ui/js/lib/provider":
-                                    <?php echo $block->getRenderContext()
-                                                ->getConfigBuilder()
-                                                ->toJson($block->getRenderContext()->getStorage(), $block->getName());
-                                    ?>,
-        "Magento_Ui/js/listing/grid": <?php echo $block->getConfigBuilder()->toJson($block->getConfig()); ?>
-    }
-}
-</script>
-<?php echo $block->getChildHtml('listing_head'); ?>
-<div class="grid">
-    <?php echo $block->getChildHtml('listing_before'); ?>
-    <div data-bind="scope: '<?php echo $block->getParentName(); ?>:<?php echo $block->getName(); ?>'">
-        <!-- ko template: getTemplate() --><!-- /ko -->
-    </div>
-    <?php echo $block->getChildHtml('listing_after'); ?>
-</div>
-<div data-role="spinner" class="grid-loading-mask">
-    <div class="grid-loader"></div>
-</div>
diff --git a/app/code/Magento/Ui/view/base/templates/listingcontainer/massaction/default.phtml b/app/code/Magento/Ui/view/base/templates/listingcontainer/massaction/default.phtml
deleted file mode 100644
index f0e80904214fb86fad22be517b94e6ef1643b362..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/templates/listingcontainer/massaction/default.phtml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-?>
-<?php
-/**
- * @var \Magento\Ui\Component\MassAction $block
- */
-?>
-<script type="text/x-magento-init">
-    {
-        "*": {
-            "Magento_Ui/js/listing/massaction": <?php echo $block->getConfigBuilder()->toJson($block->getConfig()); ?> 
-        }
-    }
-</script>
-<div data-bind="scope: '<?php echo $block->getParentName(); ?>:<?php echo $block->getName(); ?>'" class="grid-actions">
-    <!-- ko template: 'ui/massaction' --><!-- /ko -->
-</div>
diff --git a/app/code/Magento/Ui/view/base/templates/listingcontainer/massaction/page_actions.phtml b/app/code/Magento/Ui/view/base/templates/listingcontainer/massaction/page_actions.phtml
deleted file mode 100644
index 1bba18bb5ff432a80fd15a98edb53ae1cbed53a3..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/templates/listingcontainer/massaction/page_actions.phtml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-?>
-<?php
-/**
- * @var \Magento\Ui\Component\MassAction $block
- */
-?>
-<script type="text/x-magento-init">
-    {
-        "*": {
-            "Magento_Ui/js/listing/massaction": <?php echo $block->getConfigBuilder()->toJson($block->getConfig()); ?>
-        }
-    }
-</script>
-<div data-bind="scope: '<?php echo $block->getParentName(); ?>:<?php echo $block->getName(); ?>'">
-    <!-- ko template: 'ui/pageactions' --><!-- /ko -->
-</div>
diff --git a/app/code/Magento/Ui/view/base/templates/paging/default.phtml b/app/code/Magento/Ui/view/base/templates/paging/default.phtml
deleted file mode 100644
index 6c710bdf1b15441e91ba811da8951d3166919276..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/templates/paging/default.phtml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-?>
-<?php
-/**
- * @var \Magento\Ui\Component\Paging $block
- */
-?>
-<script type="text/x-magento-init">
-    {
-        "*": {
-            "Magento_Ui/js/listing/paging": <?php echo $block->getConfigBuilder()->toJson($block->getConfig()); ?>
-        }
-    }
-</script>
-<div data-bind="scope: '<?php echo $block->getParentName(); ?>:<?php echo $block->getName(); ?>'" class="pager">
-    <!-- ko template: 'ui/pagination' --><!-- /ko -->
-</div>
diff --git a/app/code/Magento/Ui/view/base/templates/sorting/default.phtml b/app/code/Magento/Ui/view/base/templates/sorting/default.phtml
deleted file mode 100644
index 1b85352c82b4ee8da9e30b2847869a48d187c84a..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/templates/sorting/default.phtml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-?>
-<?php
-/**
- * @var \Magento\Ui\Component\Sorting $block
- */
-
-?>
-<script type="text/x-magento-init">
-    {
-        "*": {
-            "Magento_Ui/js/listing/sorting": <?php echo $block->getConfigBuilder()->toJson($block->getConfig()); ?>
-        }
-    }
-</script>
diff --git a/app/code/Magento/Ui/view/base/ui_component/etc/definition.xml b/app/code/Magento/Ui/view/base/ui_component/etc/definition.xml
new file mode 100644
index 0000000000000000000000000000000000000000..4ebc69d2284abb3514c412081e36b0225781eb0e
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/ui_component/etc/definition.xml
@@ -0,0 +1,225 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<components xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../etc/ui_definition.xsd">
+    <dataSource class="Magento\Ui\Component\DataSource"/>
+    <listing sorting="true" class="Magento\Ui\Component\Listing">
+        <argument name="data" xsi:type="array">
+            <item name="template" xsi:type="string">templates/listing/default</item>
+            <item name="save_parameters_in_session" xsi:type="string">1</item>
+            <item name="client_root" xsi:type="string">mui/index/render</item>
+            <item name="js_config" xsi:type="array">
+                <item name="component" xsi:type="string">uiComponent</item>
+            </item>
+        </argument>
+    </listing>
+    <paging class="Magento\Ui\Component\Paging">
+        <argument name="data" xsi:type="array">
+            <item name="template" xsi:type="string">templates/paging/default</item>
+            <item name="js_config" xsi:type="array">
+                <item name="component" xsi:type="string">Magento_Ui/js/grid/paging</item>
+            </item>
+        </argument>
+    </paging>
+    <filters class="Magento\Ui\Component\Filters">
+        <argument name="data" xsi:type="array">
+            <item name="js_config" xsi:type="array">
+                <item name="component" xsi:type="string">Magento_Ui/js/grid/filters/filters</item>
+            </item>
+        </argument>
+    </filters>
+    <filterSelect class="Magento\Ui\Component\Filters\Type\Select">
+        <argument name="data" xsi:type="array">
+            <item name="config" xsi:type="array">
+                <item name="template" xsi:type="string" translate="true">ui/grid/filters/elements/select</item>
+            </item>
+        </argument>
+    </filterSelect>
+    <filterRange class="Magento\Ui\Component\Filters\Type\Range">
+        <argument name="data" xsi:type="array">
+            <item name="js_config" xsi:type="array">
+                <item name="component" xsi:type="string">Magento_Ui/js/grid/filters/group</item>
+            </item>
+        </argument>
+    </filterRange>
+    <filterInput class="Magento\Ui\Component\Filters\Type\Input">
+        <argument name="data" xsi:type="array">
+            <item name="config" xsi:type="array">
+                <item name="template" xsi:type="string">ui/grid/filters/elements/input</item>
+            </item>
+        </argument>
+    </filterInput>
+    <filterDate class="Magento\Ui\Component\Filters\Type\Date">
+        <argument name="data" xsi:type="array">
+            <item name="config" xsi:type="array">
+                <item name="template" xsi:type="string">ui/grid/filters/elements/date</item>
+            </item>
+        </argument>
+    </filterDate>
+    <container class="Magento\Ui\Component\Container">
+        <argument name="data" xsi:type="array">
+            <item name="js_config" xsi:type="array">
+                <item name="component" xsi:type="string">uiComponent</item>
+            </item>
+        </argument>
+    </container>
+    <massaction class="Magento\Ui\Component\MassAction">
+        <argument name="data" xsi:type="array">
+            <item name="template" xsi:type="string">templates/listingcontainer/massaction/default</item>
+            <item name="js_config" xsi:type="array">
+                <item name="component" xsi:type="string">Magento_Ui/js/grid/massactions</item>
+            </item>
+        </argument>
+    </massaction>
+    <actions class="Magento\Ui\Component\Control\Action">
+        <argument name="data" xsi:type="array">
+            <item name="js_config" xsi:type="array">
+                <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/actions</item>
+            </item>
+        </argument>
+    </actions>
+    <input class="Magento\Ui\Component\Form\Element\Input">
+        <argument name="data" xsi:type="array">
+            <item name="js_config" xsi:type="array">
+                <item name="component" xsi:type="string">Magento_Ui/js/form/element/abstract</item>
+                <item name="config" xsi:type="array">
+                    <item name="template" xsi:type="string">ui/form/field</item>
+                    <item name="elementTmpl" xsi:type="string">ui/form/element/input</item>
+                </item>
+            </item>
+        </argument>
+    </input>
+    <checkbox class="Magento\Ui\Component\Form\Element\Checkbox">
+        <argument name="data" xsi:type="array">
+            <item name="js_config" xsi:type="array">
+                <item name="component" xsi:type="string">Magento_Ui/js/form/element/boolean</item>
+                <item name="config" xsi:type="array">
+                    <item name="elementTmpl" xsi:type="string">ui/form/element/checkbox</item>
+                </item>
+            </item>
+        </argument>
+    </checkbox>
+    <select class="Magento\Ui\Component\Form\Element\Select">
+        <argument name="data" xsi:type="array">
+            <item name="js_config" xsi:type="array">
+                <item name="component" xsi:type="string">Magento_Ui/js/form/element/select</item>
+                <item name="config" xsi:type="array">
+                    <item name="elementTmpl" xsi:type="string">ui/form/element/select</item>
+                </item>
+            </item>
+        </argument>
+    </select>
+    <multiselect class="Magento\Ui\Component\Form\Element\Select">
+        <argument name="data" xsi:type="array">
+            <item name="template" xsi:type="string">ui/form/element/multiselect</item>
+            <item name="js_config" xsi:type="array">
+                <item name="component" xsi:type="string">Magento_Ui/js/form/element/multiselect</item>
+                <item name="config" xsi:type="array">
+                    <item name="elementTmpl" xsi:type="string">ui/form/element/multiselect</item>
+                </item>
+            </item>
+        </argument>
+    </multiselect>
+    <textarea class="Magento\Ui\Component\Form\Element\Textarea">
+        <argument name="data" xsi:type="array">
+            <item name="js_config" xsi:type="array">
+                <item name="component" xsi:type="string">Magento_Ui/js/form/element/textarea</item>
+                <item name="config" xsi:type="array">
+                    <item name="elementTmpl" xsi:type="string">ui/form/element/textarea</item>
+                </item>
+            </item>
+        </argument>
+    </textarea>
+    <text class="Magento\Ui\Component\Form\Element\DataType\Text">
+        <argument name="data" xsi:type="array">
+            <item name="js_config" xsi:type="array">
+                <item name="component" xsi:type="string">Magento_Ui/js/form/element/text</item>
+            </item>
+        </argument>
+    </text>
+    <number class="Magento\Ui\Component\Form\Element\DataType\Number"/>
+    <price class="Magento\Ui\Component\Form\Element\DataType\Price"/>
+    <media class="Magento\Ui\Component\Form\Element\DataType\Media">
+        <argument name="data" xsi:type="array">
+            <item name="js_config" xsi:type="array">
+                <item name="extends" xsi:type="string">input</item>
+            </item>
+        </argument>
+    </media>
+    <date class="Magento\Ui\Component\Form\Element\DataType\Date">
+        <argument name="data" xsi:type="array">
+            <item name="js_config" xsi:type="array">
+                <item name="extends" xsi:type="string">input</item>
+                <item name="component" xsi:type="string">Magento_Ui/js/form/element/date</item>
+                <item name="config" xsi:type="array">
+                    <item name="elementTmpl" xsi:type="string">ui/form/element/date</item>
+                </item>
+            </item>
+        </argument>
+    </date>
+    <boolean class="Magento\Ui\Component\Form\Element\DataType\Boolean">
+        <argument name="data" xsi:type="array">
+            <item name="js_config" xsi:type="array">
+                <item name="extends" xsi:type="string">input</item>
+            </item>
+        </argument>
+    </boolean>
+    <email class="Magento\Ui\Component\Form\Element\DataType\Email">
+        <argument name="data" xsi:type="array">
+            <item name="js_config" xsi:type="array">
+                <item name="extends" xsi:type="string">input</item>
+                <item name="config" xsi:type="array">
+                    <item name="elementTmpl" xsi:type="string">ui/form/element/email</item>
+                </item>
+            </item>
+            <item name="config" xsi:type="array">
+                <item name="addbefore" xsi:type="string">@email:</item>
+            </item>
+        </argument>
+    </email>
+    <columns class="Magento\Ui\Component\Listing\Columns">
+        <argument name="data" xsi:type="array">
+            <item name="js_config" xsi:type="array">
+                <item name="component" xsi:type="string">Magento_Ui/js/grid/listing</item>
+            </item>
+        </argument>
+    </columns>
+    <column class="Magento\Ui\Component\Listing\Columns\Column"/>
+    <form class="Magento\Ui\Component\Form">
+        <argument name="data" xsi:type="array">
+            <item name="js_config" xsi:type="array">
+                <item name="component" xsi:type="string">Magento_Ui/js/form/form</item>
+            </item>
+            <item name="template" xsi:type="string">templates/form/default</item>
+        </argument>
+    </form>
+    <fieldset class="Magento\Ui\Component\Form\Fieldset">
+        <argument name="data" xsi:type="array">
+            <item name="js_config" xsi:type="array">
+                <item name="component" xsi:type="string">Magento_Ui/js/form/components/fieldset</item>
+            </item>
+        </argument>
+    </fieldset>
+    <field class="Magento\Ui\Component\Form\Field"/>
+    <tab class="Magento\Ui\Component\Layout\Tabs\Tab">
+        <argument name="data" xsi:type="array">
+            <item name="template" xsi:type="string">templates/layout/tabs/tab/default</item>
+            <item name="js_config" xsi:type="array">
+                <item name="component" xsi:type="string">Magento_Ui/js/form/components/area</item>
+            </item>
+        </argument>
+    </tab>
+    <!-- navigation -->
+    <nav class="Magento\Ui\Component\Layout\Tabs\Nav">
+        <argument name="data" xsi:type="array">
+            <item name="template" xsi:type="string">ui/tab</item>
+            <item name="js_config" xsi:type="array">
+                <item name="component" xsi:type="string">Magento_Ui/js/form/components/tab_group</item>
+            </item>
+        </argument>
+    </nav>
+</components>
diff --git a/app/code/Magento/Ui/view/base/ui_component/templates/form/default.xhtml b/app/code/Magento/Ui/view/base/ui_component/templates/form/default.xhtml
new file mode 100644
index 0000000000000000000000000000000000000000..a27dc54abfbf6c5e5faab7ddd31e8834e8705051
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/ui_component/templates/form/default.xhtml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<div xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../Ui/etc/ui_template.xsd">
+    <div data-role="spinner" data-component="{{getName()}}.areas" class="admin__data-grid-loading-mask">
+        <div class="grid-loader"></div>
+    </div>
+    <div data-bind="scope: '{{getName()}}.areas'" class="entry-edit form-inline">
+        <!-- ko template: getTemplate() --><!-- /ko -->
+    </div>
+</div>
diff --git a/app/code/Magento/Ui/view/base/ui_component/templates/listing/default.xhtml b/app/code/Magento/Ui/view/base/ui_component/templates/listing/default.xhtml
new file mode 100644
index 0000000000000000000000000000000000000000..c56eea763192e5ce99fa92bc376ea3a33d5f7b5d
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/ui_component/templates/listing/default.xhtml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<div data-bind="scope: '{{getName()}}.{{getName()}}'" class="admin__data-grid-wrap"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../Ui/etc/ui_template.xsd">
+    <div data-role="spinner" data-component="{{getName()}}.{{getName()}}.{{spinner}}" class="admin__data-grid-loading-mask">
+        <div class="grid-loader"></div>
+    </div>
+    <!-- ko template: getTemplate() --><!-- /ko -->
+</div>
diff --git a/app/code/Magento/Ui/view/base/web/js/core/app.js b/app/code/Magento/Ui/view/base/web/js/core/app.js
index 9e8f5be7e0165a310b5f7a0406d1717beb7dd5c9..5c4593bd486a312ecc1233c2a4cc2940d2025817 100644
--- a/app/code/Magento/Ui/view/base/web/js/core/app.js
+++ b/app/code/Magento/Ui/view/base/web/js/core/app.js
@@ -3,46 +3,13 @@
  * See COPYING.txt for license details.
  */
 define([
-    'underscore',
-    './renderer/renderer',
-    'Magento_Ui/js/lib/registry/registry'
-], function (_, Renderer, registry) {
+    './renderer/types',
+    './renderer/layout'
+], function (types, layout) {
     'use strict';
 
-    function load(config, name){
-        require([config.path], function(constr){
-            registry.set(name, new constr(config));
-        });
-    }
-
-    var global = {
-        init: function(data){
-            this.data = {};
-
-            this.register()
-                .initRenderer(data.renderer)
-                .initProviders(data.providers)
-                .register();
-        },
-
-        initRenderer: function(data){
-            this.renderer = new Renderer(data);
-
-            return this;
-        },
-        
-        initProviders: function(providers){
-            _.each(providers, load);  
-
-            return this; 
-        },
-
-        register: function () {
-            registry.set('globalStorage', this);
-
-            return this;
-        }
+    return function (data) {
+        types.set(data.types);
+        layout(data.components);
     };
-
-    return global.init.bind(global);
-});
\ No newline at end of file
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/core/renderer/components/layout.js b/app/code/Magento/Ui/view/base/web/js/core/renderer/components/layout.js
deleted file mode 100644
index 6866bf0d0e644900b44834d5e061bd066da6bb0b..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/js/core/renderer/components/layout.js
+++ /dev/null
@@ -1,241 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-define([
-    'underscore',
-    'jquery',
-    'mage/utils',
-    'Magento_Ui/js/lib/class',
-    'Magento_Ui/js/lib/registry/registry'
-], function(_, $, utils, Class, registry) {
-    'use strict';
-
-    function getNodeName(parent, node, name) {
-        var parentName = parent && parent.name;
-
-        if (typeof name !== 'string') {
-            name = node.name || name;
-        }
-
-        if (parentName) {
-            name = parentName + '.' + name;
-        }
-
-        return name;
-    }
-
-    function getNodeType(parent, node){
-        return node.type || (parent && parent.childType);
-    }
-
-    function getDataScope(parent, node){
-        var dataScope   = node.dataScope,
-            parentScope = parent && parent.dataScope;
-
-        return notEmpty(parentScope) ?
-                ( notEmpty(dataScope) ?
-                    (parentScope + '.' + dataScope) :
-                    parentScope ) :
-                (dataScope || '');
-    }
-
-    function notEmpty(value){
-        return !_.isUndefined(value) && value !== '';
-    }
-
-    function mergeNode(node, config){
-        return $.extend(true, {}, config, node);
-    }
-
-    function additional(node){
-        return _.pick(node, 'name', 'index', 'dataScope');
-    }
-
-    function loadDeps(node){
-        var loaded = $.Deferred();
-
-        registry.get(node.deps, function(){
-            loaded.resolve(node);
-        });
-
-        return loaded.promise();
-    }
-
-    function loadSource(node){
-        var loaded = $.Deferred(),
-            source = node.component;
-
-        require([source], function(constr){
-            loaded.resolve(node, constr);
-        });
-
-        return loaded.promise();
-    }
-
-    function initComponent(node, constr){
-        var component = new constr(
-            node.config,
-            additional(node)
-        );
-
-        registry.set(node.name, component);
-    }
-
-    function Layout(nodes, types){
-        this.types      = types;
-        this.registry   = registry.create();
-
-        this.run(nodes);
-    }
-
-    _.extend(Layout.prototype, {
-        run: function(nodes, parent){
-            _.each(nodes || [], this.iterator.bind(this, parent));
-
-            return this;
-        },
-
-        iterator: function(parent, node, name){
-            var action = _.isString(node) ?
-                this.addChild :
-                this.process;
-
-            action.apply(this, arguments);
-        },
-
-        process: function(parent, node, name) {
-            if(!parent && node.parent){
-                return this.waitParent(node, name);
-            }
-
-            if(node.template){
-                return this.waitTemplate.apply(this, arguments);      
-            }
-
-            node = this.build.apply(this, arguments);
-
-            if(node){
-                this.addChild(parent, node.name)
-                    .manipulate(node)
-                    .initComponent(node)
-                    .run(node.children, node);
-            }
-
-            return this;
-        },
-
-        build: function(parent, node, name){
-            var type;
-
-            type = getNodeType.apply(null, arguments);
-            node = mergeNode(node, this.types.get(type));
-
-            node.index      = node.name || name;
-            node.name       = getNodeName(parent, node, name);
-            node.dataScope  = getDataScope(parent, node);
-
-            delete node.type;
-
-            this.registry.set(node.name, node);
-
-            return node.isTemplate ?
-                (node.isTemplate = false) :
-                node;
-        },
-
-        initComponent: function(node){
-            if(!node.component){
-                return this;
-            }
-
-            loadDeps(node)
-                .then(loadSource)
-                .done(initComponent);
-
-            return this;
-        }
-    });
-        
-    _.extend(Layout.prototype, {
-        waitTemplate: function(parent, node, name){
-            var args = _.toArray(arguments);
-
-            this.registry.get(node.template, function(){
-                this.applyTemplate.apply(this, args);
-            }.bind(this));
-
-            return this;
-        },
-
-        waitParent: function(node, name){
-            var process = this.process.bind(this);
-
-            this.registry.get(node.parent, function(parent){
-                process(parent, node, name);
-            });
-
-            return this;
-        },
-
-        applyTemplate: function(parent, node, name){
-            var template = this.registry.get(node.template);
-            
-            node = mergeNode(node, template);
-
-            delete node.template;
-
-            this.process(parent, node, name);
-        }
-    });
-
-    _.extend(Layout.prototype, {
-        manipulate: function(node) {
-            var name = node.name;
-
-            if (node.appendTo) {
-                this.insert(name, node.appendTo, -1);
-            }
-
-            if (node.prependTo) {
-                this.insert(name, node.prependTo, 0);
-            }
-
-            if(node.insertTo){
-                this.insertTo(name, node.insertTo);
-            }
-
-            return this;
-        },
-
-        insert: function(item, target, position){
-            registry.get(target, function(target){            
-                target.insert(item, position);
-            });
-
-            return this;
-        },
-
-        insertTo: function(item, targets){
-            _.each(targets, function(info, target){
-                this.insert(item, target, info.position);
-            }, this);
-
-            return this;
-        },
-
-        addChild: function(parent, child){
-            if(parent && parent.component){
-                this.insert(child, parent.name);
-            }
-
-            return this;
-        },
-
-        clear: function(name){
-            this.registry.remove(name);
-        }
-    });
-
-    return Layout;
-});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/core/renderer/components/types.js b/app/code/Magento/Ui/view/base/web/js/core/renderer/components/types.js
deleted file mode 100644
index 461bd8332cfd43a8ac96b4caf3c11acfcd19daf5..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/js/core/renderer/components/types.js
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-define([
-    'underscore',
-    'jquery',
-    'mage/utils',
-    'Magento_Ui/js/lib/class',
-    'Magento_Ui/js/lib/registry/registry'
-], function(_, $, utils, Class, registry) {
-    'use strict';
-
-    return Class.extend({
-        initialize: function(types){
-            this.types = {};
-
-            this.set(types);
-
-            return this;
-        },
-
-        set: function(types){
-            types = types || [];
-            
-            _.each(types, function(data, type){
-                this.types[type] = this.flatten(data);
-            }, this);
-        },
-
-        get: function(type){
-            return this.types[type] || {};
-        },
-
-        flatten: function(data){
-            var extender = data.extends || [],
-                result   = {};
-
-            extender = utils.stringToArray(extender);
-
-            extender.push(data);
-
-            extender.forEach(function(item){
-                if(_.isString(item)){
-                    item = this.get(item);
-                }
-
-                $.extend(true, result, item);
-            }, this);
-
-            delete result.extends;
-
-            return result
-        }
-    });
-});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/core/renderer/layout.js b/app/code/Magento/Ui/view/base/web/js/core/renderer/layout.js
new file mode 100644
index 0000000000000000000000000000000000000000..aac43507a35b6725c750624d7635461f88d89763
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/core/renderer/layout.js
@@ -0,0 +1,230 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+    'underscore',
+    'jquery',
+    'mageUtils',
+    'uiRegistry',
+    './types'
+], function (_, $, utils, registry, types) {
+    'use strict';
+
+    var templates = registry.create(),
+        layout = {};
+
+    function getNodeName(parent, node, name) {
+        var parentName = parent && parent.name;
+
+        if (typeof name !== 'string') {
+            name = node.name || name;
+        }
+
+        return utils.fullPath(parentName, name);
+    }
+
+    function getNodeType(parent, node) {
+        return node.type || parent && parent.childType;
+    }
+
+    function getDataScope(parent, node) {
+        var dataScope = node.dataScope,
+            parentScope = parent && parent.dataScope;
+
+        return !utils.isEmpty(parentScope) ?
+            !utils.isEmpty(dataScope) ?
+                parentScope + '.' + dataScope :
+                parentScope :
+            dataScope || '';
+    }
+
+    function loadDeps(node) {
+        var loaded = $.Deferred();
+
+        registry.get(node.deps, function () {
+            loaded.resolve(node);
+        });
+
+        return loaded.promise();
+    }
+
+    function loadSource(node) {
+        var loaded = $.Deferred(),
+            source = node.component;
+
+        require([source], function (constr) {
+            loaded.resolve(node, constr);
+        });
+
+        return loaded.promise();
+    }
+
+    function initComponent(node, Constr) {
+        var component = new Constr(_.omit(node, 'children'));
+
+        registry.set(node.name, component);
+    }
+
+    function run(nodes, parent) {
+        _.each(nodes || [], layout.iterator.bind(layout, parent));
+    }
+
+    _.extend(layout, {
+        iterator: function (parent, node) {
+            var action = _.isString(node) ?
+                this.addChild :
+                this.process;
+
+            action.apply(this, arguments);
+        },
+
+        process: function (parent, node, name) {
+            if (!parent && node.parent) {
+                return this.waitParent(node, name);
+            }
+
+            if (node.template) {
+                return this.waitTemplate.apply(this, arguments);
+            }
+
+            node = this.build.apply(this, arguments);
+
+            if (node) {
+                this.addChild(parent, node)
+                    .manipulate(node)
+                    .initComponent(node);
+
+                run(node.children, node);
+            }
+
+            return this;
+        },
+
+        build: function (parent, node, name) {
+            var defaults = parent && parent.childDefaults || {},
+                children = node.children,
+                type = getNodeType(parent, node);
+
+            node.children = false;
+
+            node = utils.extend({
+            }, types.get(type), defaults, node);
+
+            _.extend(node, node.config || {}, {
+                index: node.name || name,
+                name: getNodeName(parent, node, name),
+                dataScope: getDataScope(parent, node)
+            });
+
+            node.children = children;
+
+            delete node.type;
+            delete node.config;
+
+            if (node.isTemplate) {
+                node.isTemplate = false;
+
+                templates.set(node.name, node);
+
+                return false;
+            }
+
+            return node;
+        },
+
+        initComponent: function (node) {
+            if (!node.component) {
+                return this;
+            }
+
+            loadDeps(node)
+                .then(loadSource)
+                .done(initComponent);
+
+            return this;
+        }
+    });
+
+    _.extend(layout, {
+        waitTemplate: function (parent, node) {
+            var args = _.toArray(arguments);
+
+            templates.get(node.template, function () {
+                this.applyTemplate.apply(this, args);
+            }.bind(this));
+
+            return this;
+        },
+
+        waitParent: function (node, name) {
+            var process = this.process.bind(this);
+
+            registry.get(node.parent, function (parent) {
+                process(parent, node, name);
+            });
+
+            return this;
+        },
+
+        applyTemplate: function (parent, node, name) {
+            var template = templates.get(node.template);
+
+            node = utils.extend({}, template, node);
+
+            delete node.template;
+
+            this.process(parent, node, name);
+        }
+    });
+
+    _.extend(layout, {
+        manipulate: function (node) {
+            var name = node.name;
+
+            if (node.appendTo) {
+                this.insert(name, node.appendTo, -1);
+            }
+
+            if (node.prependTo) {
+                this.insert(name, node.prependTo, 0);
+            }
+
+            if (node.insertTo) {
+                this.insertTo(name, node.insertTo);
+            }
+
+            return this;
+        },
+
+        insert: function (item, target, position) {
+            registry.get(target, function (container) {
+                container.insert(item, position);
+            });
+
+            return this;
+        },
+
+        insertTo: function (item, targets) {
+            _.each(targets, function (info, target) {
+                this.insert(item, target, info.position);
+            }, this);
+
+            return this;
+        },
+
+        addChild: function (parent, child) {
+            var name;
+
+            if (parent && parent.component) {
+                name = child.name || child;
+
+                this.insert(name, parent.name, child.sortOrder);
+            }
+
+            return this;
+        }
+    });
+
+    return run;
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/core/renderer/renderer.js b/app/code/Magento/Ui/view/base/web/js/core/renderer/renderer.js
deleted file mode 100644
index 5b7de47144ebb0ca7da594aa157c507540f2c0c9..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/js/core/renderer/renderer.js
+++ /dev/null
@@ -1,25 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-define([
-    './components/types',
-    './components/layout',
-    'Magento_Ui/js/lib/class'
-], function(Types, Layout, Class){
-    'use strict';
-
-    return Class.extend({
-        initialize: function(data){
-            this.types = new Types(data.types);
-            this.layout = new Layout(data.layout, this.types);
-
-            return this;
-        },
-
-        render: function(data){
-            this.layout.run(data.layout);
-            this.types.set(data.types);
-        }
-    });
-});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/core/renderer/types.js b/app/code/Magento/Ui/view/base/web/js/core/renderer/types.js
new file mode 100644
index 0000000000000000000000000000000000000000..2975abbcdbe3bc86b3edcd1938735fd9b20cc0d3
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/core/renderer/types.js
@@ -0,0 +1,49 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+    'underscore',
+    'mageUtils'
+], function (_, utils) {
+    'use strict';
+
+    var store = {};
+
+    function flatten(data) {
+        var extender = data.extends || [],
+            result = {};
+
+        extender = utils.stringToArray(extender);
+
+        extender.push(data);
+
+        extender.forEach(function (item) {
+            if (_.isString(item)) {
+                item = store[item] || {};
+            }
+
+            utils.extend(result, item);
+        });
+
+        delete result.extends;
+
+        return result;
+    }
+
+    return {
+        set: function (types) {
+            types = types || {};
+
+            utils.extend(store, types);
+
+            _.each(types, function (data, type) {
+                store[type] = flatten(data);
+            });
+        },
+
+        get: function (type) {
+            return store[type] || {};
+        }
+    };
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/form.js b/app/code/Magento/Ui/view/base/web/js/form.js
deleted file mode 100644
index ef54b43da90399b6894c697e2f49cb46795af55a..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/js/form.js
+++ /dev/null
@@ -1,100 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-define([
-    'jquery',
-    'underscore',
-    'Magento_Ui/js/form/component',
-    'Magento_Ui/js/lib/spinner',
-    './form/adapter'
-], function ($, _, Component, loader, adapter) {
-    'use strict';
-
-    function collectData(selector) {
-        var data = $(selector).serializeArray(),
-            result = {};
-
-        data.forEach(function (item) {
-            result[item.name] = item.value;
-        });
-
-        return result;
-    }
-
-    return Component.extend({
-
-        initialize: function(){
-            this._super()
-                .initAdapter()
-                .initSelector()
-                .hideLoader();
-
-            return this;
-        },
-
-        initAdapter: function(){
-            adapter.on({
-                'reset':            this.reset.bind(this),
-                'save':             this.save.bind(this, true),
-                'saveAndContinue':  this.save.bind(this, false)
-            });
-
-            return this;
-        },
-        
-        initSelector: function(){
-            this.selector = '[data-form-part='+ this.namespace +']';
-
-            return this;
-        },
-
-        hideLoader: function () {
-            loader.get(this.name).hide();
-
-            return this;
-        },
-
-        save: function(redirect){
-            var params = this.provider.params;
-
-            this.validate();
-
-            if (!params.get('invalid')) {
-                this.submit(redirect);
-            }
-        },
-
-        /**
-         * Submits form
-         */
-        submit: function (redirect) {
-            var additional  = collectData(this.selector),
-                provider    = this.provider;
-
-            _.each(additional, function(value, name){
-                provider.data.set(name, value);
-            });
-
-            provider.save({
-                redirect: redirect
-            });
-        },
-
-        /**
-         * Validates each element and returns true, if all elements are valid.
-         */
-        validate: function () {
-            var provider = this.provider;
-
-            provider.params.set('invalid', false);
-            provider.data.trigger('validate');
-        },
-
-        reset: function(){
-            var data = this.provider.data;
-
-            data.trigger('reset');
-        }
-    });
-});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/form/client.js b/app/code/Magento/Ui/view/base/web/js/form/client.js
index 4526c775a39f69a51f1b93ac16d92153aff0182c..c8750c3129530719b24d7d8f3d8b4c4fc11b705e 100644
--- a/app/code/Magento/Ui/view/base/web/js/form/client.js
+++ b/app/code/Magento/Ui/view/base/web/js/form/client.js
@@ -5,21 +5,19 @@
 define([
     'jquery',
     'underscore',
-    'mage/utils',
+    'mageUtils',
     'Magento_Ui/js/lib/class'
-], function($, _, utils, Class){
+], function ($, _, utils, Class) {
     'use strict';
-    
-    var defaults = {};
 
-    function beforeSave(data, url){
+    function beforeSave(data, url) {
         var save = $.Deferred();
-        
+
         data = utils.serialize(data);
 
         data.form_key = FORM_KEY;
-        
-        if(!url){
+
+        if (!url) {
             save.resolve();
         }
 
@@ -28,12 +26,12 @@ define([
         $.ajax({
             url: url,
             data: data,
-            success: function(resp){
-                if(!resp.error){
+            success: function (resp) {
+                if (!resp.error) {
                     save.resolve();
                 }
             },
-            complete: function(){
+            complete: function () {
                 $('body').trigger('processStop');
             }
         });
@@ -46,8 +44,8 @@ define([
          * Initializes DataProvider instance.
          * @param {Object} settings - Settings to initialize object with.
          */
-        initialize: function(config) {
-            _.extend(this, defaults, config);
+        initialize: function (config) {
+            _.extend(this, config);
 
             return this;
         },
@@ -55,32 +53,32 @@ define([
         /**
          * Assembles data and submits it using 'utils.submit' method
          */
-        save: function(data, options){
-            var url     = this.urls.beforeSave,
-                save    = this._save.bind(this, data, options);
+        save: function (data, options) {
+            var url = this.urls.beforeSave,
+                save = this._save.bind(this, data, options);
 
             beforeSave(data, url).then(save);
 
             return this;
         },
 
-        _save: function(data, options){
+        _save: function (data, options) {
             var url = this.urls.save;
 
             options = options || {};
 
             data.form_key = FORM_KEY;
 
-            if(!options.redirect){
+            if (!options.redirect) {
                 url += 'back/edit';
             }
 
             utils.submit({
-                url:    url,
-                data:   data
+                url: url,
+                data: data
             });
 
             return this;
         }
     });
-});
\ No newline at end of file
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/form/component.js b/app/code/Magento/Ui/view/base/web/js/form/component.js
deleted file mode 100644
index 5b207bfc22205f174d739688231dd187caa24fcd..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/js/form/component.js
+++ /dev/null
@@ -1,473 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-define([
-    'underscore',
-    'mage/utils',
-    'Magento_Ui/js/lib/ko/scope',
-    'Magento_Ui/js/lib/events',
-    'Magento_Ui/js/lib/registry/registry'
-], function(_, utils, Scope, EventsBus, registry) {
-    'use strict';
-
-    function getOffsetFor(elems, offset){
-        if(typeof offset === 'undefined'){
-            offset = -1;
-        }
-
-        if(offset < 0){
-            offset += elems.length + 1;
-        }
-
-        return offset;
-    }
-
-    function getProxy(callback, data){
-        if(_.isArray(data)){
-            data = {
-                additional: data
-            }
-        }
-
-        _.defaults(data, {
-            conditions: '*',
-            additional: [],
-            callback: callback
-        });
-
-        return proxy.bind(null, data);
-    }
-
-    function proxy(data, value){
-        var conditions = data.conditions,
-            args;
-
-        if(conditions === value || conditions === '*'){
-            args = data.additional.slice();
-
-            args.push(value);
-
-            data.callback.apply(null, args);
-        }
-    }
-
-    function parseSource(source, storages, data){
-        var storage;
-
-        source  = utils.template(source, data);
-        source  = source.split(':');
-
-        storage = source.shift();
-
-        return {
-            source: source[0],
-            storage: storages[storage]
-        }
-    }
-
-    var Component = Scope.extend({
-        initialize: function(config, additional){
-            _.extend(this, config, additional);
-
-            _.bindAll(this, '_insert');
-
-            this.initProperties()
-                .initObservable()
-                .initListeners()
-                .initUnique();
-
-            return this;
-        },
-
-        /**
-         * Defines various properties.
-         *
-         * @returns {Component} Chainable.
-         */
-        initProperties: function () {
-            _.extend(this,{
-                'parentName':   this.getPart(this.name, -2),
-                'parentScope':  this.getPart(this.dataScope, -2),
-                'provider':     registry.get(this.provider),
-                'renderer':     registry.get('globalStorage').renderer,
-                'containers':   [],
-                'regions':      [],
-                '_elems':       []
-            });
-
-            return this;
-        },
-
-        /**
-         * Initializes observable properties.
-         *
-         * @returns {Component} Chainable.
-         */
-        initObservable: function(){
-            this.observe({
-                'elems': []
-            });
-
-            this.regions.forEach(function(region){
-                this.observe(region, []);
-            }, this);
-
-            return this;
-        },
-
-        /**
-         * Initializes storages listeners.
-         *
-         * @returns {Component} Chainable.
-         */
-        initListeners: function(){
-            var listeners = this.listeners || {},
-                params,
-                iterator;
-
-            _.each(listeners, function(handlers, source){
-                params   = parseSource(source, this.provider, this);
-                iterator = this.initListener.bind(this, params);
-
-                _.each(handlers, iterator);
-            }, this);
-
-            return this;
-        },
-
-        /**
-         * Initializes listeners of the unique property.
-         *
-         * @returns {Component} Chainable.
-         */
-        initUnique: function(){
-            var update   = this.onUniqueUpdate.bind(this),
-                params   = this.provider.params,
-                uniqueNs = this.uniqueNs;
-            
-            this.hasUnique = this.uniqueProp && uniqueNs;
-
-            if(this.hasUnique){
-                params.on('update:' + uniqueNs, update, this.name);
-            }
-
-            return this;
-        },
-
-        /**
-         * Used as iterator for the listeners object.
-         * Creates callbacks and assigns it to the specified storage.
-         *
-         * @param {Object} data -
-                Data object that contains storage object and
-                it's property name that should be listened.
-         * @param {Object} params - Parameters of the callback. 
-         * @param {String} callback - Callback's name.
-         */
-        initListener: function(data, params, callback){
-            var storage = data.storage,
-                source  = data.source;
-
-            callback = this[callback].bind(this);
-            callback = getProxy(callback, params);
-
-            callback(storage.get(source));
-
-            storage.on('update:' + source, callback, this.name);
-        },
-
-        /**
-         * Called when current element was injected to another component.
-         *
-         * @param {Object} parent - Instance of a 'parent' component.
-         * @returns {Component} Chainable.
-         */
-        initContainer: function(parent){
-            this.containers.push(parent);
-
-            return this;
-        },
-
-        /**
-         * Called when another element was added to current component.
-         *
-         * @param {Object} elem - Instance of an element that was added.
-         * @returns {Component} Chainable.
-         */
-        initElement: function(elem){
-            elem.initContainer(this);
-
-            return this;
-        },
-
-        /**
-         * Splits incoming string and returns its' part specified by offset.
-         *
-         * @param {String} parts
-         * @param {Number} [offset] 
-         * @param {String} [delimiter=.]
-         * @returns {String}
-         */
-        getPart: function(parts, offset, delimiter){
-            delimiter   = delimiter || '.';
-            parts       = parts.split(delimiter);
-            offset      = getOffsetFor(parts, offset);
-
-            parts.splice(offset, 1);
-            
-            return parts.join(delimiter) || '';
-        },
-
-        /**
-         * Returns path to components' template.
-         * @returns {String}
-         */
-        getTemplate: function(){
-            return this.template || 'ui/collection';
-        },
-
-        /**
-         * Updates property specified in uniqueNs
-         * if components' unique property is set to 'true'.
-         *
-         * @returns {Component} Chainable.
-         */
-        setUnique: function () {
-            var params  = this.provider.params,
-                property = this.uniqueProp;
-
-            if (this[property]()) {
-                params.set(this.uniqueNs, this.name);    
-            }
-
-            return this;
-        },
-
-        /**
-         * Callback which fires when property under uniqueNs has changed.
-         */
-        onUniqueUpdate: function(name){
-            var active   = name === this.name,
-                property = this.uniqueProp;
-
-            this[property](active);
-        }
-    }, EventsBus);
-    
-
-    /**
-     * Elements manipulation methods.
-     */
-    _.extend(Component.prototype, {
-        /**
-         * Requests specified components to insert
-         * them into 'elems' array starting from provided position.
-         *
-         * @param {String} elem - Name of the component to insert.
-         * @param {Number} [offset=-1] - Position at which to insert elements.
-         * @returns {Component} Chainable.
-         */
-        insert: function(elem, offset){
-            var _elems  = this._elems,
-                insert  = this._insert;
-            
-            offset = getOffsetFor(_elems, offset);
-
-            _elems.splice(offset, 0, false);
-
-            registry.get(elem, function(elem){
-                insert(elem, offset);
-            });
-
-            return this;
-        },
-
-        /**
-         * Removes specified element from the 'elems' array.
-         *
-         * @param {Object} elem - Element to be removed.
-         * @returns {Component} Chainable.
-         */
-        remove: function(elem) {
-            utils.remove(this._elems, elem);
-            this._update();
-
-            return this;
-        },
-
-        /**
-         * Destroys current instance along with all of its' children.
-         */
-        destroy: function(){
-            this._dropHandlers()
-                ._clearData()
-                ._clearRefs();
-        },
-
-        /**
-         * Removes events listeners.
-         * @private
-         *
-         * @returns {Component} Chainable.      
-         */
-        _dropHandlers: function(){
-            var provider = this.provider;
-
-            this.off();
-            
-            provider.data.off(this.name);
-            provider.params.off(this.name);
-
-            return this;
-        },
-
-        /**
-         * Clears all data associated with component.
-         * @private
-         *
-         * @returns {Component} Chainable.      
-         */
-        _clearData: function(){
-            var provider = this.provider,
-                layout   = this.renderer.layout;
-
-            provider.data.remove(this.dataScope);
-            provider.params.remove(this.name);
-
-            layout.clear(this.name);
-
-            return this;
-        },
-
-        /**
-         * Removes all references to current instance and
-         * calls 'destroy' method on all of its' children.
-         * @private
-         *
-         * @returns {Component} Chainable.      
-         */
-        _clearRefs: function(){
-            registry.remove(this.name);
-
-            this.containers.forEach(function(parent){
-                parent.remove(this);
-            }, this);
-            
-            this.elems().forEach(function(child){ 
-                child.destroy();
-            });
-
-            return this;
-        },
-
-        /**
-         * Inserts provided component into 'elems' array at a specified position.
-         * @private
-         *
-         * @param {Object} elem - Element to insert.
-         * @param {Number} index - Position of the element.
-         */
-        _insert: function(elem, index){            
-            this._elems[index] = elem;
-                
-            this._update()
-                .initElement(elem);
-        },
-
-        /**
-         * Synchronizes multiple elements arrays with a core '_elems' container.
-         * Performs elemets grouping by theirs 'displayArea' property.
-         * @private
-         *
-         * @returns {Component} Chainable.
-         */
-        _update: function(){
-            var _elems  = _.compact(this._elems),
-                grouped = _.groupBy(_elems, 'displayArea'),
-                group;
-
-            this.regions.forEach(function(region) {
-                if ((group = grouped[region])) {
-                    this[region](group);
-                }
-            }, this);
-
-            this.elems(_elems);
-
-            return this;
-        },
-    });
-
-
-    /**
-     * Elements traversing methods.
-     */
-    _.extend(Component.prototype, {
-        /**
-         * Tries to call specified method of a current component,
-         * otherwise delegates attempt to its' children.
-         *
-         * @param {String} target - Name of the method.
-         * @param [...] Arguments that will be passed to method.
-         * @returns {*} Result of the method calls. 
-         */
-        delegate: function(target){
-            var args = _.toArray(arguments);
-
-            target = this[target];
-
-            if(_.isFunction(target)){
-                return target.apply(this, args.slice(1));   
-            }
-
-            return this._delegate(args);
-        },
-
-        /**
-         * Calls 'delegate' method of all of it's children components.
-         * @private
-         *
-         * @param {Array} args - An array of arguments to pass to the next delegation call.
-         * @returns {Array} An array of delegation resutls.
-         */
-        _delegate: function(args){
-            var result;
-
-            result = this.elems.map(function(elem){
-                return elem.delegate.apply(elem, args);
-            });
-
-            return _.flatten(result);
-        },
-
-        /**
-         * Overrides 'EventsBus.trigger' method to implement events bubbling.
-         *
-         * @param {String} name - Name of the event.
-         * @param [...] Any number of arguments that should be to the events' handler.
-         * @returns {Boolean} False if event bubbling was canceled.
-         */
-        trigger: function(){
-            var args    = _.toArray(arguments),
-                bubble  = EventsBus.trigger.apply(this, args),
-                result;
-
-            if(!bubble){
-                return false; 
-            }
-
-            this.containers.forEach(function(parent) {
-                result = parent.trigger.apply(parent, args);
-
-                if (result === false) {
-                    bubble = false;
-                }
-            });
-
-            return !!bubble;
-        }
-    });
-
-    return Component;
-});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/form/components/area.js b/app/code/Magento/Ui/view/base/web/js/form/components/area.js
index 387260f10e1b0bca802a1965641edb123e77c1b4..b9d2884597e2c30884226894c3d44e4f194c6918 100644
--- a/app/code/Magento/Ui/view/base/web/js/form/components/area.js
+++ b/app/code/Magento/Ui/view/base/web/js/form/components/area.js
@@ -5,12 +5,12 @@
 define([
     'underscore',
     './tab'
-], function(_, Tab) {
+], function (_, Tab) {
     'use strict';
 
     return Tab.extend({
         defaults: {
-            uniqueNs:   'activeArea',
+            uniqueNs:   'params.activeArea',
             template:   'ui/area',
             changed:    false,
             loading:    false
@@ -20,7 +20,7 @@ define([
          * Extends instance with defaults. Invokes parent initialize method.
          * Calls initListeners and pushParams methods.
          */
-        initialize: function() {
+        initialize: function () {
             _.bindAll(this, 'onChildrenUpdate', 'onContentLoading', 'onContentLoaded');
 
             return this._super();
@@ -31,7 +31,7 @@ define([
          * Defines observable properties of instance.
          * @return {Object} - reference to instance
          */
-        initObservable: function() {
+        initObservable: function () {
             this._super()
                 .observe('changed loading');
 
@@ -44,7 +44,7 @@ define([
          * @param  {Object} elem
          * @return {Object} - reference to instance
          */
-        initElement: function(elem){
+        initElement: function (elem) {
             this._super();
 
             elem.on({
@@ -61,11 +61,11 @@ define([
          * Sets changed property to one incoming.
          * Invokes setActive method if settings
          * contain makeVisible property set to true.
-         * 
-         * @param  {Boolean} changed
+         *
+         * @param  {Boolean} hasChanged
          */
-        onChildrenUpdate: function(hasChanged){
-            if(!hasChanged){
+        onChildrenUpdate: function (hasChanged) {
+            if (!hasChanged) {
                 hasChanged = _.some(this.delegate('hasChanged'));
             }
 
@@ -75,15 +75,15 @@ define([
         /**
          * Callback that sets loading property to true.
          */
-        onContentLoading: function(){
+        onContentLoading: function () {
             this.loading(true);
         },
 
         /**
          * Callback that sets loading property to true.
          */
-        onContentLoaded: function(){
+        onContentLoaded: function () {
             this.loading(false);
         }
     });
-});
\ No newline at end of file
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/form/components/collection.js b/app/code/Magento/Ui/view/base/web/js/form/components/collection.js
index 0dd910f3e3ca37a6ab59212125cf0b3dfa16c7f4..5835bb0b486a089e6b1e56ba27597ce6c20c9680 100644
--- a/app/code/Magento/Ui/view/base/web/js/form/components/collection.js
+++ b/app/code/Magento/Ui/view/base/web/js/form/components/collection.js
@@ -4,17 +4,18 @@
  */
 define([
     'underscore',
-    'mage/utils',
-    'Magento_Ui/js/lib/registry/registry',
-    'Magento_Ui/js/form/component',
-], function (_, utils, registry, Component) {
+    'mageUtils',
+    'uiRegistry',
+    'uiComponent',
+    'Magento_Ui/js/core/renderer/layout'
+], function (_, utils, registry, Component, layout) {
     'use strict';
 
     var childTemplate = {
-        template:   "{name}.{itemTemplate}",
-        parent:     "{name}",
-        name:       "{childIndex}",
-        dataScope:  "{childIndex}"
+        template: '<%= $data.name %>.<%= $data.itemTemplate %>',
+        parent: '<%= $data.name %>',
+        name: '<%= $data.childIndex %>',
+        dataScope: '<%= name %>'
     };
 
     return Component.extend({
@@ -39,7 +40,7 @@ define([
          *
          * @param {Object} elem - Incoming child.
          */
-        initElement: function(elem) {
+        initElement: function (elem) {
             this._super();
 
             elem.activate();
@@ -55,12 +56,11 @@ define([
          *
          * @returns {Collection} Chainable.
          */
-        initChildren: function() {
-            var data     = this.provider.data,
-                children = data.get(this.dataScope),
-                initial  = this.initialItems = [];
+        initChildren: function () {
+            var children = this.source.get(this.dataScope),
+                initial = this.initialItems = [];
 
-            _.each(children, function(item, index) {
+            _.each(children, function (item, index) {
                 initial.push(index);
                 this.addChild(index);
             }, this);
@@ -74,16 +74,12 @@ define([
          * @param {String|Object} [index] - Index of a child.
          * @returns {Collection} Chainable.
          */
-        addChild: function(index) {
+        addChild: function (index) {
             this.childIndex = !_.isString(index) ?
-                ('new_' + this.lastIndex++) :
+                'new_' + this.lastIndex++ :
                 index;
 
-            this.renderer.render({
-                layout: [
-                    utils.template(childTemplate, this)
-                ]
-            });
+            layout([utils.template(childTemplate, this)]);
 
             return this;
         },
@@ -94,12 +90,12 @@ define([
          *
          * @returns {Boolean}
          */
-        hasChanged: function(){
+        hasChanged: function () {
             var initial = this.initialItems,
                 current = this.elems.pluck('index'),
                 changed = !utils.identical(initial, current);
 
-            return changed || this.elems.some(function(elem){
+            return changed || this.elems.some(function (elem) {
                 return _.some(elem.delegate('hasChanged'));
             });
         },
@@ -109,12 +105,12 @@ define([
          *
          * @returns {Array} An array of validation results.
          */
-        validate: function(){
+        validate: function () {
             var elems;
 
             this.allValid = true;
 
-            elems = this.elems.sortBy(function(elem){
+            elems = this.elems.sortBy(function (elem) {
                 return !elem.active();
             });
 
@@ -130,23 +126,23 @@ define([
          * @param {Object} elem - Element to run validation on.
          * @returns {Array} An array of validation results.
          */
-        _validate: function(elem){
+        _validate: function (elem) {
             var result = elem.delegate('validate'),
                 invalid;
 
-            invalid = _.some(result, function(item){
+            invalid = _.some(result, function (item) {
                 return !item.valid;
             });
 
-            if(this.allValid && invalid){
+            if (this.allValid && invalid) {
                 this.allValid = false;
 
                 elem.activate();
             }
 
-            return result;  
+            return result;
         },
-        
+
         /**
          * Creates function that removes element
          * from collection using '_removeChild' method.
@@ -155,15 +151,12 @@ define([
          *      Since this method is used by 'click' binding,
          *      it requires function to invoke.
          */
-        removeChild: function(elem) {
-            return function() {
-                var confirmed = confirm(this.removeMessage);
-
-                if (confirmed) {
-                    this._removeChild(elem);
-                }
+        removeChild: function (elem) {
+            var confirmed = confirm(this.removeMessage);
 
-            }.bind(this);
+            if (confirmed) {
+                this._removeChild(elem);
+            }
         },
 
         /**
@@ -173,7 +166,7 @@ define([
          *
          * @param {Object} elem - Element to remove.
          */
-        _removeChild: function(elem) {
+        _removeChild: function (elem) {
             var isActive = elem.active(),
                 first;
 
@@ -189,4 +182,3 @@ define([
         }
     });
 });
-
diff --git a/app/code/Magento/Ui/view/base/web/js/form/components/collection/item.js b/app/code/Magento/Ui/view/base/web/js/form/components/collection/item.js
index 44413dd4555972fc7b8f86323921d10d04584640..d8b4bf4cc4192fe038f7d1c74c00af1f23f4daa6 100644
--- a/app/code/Magento/Ui/view/base/web/js/form/components/collection/item.js
+++ b/app/code/Magento/Ui/view/base/web/js/form/components/collection/item.js
@@ -4,7 +4,7 @@
  */
 define([
     'underscore',
-    'mage/utils',
+    'mageUtils',
     '../tab'
 ], function (_, utils, Tab) {
     'use strict';
@@ -16,12 +16,12 @@ define([
 
     /**
      * Parses incoming data and returnes result merged with default preview config
-     * 
+     *
      * @param  {Object|String} data
      * @return {Object}
      */
-    function parsePreview(data){
-       if (typeof data === 'string') {
+    function parsePreview(data) {
+        if (typeof data == 'string') {
             data = {
                 items: data
             };
@@ -34,10 +34,9 @@ define([
 
     return Tab.extend({
         defaults: {
-            template:           'ui/form/components/collection/item',
-            label:              '',
-            uniqueNs:           'activeCollectionItem',
-            previewTpl:         'ui/form/components/collection/preview'   
+            label: '',
+            uniqueNs: 'activeCollectionItem',
+            previewTpl: 'ui/form/components/collection/preview'
         },
 
         /**
@@ -50,25 +49,23 @@ define([
         },
 
         /**
-         * Calls initProperties of parent class, initializes properties 
-         *     of instance
-         *     
+         * Calls initProperties of parent class, initializes properties
+         * of instance.
+         *
          * @return {Object} - reference to instance
          */
         initProperties: function () {
             this._super();
 
             this.displayed = [];
-            
-            utils.add(this.regions, 'body', 'head');
 
             return this;
         },
 
         /**
          * Calls initObservable of parent class, initializes observable
-         *     properties of instance
-         *     
+         * properties of instance.
+         *
          * @return {Object} - reference to instance
          */
         initObservable: function () {
@@ -76,7 +73,7 @@ define([
 
             this.observe({
                 'noPreview': true,
-                'indexed':   {}
+                'indexed': {}
             });
 
             return this;
@@ -98,73 +95,76 @@ define([
 
         /**
          * Adds element to observable indexed object of instance
-         * 
+         *
          * @param  {Object} elem
          * @return {Object} - reference to instance
          */
         insertToIndexed: function (elem) {
             var indexed = this.indexed();
-            
+
             indexed[elem.index] = elem;
 
             this.indexed(indexed);
-            
+
             return this;
         },
 
         /**
-         * Formats incoming previews array via parsePreview function
-         * 
+         * Formats incoming previews array via parsePreview function.
+         *
          * @param  {Array} previews
          * @return {Array} - formatted previews
          */
-        formatPreviews: function(previews){
+        formatPreviews: function (previews) {
             return previews.map(parsePreview);
         },
 
         /**
          * Creates string view of previews
-         * 
+         *
          * @param  {Object} data
          * @return {Strict} - formatted preview string
          */
-        buildPreview: function(data){
+        buildPreview: function (data) {
             var preview = this.getPreview(data.items),
-                prefix  = data.prefix;
+                prefix = data.prefix;
 
             return prefix + preview.join(data.separator);
         },
 
         /**
          * Defines if instance has preview for incoming data
-         * 
+         *
          * @param  {Object}  data
          * @return {Boolean}
          */
-        hasPreview: function(data){
+        hasPreview: function (data) {
             return !!this.getPreview(data.items).length;
         },
 
         /**
          * Creates an array of previews for elements specified in incoming
          * items array, calls updatePreview afterwards.
-         * 
+         *
          * @param  {Array} items - An array of element's indexes.
          * @returns {Array} An array of previews.
          */
-        getPreview: function(items){
-            var elems       = this.indexed(),
-                displayed   = this.displayed,
+        getPreview: function (items) {
+            var elems = this.indexed(),
+                displayed = this.displayed,
                 preview;
 
-            items = items.map(function(index){
+            items = items.map(function (index) {
                 var elem = elems[index];
 
-                preview = elem ? elem.delegate('getPreview') : [];
-                preview = _.compact(preview).join(', ');
+                preview = elem ? elem.delegate('getPreview') : '';
+
+                preview = Array.isArray(preview) ?
+                    _.compact(preview).join(', ') :
+                    preview;
 
                 utils.toggle(displayed, index, !!preview);
-                
+
                 return preview;
             });
 
@@ -173,4 +173,4 @@ define([
             return _.compact(items);
         }
     });
-});
\ No newline at end of file
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/form/components/fieldset.js b/app/code/Magento/Ui/view/base/web/js/form/components/fieldset.js
index 752a678fc72fe58805fe89e38696d144fa1881aa..2369c3740f4688f8116628a1cb561170342c544b 100644
--- a/app/code/Magento/Ui/view/base/web/js/form/components/fieldset.js
+++ b/app/code/Magento/Ui/view/base/web/js/form/components/fieldset.js
@@ -3,13 +3,15 @@
  * See COPYING.txt for license details.
  */
 define([
-    './collapsible'
-], function(Collapsible) {
+    'Magento_Ui/js/lib/collapsible'
+], function (Collapsible) {
     'use strict';
 
     return Collapsible.extend({
         defaults: {
-            template: 'ui/fieldset/fieldset'
+            template: 'ui/form/fieldset',
+            collapsible: false,
+            opened: true
         }
     });
-});
\ No newline at end of file
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/form/components/group.js b/app/code/Magento/Ui/view/base/web/js/form/components/group.js
index 2a23cb48a54da5f3e6d2764a39554a4558691928..325e4e0f4295e06d3326d94d75ab08573db58d99 100644
--- a/app/code/Magento/Ui/view/base/web/js/form/components/group.js
+++ b/app/code/Magento/Ui/view/base/web/js/form/components/group.js
@@ -4,45 +4,25 @@
  */
 define([
     'underscore',
-    '../component',
-    'mage/utils'
-], function(_, Component, utils) {
+    'uiComponent'
+], function (_, Component) {
     'use strict';
-    
-    function extractData(container, field){
-        var data,
-            value;
-
-        container.some(function(item){
-            value = item[field];
-
-            if(_.isFunction(value)){
-                value = value();
-            }
-
-            return !item.hidden() && (data = value);
-        });
-
-        return data || '';
-    }
 
     return Component.extend({
         defaults: {
-            hidden:         false,
-            label:          '',
-            required:       false,
-            template:       'ui/group/group',
-            fieldTemplate:  'ui/group/field',
-            breakLine:      true
+            hidden: false,
+            label: '',
+            required: false,
+            template: 'ui/group/group',
+            fieldTemplate: 'ui/form/field',
+            breakLine: true
         },
 
         /**
          * Extends this with defaults and config.
          * Then calls initObservable, iniListenes and extractData methods.
-         * 
-         * @param  {Object} config
          */
-        initialize: function() {            
+        initialize: function () {
             _.bindAll(this, 'toggle');
 
             return this._super();
@@ -51,12 +31,12 @@ define([
         /**
          * Calls initObservable of parent class.
          * Defines observable properties of instance.
-         * 
+         *
          * @return {Object} - reference to instance
          */
-        initObservable: function(){
+        initObservable: function () {
             this._super()
-                .observe('hidden label required');
+                .observe('hidden required');
 
             return this;
         },
@@ -64,41 +44,25 @@ define([
         /**
          * Assignes onUpdate callback to update event of incoming element.
          * Calls extractData method.
-         * @param  {Object} element
+         * @param  {Object} elem
          * @return {Object} - reference to instance
          */
-        initElement: function(elem){
+        initElement: function (elem) {
             this._super();
 
             elem.on({
                 'toggle': this.toggle
             });
 
-            this.extractData();
-
-            return this;
-        },
-
-        /**
-         * Extracts label and required properties from child elements
-         * 
-         * @return {Object} - reference to instance
-         */
-        extractData: function(){
-            var elems = this.elems();
-
-            this.label(extractData(elems, 'label'));
-            this.required(extractData(elems, 'required'));
-
             return this;
         },
 
         /**
          * Sets incoming value to hidden observable, calls extractData method
-         * 
+         *
          * @param  {Boolean} value
          */
-        toggle: function(value){
+        toggle: function (value) {
             this.extractData()
                 .hidden(value);
         },
@@ -119,4 +83,4 @@ define([
             return this.elems.getLength() > 1;
         }
     });
-});
\ No newline at end of file
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/form/components/html.js b/app/code/Magento/Ui/view/base/web/js/form/components/html.js
index d9dd813981d5f03ea6abbaca1deef638664b6bed..e8cf03cc4e1bc266f16987cf65a653842f8b432b 100644
--- a/app/code/Magento/Ui/view/base/web/js/form/components/html.js
+++ b/app/code/Magento/Ui/view/base/web/js/form/components/html.js
@@ -5,8 +5,8 @@
 define([
     'jquery',
     'underscore',
-    '../component'
-], function($, _, Component) {
+    'uiComponent'
+], function ($, _, Component) {
     'use strict';
 
     return Component.extend({
@@ -14,14 +14,17 @@ define([
             content:        '',
             showSpinner:    false,
             loading:        false,
-            template:       'ui/content/content'
+            template:       'ui/content/content',
+            listens: {
+                loading: 'toggleLoadState'
+            }
         },
 
         /**
          * Extends instance with default config, calls 'initialize' method of
          *     parent, calls 'initAjaxConfig'
          */
-        initialize: function() {
+        initialize: function () {
             _.bindAll(this, 'onContainerToggle', 'onDataLoaded');
 
             this._super()
@@ -32,33 +35,18 @@ define([
 
         /**
          * Calls 'initObservable' method of parent, initializes observable
-         *     properties of instance
-         *     
+         * properties of instance
+         *
          * @return {Object} - reference to instance
          */
-        initObservable: function() {
+        initObservable: function () {
             this._super()
                 .observe('content loading');
 
             return this;
         },
 
-        /**
-         * Calls 'initListeners' method of parent, defines instance's subscriptions
-         * 
-         * @return {Object} - reference to instance
-         */
-        initListeners: function() {
-            this._super();
-
-            this.loading.subscribe(function(value) {
-                this.trigger(value ? 'loading' : 'loaded');
-            }, this);
-
-            return this;
-        },
-
-        initContainer: function(parent) {
+        initContainer: function (parent) {
             this._super();
 
             parent.on('active', this.onContainerToggle);
@@ -68,13 +56,15 @@ define([
 
         /**
          * Initializes default ajax config on instance
-         * 
+         *
          * @return {Object} - reference to instance
          */
-        initAjaxConfig: function(){
+        initAjaxConfig: function () {
             this.ajaxConfig = {
-                url:        this.source,
-                data:       { FORM_KEY: FORM_KEY },
+                url: this.url,
+                data: {
+                    FORM_KEY: FORM_KEY
+                },
                 success:    this.onDataLoaded
             };
 
@@ -83,40 +73,44 @@ define([
 
         /**
          * Calls 'loadData' if both 'active' variable and 'shouldLoad'
-         *     property are truthy
-         * 
+         * property are truthy
+         *
          * @param  {Boolean} active
          */
-        onContainerToggle: function(active) {
+        onContainerToggle: function (active) {
             if (active && this.shouldLoad()) {
                 this.loadData();
             }
         },
 
+        toggleLoadState: function (value) {
+            this.trigger(value ? 'loading' : 'loaded');
+        },
+
         /**
-         * Defines if instance has 'content' property defined 
-         * 
+         * Defines if instance has 'content' property defined.
+         *
          * @return {Boolean} [description]
          */
-        hasData: function() {
+        hasData: function () {
             return !!this.content();
         },
 
         /**
          * Defines if instance should load external data
-         * 
+         *
          * @return {Boolean}
          */
-        shouldLoad: function() {
-            return this.source && !this.hasData() && !this.loading();
+        shouldLoad: function () {
+            return this.url && !this.hasData() && !this.loading();
         },
 
         /**
          * Sets loading property to true, makes ajax call
-         * 
+         *
          * @return {Object} - reference to instance
          */
-        loadData: function() {
+        loadData: function () {
             this.loading(true);
 
             $.ajax(this.ajaxConfig);
@@ -126,25 +120,25 @@ define([
 
         /**
          * Ajax's request success handler. Calls 'updateContent' passing 'data'
-         *     to it, then sets 'loading' property to false 
-         * 
+         * to it, then sets 'loading' property to false.
+         *
          * @param  {String} data
          */
-        onDataLoaded: function(data) {
+        onDataLoaded: function (data) {
             this.updateContent(data)
                 .loading(false);
         },
 
         /**
          * Sets incoming data 'content' property's value
-         *  
+         *
          * @param  {String} content
          * @return {Object} - reference to instance
          */
-        updateContent: function(content) {
+        updateContent: function (content) {
             this.content(content);
 
             return this;
         }
     });
-});
\ No newline at end of file
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/form/components/tab.js b/app/code/Magento/Ui/view/base/web/js/form/components/tab.js
index c15e513883219106dfc7639dcf7b6ef6fc41a38e..61560892e3e9ddd8dc3885644eb3d874a50ea9fb 100644
--- a/app/code/Magento/Ui/view/base/web/js/form/components/tab.js
+++ b/app/code/Magento/Ui/view/base/web/js/form/components/tab.js
@@ -3,8 +3,8 @@
  * See COPYING.txt for license details.
  */
 define([
-    '../component'
-], function(Component) {
+    'uiComponent'
+], function (Component) {
     'use strict';
 
     return Component.extend({
@@ -18,7 +18,7 @@ define([
          * Extends instance with defaults. Invokes parent initialize method.
          * Calls initListeners and pushParams methods.
          */
-        initialize: function() {
+        initialize: function () {
             this._super()
                 .setUnique();
         },
@@ -28,29 +28,29 @@ define([
          * Defines observable properties of instance.
          * @return {Object} - reference to instance
          */
-        initObservable: function() {
+        initObservable: function () {
             this._super()
                 .observe('active wasActivated');
 
             return this;
         },
-        
-        onUniqueUpdate: function(name){
+
+        onUniqueUpdate: function (name) {
             var active = name === this.name;
 
             this._super();
 
             this.trigger('active', active);
         },
-        
+
         /**
          * Sets active property to true, then invokes pushParams method.
          */
-        activate: function(){
+        activate: function () {
             this.active(true);
             this.wasActivated(true);
 
             this.setUnique();
         }
     });
-});
\ No newline at end of file
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/form/components/tab_group.js b/app/code/Magento/Ui/view/base/web/js/form/components/tab_group.js
index 625d2ba848c6bfd0c60d6453e3835fb072dd0748..474814559d3cae9f0f364bdf593332ecb12654bb 100644
--- a/app/code/Magento/Ui/view/base/web/js/form/components/tab_group.js
+++ b/app/code/Magento/Ui/view/base/web/js/form/components/tab_group.js
@@ -4,12 +4,18 @@
  */
 define([
     'underscore',
-    './collapsible',
-    'Magento_Ui/js/lib/spinner'
-], function(_, Collapsible, loader) {
+    'Magento_Ui/js/lib/collapsible'
+], function (_, Collapsible) {
     'use strict';
-   
+
     return Collapsible.extend({
+        defaults: {
+            listens: {
+                '<%= provider %>:data.validate': 'onValidate'
+            },
+            collapsible: false,
+            opened: true
+        },
 
         /**
          * Invokes initElement method of parent class, calls 'initActivation' method
@@ -17,27 +23,10 @@ define([
          * @param {Object} elem
          * @returns {Object} - reference to instance
          */
-        initElement: function(elem){
+        initElement: function (elem) {
             this._super()
-                .initActivation(elem)
-                .hideLoader();
-
-            return this;
-        },
-
-        /**
-         * Binds 'onValidate' method as handler for data storage's 'validate' event
-         * 
-         * @return {Object} - reference to instance
-         */
-        initListeners: function(){
-            var data    = this.provider.data,
-                handler = this.onValidate.bind(this);
-
-            this._super();
+                .initActivation(elem);
 
-            data.on('validate', handler, this.name);
-            
             return this;
         },
 
@@ -48,40 +37,36 @@ define([
          * @param  {Object} elem
          * @returns {Object} - reference to instance
          */
-        initActivation: function(elem){
+        initActivation: function (elem) {
             var elems   = this.elems(),
                 isFirst = !elems.indexOf(elem);
 
-            if(isFirst || elem.active()){
+            if (isFirst || elem.active()) {
                 elem.activate();
             }
 
             return this;
         },
 
-        hideLoader: function () {
-            loader.get(this.name).hide();
-        },
-
         /**
          * Delegates 'validate' method on element, then reads 'invalid' property
-         * of params storage, and if defined, activates element, sets 
+         * of params storage, and if defined, activates element, sets
          * 'allValid' property of instance to false and sets invalid's
          * 'focused' property to true.
          *
          * @param {Object} elem
          */
-        validate: function(elem){
-            var params  = this.provider.params,
+        validate: function (elem) {
+            var source = this.source,
                 result  = elem.delegate('validate'),
                 invalid = false;
 
-            _.some(result, function(item){
+            _.some(result, function (item) {
                 return !item.valid && (invalid = item.target);
             });
 
-            if (invalid && !params.get('invalid')) {
-                params.set('invalid', invalid);
+            if (invalid && !source.get('params.invalid')) {
+                source.set('params.invalid', true);
 
                 elem.activate();
                 invalid.focused(true);
@@ -90,16 +75,16 @@ define([
 
         /**
          * Sets 'allValid' property of instance to true, then calls 'validate' method
-         * of instance for each element 
+         * of instance for each element.
          */
-        onValidate: function(){
+        onValidate: function () {
             var elems;
 
-            elems = this.elems.sortBy(function(elem){
+            elems = this.elems.sortBy(function (elem) {
                 return !elem.active();
-            });            
+            });
 
-            elems.each(this.validate, this);
+            elems.forEach(this.validate, this);
         }
     });
-});
\ No newline at end of file
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js b/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js
index e1d66754af6285e4a6938ca4f878a3a2b7fdca3d..1e5f1168ffbe0fd7c4ba037f65fe91f53f35bee8 100644
--- a/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js
+++ b/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js
@@ -4,59 +4,69 @@
  */
 define([
     'underscore',
-    'mage/utils',
-    'Magento_Ui/js/form/component',
+    'mageUtils',
+    'uiComponent',
     'Magento_Ui/js/lib/validation/validator'
 ], function (_, utils, Component, validator) {
     'use strict';
-    
-    /**
-     * Checks wether the incoming value is not empty,
-     * e.g. not 'null' or 'undefined'
-     *
-     * @param {*} value - Value to check.
-     * @returns {Boolean}
-     */
-    function isEmpty(value){
-        return _.isUndefined(value) || _.isNull(value);
-    }
 
     return Component.extend({
         defaults: {
-            hidden:             false,
-            preview:            '',
-            focused:            false,
-            required:           false,
-            disabled:           false,
-            tmpPath:            'ui/form/element/',
-            tooltipTpl:         'ui/form/element/helper/tooltip',
-            input_type:         'input',
-            placeholder:        '',
-            description:        '',
-            label:              '',
-            error:              '',
-            notice:             ''
+            visible: true,
+            preview: '',
+            focused: false,
+            required: false,
+            disabled: false,
+            tmpPath: 'ui/form/element/',
+            tooltipTpl: 'ui/form/element/helper/tooltip',
+            input_type: 'input',
+            placeholder: '',
+            description: '',
+            label: '',
+            error: '',
+            notice: '',
+
+            listens: {
+                value: 'onUpdate',
+                visible: 'setPreview',
+                '<%= provider %>:data.reset': 'reset',
+                '<%= provider %>:data.validate': 'validate'
+            },
+
+            links: {
+                value: '<%= provider %>:<%= dataScope %>'
+            },
+
+            exports: {
+                visible: '<%= provider %>:config.<%= name %>.visible'
+            },
+
+            imports: {
+                setPreview: '<%= name %>:value'
+            }
         },
 
         /**
          * Invokes initialize method of parent class, contains initialization
          *     logic
-         *     
+         *
          * @param {Object} config - form element configuration
          */
         initialize: function () {
-            _.bindAll(this, 'onUpdate', 'reset');
+            _.bindAll(this, 'reset');
+
+            this._super();
+
+            this.initialValue = this.getInititalValue();
 
-            this._super()
-                .setHidden(this.hidden())
-                .store(this.value());
+            this.value(this.initialValue);
 
             return this;
         },
 
         /**
          * Initializes observable properties of instance
-         * 
+         *
          * @returns {Abstract} Chainable.
          */
         initObservable: function () {
@@ -64,11 +74,8 @@ define([
 
             this._super();
 
-            this.initialValue = this.getInititalValue();
-
-            this.observe('error disabled focused preview hidden')
+            this.observe('error disabled focused preview visible')
                 .observe({
-                    'value':    this.initialValue,
                     'required': !!rules['required-entry']
                 });
 
@@ -77,7 +84,7 @@ define([
 
         /**
          * Initializes regular properties of instance.
-         * 
+         *
          * @returns {Abstract} Chainable.
          */
         initProperties: function () {
@@ -86,87 +93,37 @@ define([
             this._super();
 
             _.extend(this, {
-                'uid':          uid,
-                'noticeId':     'notice-' + this.uid,
-                'inputName':    utils.serializeName(this.dataScope)
-            });
-
-            _.defaults(this, {
-                'template': this.tmpPath + this.input_type
+                'uid': uid,
+                'noticeId': 'notice-' + uid,
+                'inputName': utils.serializeName(this.dataScope)
             });
 
             return this;
         },
 
-        /**
-         * Initializes instance's listeners.
-         * 
-         * @returns {Abstract} Chainable.
-         */
-        initListeners: function(){
-            var provider  = this.provider,
-                data      = provider.data;
-
-            this._super();
-
-            data.on('reset', this.reset, this.name);
-            
-            this.value.subscribe(this.onUpdate);
-
-            return this;
-        },
-
         /**
          * Gets initial value of element
-         * 
+         *
          * @returns {*} Elements' value.
          */
-        getInititalValue: function(){
-            var data    = this.provider.data,
-                values  = [data.get(this.dataScope), this.default],
+        getInititalValue: function () {
+            var values = [this.value(), this.default],
                 value;
 
-            values.some(function(v){
-                return !isEmpty(value = v);
+            values.some(function (v) {
+                return !utils.isEmpty(value = v);
             });
 
-            return isEmpty(value) ? '': value;
+            return utils.isEmpty(value) ? '' : value;
         },
 
         /**
          * Sets value to preview observable
-         * 
+         *
          * @returns {Abstract} Chainable.
          */
-        setPreview: function(value){
-            this.preview(this.hidden() ? '' : value);
-
-            return this;
-        },
-
-        /**
-         * Returnes unwrapped preview observable.
-         * 
-         * @returns {String} Value of the preview observable.
-         */
-        getPreview: function(){
-            return this.preview();
-        },
-
-        /**
-         * Calls 'setHidden' passing true to it.
-         */
-        hide: function(){
-            this.setHidden(true);
-
-            return this;
-        },
-
-        /**
-         * Calls 'setHidden' passing false to it.
-         */
-        show: function(){
-            this.setHidden(false);
+        setPreview: function (value) {
+            this.preview(!this.visible() ? '' : value);
 
             return this;
         },
@@ -175,25 +132,29 @@ define([
          * Sets 'value' as 'hidden' propertie's value, triggers 'toggle' event,
          * sets instance's hidden identifier in params storage based on
          * 'value'.
-         * 
+         *
          * @returns {Abstract} Chainable.
          */
-        setHidden: function(isHidden){
-            var params = this.provider.params;
-
-            this.hidden(isHidden);
-    
-            this.setPreview(this.value())
-                .trigger('toggle', isHidden);
+        setVisible: function (isVisible) {
+            this.visible(isVisible);
 
-            params.set(this.name + '.hidden', isHidden);
+            this.trigger('toggle', isVisible);
 
             return this;
         },
 
+        /**
+         * Returnes unwrapped preview observable.
+         *
+         * @returns {String} Value of the preview observable.
+         */
+        getPreview: function () {
+            return this.preview();
+        },
+
         /**
          * Checkes if element has addons
-         * 
+         *
          * @returns {Boolean}
          */
         hasAddons: function () {
@@ -205,29 +166,20 @@ define([
          *
          * @returns {Boolean}
          */
-        hasChanged: function(){
+        hasChanged: function () {
             var notEqual = this.value() != this.initialValue;
 
-            return this.hidden() ? false : notEqual;
+            return !this.visible() ? false : notEqual;
         },
 
-        /**
-         * Stores element's value to registry by element's path value
-         * @param  {*} value - current value of form element
-         * @returns {Abstract} Chainable.
-         */
-        store: function (value) {
-            var data = this.provider.data;
-
-            data.set(this.dataScope, value);
-
-            return this;
+        hasData: function () {
+            return !utils.isEmpty(this.value());
         },
 
         /**
          * Sets value observable to initialValue property.
          */
-        reset: function(){
+        reset: function () {
             this.value(this.initialValue);
         },
 
@@ -235,18 +187,18 @@ define([
          * Validates itself by it's validation rules using validator object.
          * If validation of a rule did not pass, writes it's message to
          * 'error' observable property.
-         *     
+         *
          * @returns {Boolean} True, if element is invalid.
          */
         validate: function () {
-            var value   = this.value(),
-                msg     = validator(this.validation, value),
-                isValid = this.hidden() || !msg;
+            var value = this.value(),
+                msg = validator(this.validation, value),
+                isValid = !this.visible() || !msg;
 
             this.error(msg);
 
             return {
-                valid:  isValid,
+                valid: isValid,
                 target: this
             };
         },
@@ -254,12 +206,10 @@ define([
         /**
          * Callback that fires when 'value' property is updated.
          */
-        onUpdate: function (value) {            
-            this.store(value)
-                .setPreview(value)
-                .trigger('update', this.hasChanged());
+        onUpdate: function () {
+            this.trigger('update', this.hasChanged());
 
             this.validate();
         }
     });
-});
\ No newline at end of file
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/boolean.js b/app/code/Magento/Ui/view/base/web/js/form/element/boolean.js
index 8b13f063ce2052649d4c0ce6c335e1d43b6c5063..4782c853d210b11696c71f31d8d855a8e64eb4b0 100644
--- a/app/code/Magento/Ui/view/base/web/js/form/element/boolean.js
+++ b/app/code/Magento/Ui/view/base/web/js/form/element/boolean.js
@@ -10,28 +10,26 @@ define([
     return Abstract.extend({
         /**
          * Converts the result of parent 'getInitialValue' call to boolean
-         * 
+         *
          * @return {Boolean}
          */
-        getInititalValue: function(){
+        getInititalValue: function () {
             return !!+this._super();
         },
 
         /**
          * Calls 'store' method of parent, if value is defined and instance's
          *     'unique' property set to true, calls 'setUnique' method
-         *     
+         *
          * @param  {*} value
          * @return {Object} - reference to instance
          */
-        store: function() {
-            this._super();
-
+        onUpdate: function () {
             if (this.hasUnique) {
                 this.setUnique();
             }
 
-            return this;
+            return this._super();
         }
     });
-});
\ No newline at end of file
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/date.js b/app/code/Magento/Ui/view/base/web/js/form/element/date.js
index 6e53005137b69fac101db602d58b930d24c24473..4943d845c0504730963115b9bee9e6187e4f72e4 100644
--- a/app/code/Magento/Ui/view/base/web/js/form/element/date.js
+++ b/app/code/Magento/Ui/view/base/web/js/form/element/date.js
@@ -4,13 +4,21 @@
  */
 define([
     'moment',
+    'mageUtils',
     './abstract'
-], function (moment, Abstract) {
+], function (moment, utils, Abstract) {
     'use strict';
 
     return Abstract.extend({
         defaults: {
-            dateFormat: 'MM/DD/YYYY'
+            dateFormat: 'MM/DD/YYYY',
+            options: {}
+        },
+
+        initProperties: function () {
+            this.dateFormat = utils.normalizeDate(this.dateFormat);
+
+            return this._super();
         },
 
         /**
diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/multiselect.js b/app/code/Magento/Ui/view/base/web/js/form/element/multiselect.js
index 1afc75a8837ef240151de7f884dc8cef07ae2fdb..a6dc9e3b3afe600527a5b0fd470b05547b955789 100644
--- a/app/code/Magento/Ui/view/base/web/js/form/element/multiselect.js
+++ b/app/code/Magento/Ui/view/base/web/js/form/element/multiselect.js
@@ -4,7 +4,7 @@
  */
 define([
     'underscore',
-    'mage/utils',
+    'mageUtils',
     './select'
 ], function (_, utils, Select) {
     'use strict';
@@ -17,10 +17,10 @@ define([
         /**
          * Calls 'getInitialValue' of parent and if the result of it is not empty
          * string, returs it, else returnes caption or first found option's value
-         *     
+         *
          * @returns {Number|String}
          */
-        getInititalValue: function(){
+        getInititalValue: function () {
             var value = this._super();
 
             return _.isString(value) ? value.split(',') : value;
@@ -31,7 +31,7 @@ define([
          * @returns {Boolean}
          */
         hasChanged: function () {
-            var value   = this.value(),
+            var value = this.value(),
                 initial = this.initialValue;
 
             return !utils.identical(value, initial);
diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/post-code.js b/app/code/Magento/Ui/view/base/web/js/form/element/post-code.js
index 066d99b1d21078ebe36d2bf12077a15643ce002d..97cb38dcbb07b9aa0018cb54f6535f2c6a2c8c3c 100644
--- a/app/code/Magento/Ui/view/base/web/js/form/element/post-code.js
+++ b/app/code/Magento/Ui/view/base/web/js/form/element/post-code.js
@@ -4,62 +4,37 @@
  */
 define([
     'underscore',
-    'Magento_Ui/js/lib/registry/registry',
+    'uiRegistry',
     './abstract'
 ], function (_, registry, Abstract) {
     'use strict';
 
     return Abstract.extend({
-        /**
-         * Extended list of Listeners
-         *
-         * @return {this}
-         */
-        initListeners: function () {
-            this._super()
-                .update()
-                .provider.data.on('update:' + this.parentScope + '.country_id', this.update.bind(this));
-
-            return this;
+        defaults: {
+            imports: {
+                update: '<%= parentName %>.country_id:value'
+            }
         },
 
-        /**
-         * Fix _postcode_ depend on _country_id_ change:
-         *  - If country in list "Zip/Postal Code is Optional countries" then
-         *    - field "postcode" should not be required
-         *
-         * @returns {this}
-         */
-        update: function () {
-            var parentScope = this.getPart(this.getPart(this.name, -2), -2),
-                option,
-                postcode = this;
-
-            registry.get(parentScope + '.country_id.0', function (countryComponent) {
-                var value = countryComponent.value();
-
-                if (!value) { // empty value discard logic
-                    return;
-                }
+        update: function (value) {
+            var country = registry.get(this.parentName + '.' + 'country_id'),
+                options = country.indexedOptions,
+                option;
 
-                countryComponent
-                    .options()
-                    .some(function (el) {
-                        option = el;
+            if (!value) {
+                return;
+            }
 
-                        return el.value === value;
-                    });
+            option = options[value];
 
-                if (!option.is_region_required) {
-                    postcode.error(false);
-                    postcode.validation = _.omit(postcode.validation, 'required-entry');
-                } else {
-                    postcode.validation['required-entry'] = true;
-                }
-                postcode.required(!!option.is_region_required);
-            });
+            if (!option.is_region_required) {
+                this.error(false);
+                this.validation = _.omit(this.validation, 'required-entry');
+            } else {
+                this.validation['required-entry'] = true;
+            }
 
-            return this;
+            this.required(!!option.is_region_required);
         }
     });
 });
diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/select.js b/app/code/Magento/Ui/view/base/web/js/form/element/select.js
index bd2e6d6d13ca04562b5cfe2472ff119ac00c9d54..2dd476c24a50aaadee6dd7484f8d23c8f329a63f 100644
--- a/app/code/Magento/Ui/view/base/web/js/form/element/select.js
+++ b/app/code/Magento/Ui/view/base/web/js/form/element/select.js
@@ -4,44 +4,37 @@
  */
 define([
     'underscore',
-    'mage/utils',
-    './abstract'
-], function (_, utils, Abstract) {
+    'mageUtils',
+    'uiRegistry',
+    './abstract',
+    'Magento_Ui/js/core/renderer/layout'
+], function (_, utils, registry, Abstract, layout) {
     'use strict';
 
     var inputNode = {
-        name:  '{index}_input',
-        type: 'input',
-        parent: '{parentName}',
-        dataScope: '{customEntry}',
-        config: {
-            hidden: true,
-            label: '{label}',
-            listeners: {
-                "params:{parentName}.{index}.hidden":{
-                    "hide": {
-                        "conditions": false
-                    },
-                    "show": {
-                        "conditions": true
-                    }
-                }
-            }
-        }
+        parent: '<%= $data.parentName %>',
+        type: 'form.input',
+        name: '<%= $data.index %>_input',
+        dataScope: '<%= $data.customEntry %>',
+        sortOrder: {
+            after: '<%= $data.name %>'
+        },
+        displayArea: 'body',
+        label: '<%= $data.label %>'
     };
 
     /**
      * Parses incoming options, considers options with undefined value property
      *     as caption
-     *  
+     *
      * @param  {Array} nodes
      * @return {Object}
      */
-    function parseOptions(nodes){
+    function parseOptions(nodes) {
         var caption,
             value;
 
-        nodes = _.map(nodes, function(node) {
+        nodes = _.map(nodes, function (node) {
             value = node.value;
 
             if (value == null || value === '') {
@@ -55,24 +48,24 @@ define([
 
         return {
             options: _.compact(nodes),
-            caption: caption
+            caption: caption || false
         };
     }
 
     /**
      * Recursively loops over data to find non-undefined, non-array value
-     * 
+     *
      * @param  {Array} data
      * @return {*} - first non-undefined value in array
      */
-    function findFirst(data){
+    function findFirst(data) {
         var value;
 
-        data.some(function(node){
+        data.some(function (node) {
             value = node.value;
 
-            if(Array.isArray(value)){
-                value = findFirst(value);  
+            if (Array.isArray(value)) {
+                value = findFirst(value);
             }
 
             return !_.isUndefined(value);
@@ -81,9 +74,27 @@ define([
         return value;
     }
 
+    function indexOptions(data, result) {
+        var value;
+
+        result = result || {};
+
+        data.forEach(function (item) {
+            value = item.value;
+
+            if (Array.isArray(value)) {
+                indexOptions(value, result);
+            } else {
+                result[value] = item;
+            }
+        });
+
+        return result;
+    }
+
     return Abstract.extend({
         defaults: {
-            template: 'ui/form/element/select'
+            customName: '<%= parentName %>.<%= index %>_input'
         },
 
         /**
@@ -91,24 +102,47 @@ define([
          *     and options, and invokes initialize method of AbstractElement class.
          *     If instance's 'customEntry' property is set to true, calls 'initInput'
          */
-        initialize: function (config) {
-            this.initOptions(config)
-                ._super();
-   
-            if(this.customEntry){
+        initialize: function () {
+            this._super();
+
+            if (this.customEntry) {
                 this.initInput();
             }
 
+            if (this.filterBy) {
+                this.initFilter();
+            }
+
+            return this;
+        },
+
+        /**
+         * Parses options and merges the result with instance
+         *
+         * @param  {Object} config
+         * @returns {Select} Chainable.
+         */
+        initConfig: function (config) {
+            var result = parseOptions(config.options);
+
+            if (config.caption) {
+                delete result.caption;
+            }
+
+            _.extend(config, result);
+
+            this._super();
+
             return this;
         },
 
         /**
          * Calls 'initObservable' of parent, initializes 'options' and 'initialOptions'
          *     properties, calls 'setOptions' passing options to it
-         *     
+         *
          * @returns {Select} Chainable.
          */
-        initObservable: function(){
+        initObservable: function () {
             this._super();
 
             this.initialOptions = this.options;
@@ -119,31 +153,23 @@ define([
             return this;
         },
 
-        /**
-         * Parses options and merges the result with instance
-         * 
-         * @param  {Object} config
-         * @returns {Select} Chainable.
-         */
-        initOptions: function(config){
-            var result = parseOptions(config.options);
+        initFilter: function () {
+            var filter = this.filterBy;
 
-            _.extend(config, result);
+            this.setLinks({
+                filter: filter.target
+            }, 'imports');
 
             return this;
         },
 
         /**
          * Creates input from template, renders it via renderer.
-         * 
+         *
          * @returns {Select} Chainable.
          */
-        initInput: function(){
-            this.renderer.render({
-                layout: [
-                    utils.template(inputNode, this)
-                ]
-            });
+        initInput: function () {
+            layout([utils.template(inputNode, this)]);
 
             return this;
         },
@@ -151,54 +177,67 @@ define([
         /**
          * Calls 'getInitialValue' of parent and if the result of it is not empty
          * string, returs it, else returnes caption or first found option's value
-         *     
+         *
          * @returns {Number|String}
          */
-        getInititalValue: function(){
+        getInititalValue: function () {
             var value = this._super();
 
-            if(value !== ''){
+            if (value !== '') {
                 return value;
             }
-            
-            if(!this.caption){
+
+            if (!this.caption) {
                 return findFirst(this.options);
             }
         },
 
         /**
          * Filters 'initialOptions' property by 'field' and 'value' passed,
-         * calls 'setOptions' passing the result to it 
-         * 
-         * @param {String} field
+         * calls 'setOptions' passing the result to it
+         *
          * @param {*} value
+         * @param {String} field
          */
-        filter: function(field, value){
+        filter: function (value, field) {
             var source = this.initialOptions,
                 result;
 
-            result = _.filter(source, function(item){
+            field = field || this.filterBy.field;
+
+            result = _.filter(source, function (item) {
                 return item[field] === value;
             });
 
             this.setOptions(result);
         },
 
+        toggleInput: function (isVisible) {
+            registry.get(this.customName, function (input) {
+                input.setVisible(isVisible);
+            });
+        },
+
         /**
-         * Sets 'data' to 'options' observable array, if instance has 
+         * Sets 'data' to 'options' observable array, if instance has
          * 'customEntry' property set to true, calls 'setHidden' method
          *  passing !options.length as a parameter
-         * 
+         *
          * @param {Array} data
          * @returns {Select} Chainable.
          */
-        setOptions: function(data){
-            this.indexedOptions = _.indexBy(data, 'value');
+        setOptions: function (data) {
+            var isVisible;
+
+            this.indexedOptions = indexOptions(data);
 
             this.options(data);
-            
-            if(this.customEntry){
-                this.setHidden(!data.length);
+
+            if (this.customEntry) {
+                isVisible = !!data.length;
+
+                this.setVisible(isVisible);
+                this.toggleInput(!isVisible);
             }
 
             return this;
@@ -207,17 +246,17 @@ define([
         /**
          * Processes preview for option by it's value, and sets the result
          * to 'preview' observable
-         * 
+         *
          * @param {String} value
          * @returns {Select} Chainable.
          */
-        setPreview: function(value){
-            var option  = this.indexedOptions[value],
+        setPreview: function (value) {
+            var option = this.indexedOptions[value],
                 preview = option ? option.label : '';
-                
+
             this.preview(preview);
 
             return this;
         }
     });
-});
\ No newline at end of file
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/textarea.js b/app/code/Magento/Ui/view/base/web/js/form/element/textarea.js
index a575e352e6ffcbdce395b56b78cb722123c8f3b8..ebd8a85fac67c2c055c0c1a1ee47ebc1bfb9a93c 100644
--- a/app/code/Magento/Ui/view/base/web/js/form/element/textarea.js
+++ b/app/code/Magento/Ui/view/base/web/js/form/element/textarea.js
@@ -14,4 +14,4 @@ define([
             template:   'ui/form/element/textarea'
         }
     });
-});
\ No newline at end of file
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/form/form.js b/app/code/Magento/Ui/view/base/web/js/form/form.js
new file mode 100644
index 0000000000000000000000000000000000000000..2a192c20c2463e29397750f0ade0e147ac0d80bd
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/form/form.js
@@ -0,0 +1,95 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+    'underscore',
+    'uiComponent',
+    'Magento_Ui/js/lib/spinner',
+    './adapter'
+], function (_, Component, loader, adapter) {
+    'use strict';
+
+    function collectData(selector) {
+        var items = document.querySelectorAll(selector),
+            result = {};
+
+        items = Array.prototype.slice.call(items);
+
+        items.forEach(function (item) {
+            result[item.name] = item.value;
+        });
+
+        return result;
+    }
+
+    return Component.extend({
+        initialize: function () {
+            this._super()
+                .initAdapter()
+                .hideLoader();
+
+            return this;
+        },
+
+        initAdapter: function () {
+            adapter.on({
+                'reset': this.reset.bind(this),
+                'save': this.save.bind(this, true),
+                'saveAndContinue': this.save.bind(this, false)
+            });
+
+            return this;
+        },
+
+        initProperties: function () {
+            this._super();
+
+            this.selector = '[data-form-part=' + this.namespace + ']';
+
+            return this;
+        },
+
+        hideLoader: function () {
+            loader.get(this.name).hide();
+
+            return this;
+        },
+
+        save: function (redirect) {
+            this.validate();
+
+            if (!this.source.get('params.invalid')) {
+                this.submit(redirect);
+            }
+        },
+
+        /**
+         * Submits form
+         */
+        submit: function (redirect) {
+            var additional = collectData(this.selector),
+                source = this.source;
+
+            _.each(additional, function (value, name) {
+                source.set('data.' + name, value);
+            });
+
+            source.save({
+                redirect: redirect
+            });
+        },
+
+        /**
+         * Validates each element and returns true, if all elements are valid.
+         */
+        validate: function () {
+            this.source.set('params.invalid', false);
+            this.source.trigger('data.validate');
+        },
+
+        reset: function () {
+            this.source.trigger('data.reset');
+        }
+    });
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/form/provider.js b/app/code/Magento/Ui/view/base/web/js/form/provider.js
index ccf45e2f2f0fdb55efd2f1285b3b0081912551a0..c388763fc4ce7b25cc535cfcbdba5419ccbd0e03 100644
--- a/app/code/Magento/Ui/view/base/web/js/form/provider.js
+++ b/app/code/Magento/Ui/view/base/web/js/form/provider.js
@@ -4,72 +4,36 @@
  */
 define([
     'underscore',
-    './client',
-    './storages',
-    'Magento_Ui/js/lib/registry/registry',
-    'Magento_Ui/js/lib/class',
-    'Magento_Ui/js/lib/events',
-], function(_, Client, storages, registry, Class, EventsBus){
+    'Magento_Ui/js/lib/provider',
+    './client'
+], function (_, Provider, Client) {
     'use strict';
-    
-    var defaults = {
-        stores: ['data', 'params']
-    };
 
-    return Class.extend({
-        /**
-         * Initializes DataProvider instance.
-         * @param {Object} settings - Settings to initialize object with.
-         */
-        initialize: function(settings) {
-            _.extend(this, defaults, settings, settings.config || {});
-
-            this.initStorages()
+    return Provider.extend({
+        initialize: function () {
+            this._super()
                 .initClient();
-        },
-
-        /**
-         * Creates instances of storage objects.
-         * @returns {DataProvider} Chainable.
-         */
-        initStorages: function() {
-            var storage,
-                config;
-
-            this.stores.forEach(function(store) {
-                storage = storages[store];
-                config  = this[store] || {};
-
-                if(Array.isArray(config)){
-                    config = {};
-                }
-
-                this[store] = new storage(config);
-            }, this);
 
             return this;
         },
 
-        initClient: function(){
+        initClient: function () {
             this.client = new Client({
                 urls: {
-                    beforeSave: this.validate_url,
-                    save:       this.submit_url
-                } 
+                    beforeSave: this.data.validate_url,
+                    save: this.data.submit_url
+                }
             });
 
             return this;
         },
 
-        /**
-         * Assembles data and submits it using 'utils.submit' method
-         */
-        save: function(options){
-            var data = this.data.get();
-            
+        save: function (options) {
+            var data = this.get('data');
+
             this.client.save(data, options);
 
             return this;
         }
-    }, EventsBus);
-});
\ No newline at end of file
+    });
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/form/storages.js b/app/code/Magento/Ui/view/base/web/js/form/storages.js
deleted file mode 100644
index 9eba0b970be472943833cdaa2286c1ab29abbe85..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/js/form/storages.js
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-/**
- * Assembles storages for form provider
- */
-define([
-    'Magento_Ui/js/lib/storage/storage'
-], function(Storage){
-    'use strict';
-
-    return {
-        meta:   Storage,
-        params: Storage,
-        data:   Storage,
-        dump:   Storage
-    }
-});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/grid/columns/actions.js b/app/code/Magento/Ui/view/base/web/js/grid/columns/actions.js
new file mode 100644
index 0000000000000000000000000000000000000000..33a095e64e806024affa49638b9fe8bb40566e79
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/grid/columns/actions.js
@@ -0,0 +1,27 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+    'underscore',
+    './column'
+], function (_, Column) {
+    'use strict';
+
+    return Column.extend({
+        defaults: {
+            headerTmpl: 'ui/grid/columns/actions',
+            bodyTmpl: 'ui/grid/cells/actions'
+        },
+
+        getDisplayed: function (actions) {
+            actions = _.filter(actions, function (action) {
+                return !('hidden' in action) || !action.hidden;
+            });
+
+            this.displayed = actions;
+
+            return actions;
+        }
+    });
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/grid/columns/column.js b/app/code/Magento/Ui/view/base/web/js/grid/columns/column.js
new file mode 100644
index 0000000000000000000000000000000000000000..dd91490b300a037bb258775ffdd39f15f5900a52
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/grid/columns/column.js
@@ -0,0 +1,53 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+    'uiComponent'
+], function (Component) {
+    'use strict';
+
+    return Component.extend({
+        defaults: {
+            headerTmpl: 'ui/grid/columns/text',
+            bodyTmpl: 'ui/grid/cells/text',
+            sortable: false,
+            visible: true,
+            defaultVisible: '<%= visible %>',
+            imports: {
+                visible: '<%= provider %>:config.columns.<%= index %>.visible'
+            }
+        },
+
+        resetVisible: function () {
+            this.visible(this.defaultVisible);
+        },
+
+        getClickUrl: function (row) {
+            var field = row[this.actionField],
+                action = field && field[this.clickAction];
+
+            return action ? action.href : '';
+        },
+
+        isClickable: function (row) {
+            return !!this.getClickUrl(row);
+        },
+
+        redirect: function (url) {
+            window.location.href = url;
+        },
+
+        getLabel: function (data) {
+            return data;
+        },
+
+        getHeader: function () {
+            return this.headerTmpl;
+        },
+
+        getBody: function () {
+            return this.bodyTmpl;
+        }
+    });
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/grid/columns/date.js b/app/code/Magento/Ui/view/base/web/js/grid/columns/date.js
new file mode 100644
index 0000000000000000000000000000000000000000..0e319022a8b040491976c758cc2476c5286af112
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/grid/columns/date.js
@@ -0,0 +1,27 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+    'mageUtils',
+    'moment',
+    './sortable'
+], function (utils, moment, Sortable) {
+    'use strict';
+
+    return Sortable.extend({
+        defaults: {
+            dateFormat: 'MMM D, YYYY h:mm:ss A'
+        },
+
+        initProperties: function () {
+            this.dateFormat = utils.normalizeDate(this.dateFormat);
+
+            return this._super();
+        },
+
+        getLabel: function (data) {
+            return moment(data).format(this.dateFormat);
+        }
+    });
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/grid/columns/multiselect.js b/app/code/Magento/Ui/view/base/web/js/grid/columns/multiselect.js
new file mode 100644
index 0000000000000000000000000000000000000000..a88d981dac96cee9b0538a52732252ba27fb0ac1
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/grid/columns/multiselect.js
@@ -0,0 +1,331 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+    'underscore',
+    'mage/translate',
+    './column'
+], function (_, $t, Column) {
+    'use strict';
+
+    return Column.extend({
+        defaults: {
+            headerTmpl: 'ui/grid/columns/multiselect',
+            bodyTmpl: 'ui/grid/cells/multiselect',
+            menuVisible: false,
+            excludeMode: false,
+            allSelected: false,
+            indetermine: false,
+            selected: [],
+            excluded: [],
+            ns: '<%= provider %>:params',
+            actions: [{
+                value: 'selectAll',
+                label: $t('Select all')
+            }, {
+                value: 'deselectAll',
+                label: $t('Deselect all')
+            }, {
+                value: 'selectPage',
+                label: $t('Select all on this page')
+            }, {
+                value: 'deselectPage',
+                label: $t('Deselect all on this page')
+            }],
+
+            imports: {
+                totalRecords: '<%= provider %>:data.totalRecords',
+                rows: '<%= provider %>:data.items'
+            },
+
+            listens: {
+                '<%= ns %>.applyFilters': 'deselectAll',
+                selected: 'onSelectedChange',
+                rows: 'onRowsChange'
+            }
+        },
+
+        /**
+         * Initializes observable properties.
+         *
+         * @returns {Multiselect} Chainable.
+         */
+        initObservable: function () {
+            this._super()
+                .observe([
+                    'menuVisible',
+                    'selected',
+                    'excluded',
+                    'excludeMode',
+                    'totalSelected',
+                    'allSelected',
+                    'indetermine'
+                ]);
+
+            return this;
+        },
+
+        /**
+         * Toggles menu with a list of select actions.
+         */
+        toggleMenu: function () {
+            this.menuVisible(!this.menuVisible());
+        },
+
+        /**
+         * Hides menu with a list of select actions.
+         */
+        hideMenu: function () {
+            this.menuVisible(false);
+        },
+
+        /**
+         * Selects all grid records, even those that are not visible on the page.
+         */
+        selectAll: function () {
+            this.excludeMode(true);
+
+            this.clearExcluded()
+                .selectPage();
+
+            return this;
+        },
+
+        /**
+         * Deselects all grid records.
+         */
+        deselectAll: function () {
+            this.excludeMode(false);
+
+            this.clearExcluded()
+                .deselectPage();
+            this.selected.removeAll();
+
+            return this;
+        },
+
+        /**
+         * Selects or deselects all records.
+         */
+        toggleSelectAll: function () {
+            return this.allSelected() ?
+                    this.deselectAll() :
+                    this.selectAll();
+        },
+
+        /**
+         * Selects all records on the current page.
+         */
+        selectPage: function () {
+            this.selected(
+                _.union(this.selected(), this.getIds())
+            );
+
+            return this;
+        },
+
+        /**
+         * Deselects all records on the current page.
+         */
+        deselectPage: function () {
+            var currentPageIds = this.getIds();
+            this.selected.remove(function (value) {
+                return currentPageIds.indexOf(value) !== -1;
+            });
+
+            return this;
+        },
+
+        /**
+         * Clears the array of not selected records.
+         *
+         * @returns {Multiselect} Chainable.
+         */
+        clearExcluded: function () {
+            this.excluded.removeAll();
+
+            return this;
+        },
+
+        /**
+         * Retrieve all id's from available records.
+         *
+         * @param {Boolean} [exclude] - Whether to exclude not selected ids' from result.
+         * @returns {Array} An array of ids'.
+         */
+        getIds: function (exclude) {
+            var items = this.rows(),
+                ids = _.pluck(items, this.indexField);
+
+            return exclude ?
+                    _.difference(ids, this.excluded()) :
+                    ids;
+        },
+
+        /**
+         * Recalculates list of the excluded records.
+         * Changes value of `excluded`.
+         *
+         * @param {Array} selected - List of the currently selected records.
+         * @returns {Multiselect} Chainable.
+         */
+        updateExcluded: function (selected) {
+            var excluded = this.excluded(),
+                fromPage = _.difference(this.getIds(), selected);
+
+            excluded = _.union(excluded, fromPage);
+            excluded = _.difference(excluded, selected);
+
+            this.excluded(excluded);
+
+            return this;
+        },
+
+        /**
+         * Calculates number of the selected records.
+         * Changes value of `totalSelected`.
+         *
+         * @returns {Multiselect} Chainable.
+         */
+        countSelected: function () {
+            var total = this.totalRecords(),
+                excluded = this.excluded().length,
+                selected = this.selected().length;
+
+            if (this.excludeMode()) {
+                selected = total - excluded;
+            }
+
+            this.totalSelected(selected);
+
+            return this;
+        },
+
+        /**
+         * Exports selections to the data provider.
+         */
+        exportSelections: function () {
+            var data = {},
+                type;
+
+            type = this.excludeMode() ? 'excluded' : 'selected';
+
+            data[type] = this[type]();
+            data.total = this.totalSelected();
+
+            this.source.set('config.multiselect', data);
+        },
+
+        /**
+         * Defines if provided select/deselect action is relevant.
+         *
+         * @param {String} actionId - Id of the action to be checked.
+         * @returns {Boolean}
+         */
+        isActionRelevant: function (actionId) {
+            var pageIds = this.getIds().length,
+                multiplePages = pageIds < this.totalRecords();
+
+            switch (actionId) {
+                case 'selectPage':
+
+                    return multiplePages && !this.isPageSelected(true);
+
+                case 'deselectPage':
+
+                    return multiplePages && this.isPageSelected();
+
+                case 'selectAll':
+
+                    return !this.allSelected();
+
+                case 'deselectAll':
+
+                    return this.totalSelected() > 0;
+            }
+
+            return true;
+        },
+
+        /**
+         * Defines if current page has selected records on it.
+         *
+         * @param {Boolean} [all=false] - If set to 'true' checks that every
+         *      record on the page is selected. Otherwise checks that
+         *      page has some selected records.
+         * @returns {Boolean}
+         */
+        isPageSelected: function (all) {
+            var pageIds = this.getIds(),
+                selected = this.selected(),
+                excluded = this.excluded(),
+                iterator = all ? 'every' : 'some';
+
+            if (this.allSelected()) {
+                return true;
+            }
+
+            if (this.excludeMode()) {
+                return pageIds[iterator](function (id) {
+                    return !~excluded.indexOf(id);
+                });
+            }
+
+            return pageIds[iterator](function (id) {
+                return !!~selected.indexOf(id);
+            });
+        },
+
+        /**
+         * Updates values of the 'allSelected'
+         * and 'indetermine' properties.
+         */
+        updateState: function () {
+            var selected        = this.selected().length,
+                excluded        = this.excluded().length,
+                totalSelected   = this.totalSelected(),
+                totalRecords    = this.totalRecords(),
+                allSelected     = totalRecords && totalSelected === totalRecords;
+
+            if (this.excludeMode()) {
+                if (excluded === totalRecords) {
+                    this.deselectAll();
+                }
+            } else if (totalRecords && selected === totalRecords) {
+                this.selectAll();
+            }
+
+            this.allSelected(allSelected);
+            this.indetermine(totalSelected > 0 && !allSelected);
+
+            return this;
+        },
+
+        /**
+         * Callback method to handle change of the selected items.
+         *
+         * @param {Array} selected - List of the currently selected items.
+         */
+        onSelectedChange: function (selected) {
+            this.updateExcluded(selected)
+                .countSelected()
+                .updateState()
+                .exportSelections();
+        },
+
+        /**
+         * Is invoked when rows has changed. Recalculates selected items
+         * based on "selectMode" property.
+         */
+        onRowsChange: function () {
+            var newSelected;
+
+            if (this.excludeMode()) {
+                newSelected = _.union(this.getIds(true), this.selected());
+
+                this.selected(newSelected);
+            }
+        }
+    });
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/grid/columns/select.js b/app/code/Magento/Ui/view/base/web/js/grid/columns/select.js
new file mode 100644
index 0000000000000000000000000000000000000000..75acdbca9c150981798d0d689a75c0beae1e13d8
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/grid/columns/select.js
@@ -0,0 +1,24 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+    './sortable'
+], function (Sortable) {
+    'use strict';
+
+    return Sortable.extend({
+        getLabel: function (data) {
+            var options = this.options || [],
+                label = '';
+
+            options.some(function (item) {
+                label = item.label;
+
+                return item.value == data;
+            });
+
+            return label;
+        }
+    });
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/grid/columns/sortable.js b/app/code/Magento/Ui/view/base/web/js/grid/columns/sortable.js
new file mode 100644
index 0000000000000000000000000000000000000000..6e4221ae565fcb0718211fed3c81ef518cbe4dc5
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/grid/columns/sortable.js
@@ -0,0 +1,76 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+    './column'
+], function (Column) {
+    'use strict';
+
+    return Column.extend({
+        defaults: {
+            sortable: true,
+            sorting: false,
+            classes: {
+                'asc': '_ascend',
+                'desc': '_descend'
+            },
+            listens: {
+                '<%= provider %>:params.sorting.field': 'onSortChange',
+                sorting: 'setSortClass push'
+            }
+        },
+
+        initObservable: function () {
+            this._super()
+                .observe('sorting sortClass');
+
+            this.setSortClass(this.sorting());
+
+            return this;
+        },
+
+        sort: function (enabled) {
+            var direction;
+
+            direction = enabled !== false ?
+                this.sorting() ?
+                    this.toggleDirection() :
+                    'asc' :
+                false;
+
+            this.sorting(direction);
+        },
+
+        push: function (sorting) {
+            if (!sorting) {
+                return;
+            }
+
+            this.source.set('params.sorting', {
+                field: this.index,
+                direction: sorting
+            });
+
+            this.source.reload();
+        },
+
+        toggleDirection: function () {
+            return this.sorting() === 'asc' ?
+                'desc' :
+                'asc';
+        },
+
+        setSortClass: function (sorting) {
+            var sortClass = this.classes[sorting] || '';
+
+            this.sortClass(sortClass);
+        },
+
+        onSortChange: function (field) {
+            if (field !== this.index) {
+                this.sort(false);
+            }
+        }
+    });
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/grid/controls/columns.js b/app/code/Magento/Ui/view/base/web/js/grid/controls/columns.js
new file mode 100644
index 0000000000000000000000000000000000000000..c46a1b81cf6e3bac1c6da0a38f749baefd1d74f0
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/grid/controls/columns.js
@@ -0,0 +1,115 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+    'mageUtils',
+    'mage/translate',
+    'underscore',
+    'Magento_Ui/js/lib/collapsible'
+], function (utils, $t, _, Collapsible) {
+    'use strict';
+
+    return Collapsible.extend({
+        defaults: {
+            template: 'ui/grid/controls/columns',
+            viewportSize: 18,
+            viewportMaxSize: 30
+        },
+
+        /**
+         * Action Reset
+         */
+        reset: function () {
+            this.delegate('resetVisible');
+        },
+
+        /**
+         * Action Apply
+         */
+        apply: function () {
+            var data = {},
+                current;
+
+            this.close();
+
+            current = this.source.get('config.columns') || {};
+
+            this.elems().forEach(function (elem) {
+                data[elem.index] = {
+                    visible: elem.visible()
+                };
+            });
+
+            utils.extend(current, data);
+
+            this.source.store('config.columns', current);
+        },
+
+        /**
+         * Action Cancel
+         */
+        cancel: function () {
+            var previous = this.source.get('config.columns'),
+                config;
+
+            this.close();
+
+            if (!previous) {
+                return;
+            }
+
+            this.elems().forEach(function (elem) {
+                config = previous[elem.index] || {};
+
+                elem.visible(config.visible);
+            });
+        },
+
+        /**
+         * Helper, wich helps to stop resizing and
+         * @returns {Boolean}
+         */
+        hasOverflow: function () {
+            return this.elems().length > this.viewportSize;
+        },
+
+        /**
+         * Helper, checks
+         *  - if less than one item choosen
+         *  - if more then viewportMaxSize choosen
+         * @param {Object} elem
+         * @returns {Boolean}
+         */
+        isDisabled: function (elem) {
+            var count = this.countVisible(),
+                isLast = elem.visible() && count === 1,
+                isTooMuch = count > this.viewportMaxSize;
+
+            return isLast || isTooMuch;
+        },
+
+        /**
+         * Helper, returns number of visible checkboxes
+         * @returns {Number}
+         */
+        countVisible: function () {
+            return this.elems().filter(function (elem) {
+                return elem.visible();
+            }).length;
+        },
+
+        /**
+         * Compile header message from headerMessage setting.
+         * Expects Underscore template format
+         * @param {String} text - underscore-format template
+         * @returns {String}
+         */
+        getHeaderMessage: function (text) {
+            return _.template(text)({
+                visible: this.countVisible(),
+                total: this.elems().length
+            });
+        }
+    });
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/grid/controls/view.js b/app/code/Magento/Ui/view/base/web/js/grid/controls/view.js
new file mode 100644
index 0000000000000000000000000000000000000000..4ad292e5801d2c2b96ec491265d8bc68013a297d
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/grid/controls/view.js
@@ -0,0 +1,24 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+    'Magento_Ui/js/lib/collapsible'
+], function (Collapsible) {
+    'use strict';
+
+    return Collapsible.extend({
+        defaults: {
+            template: 'ui/grid/controls/view',
+            sampleData: [{
+                label: 'Cameras'
+            }, {
+                label: 'Products by weight'
+            }, {
+                label: 'Greg\'s view'
+            }, {
+                label: 'Default View'
+            }]
+        }
+    });
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js b/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js
new file mode 100644
index 0000000000000000000000000000000000000000..e196cfad0db8d89c98de0e003961d90b7a28d8ab
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js
@@ -0,0 +1,76 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+    'underscore',
+    'Magento_Ui/js/lib/collapsible'
+], function (_, Collapsible) {
+    'use strict';
+
+    function extractPreview(elem) {
+        return {
+            label: elem.label,
+            preview: elem.delegate('getPreview'),
+            elem: elem
+        };
+    }
+
+    function hasData(elem) {
+        return elem.delegate('hasData');
+    }
+
+    function resetValue(elem) {
+        return elem.delegate('reset');
+    }
+
+    return Collapsible.extend({
+        defaults: {
+            template: 'ui/grid/filters/filters',
+            listens: {
+                active: 'extractPreviews'
+            }
+        },
+
+        initObservable: function () {
+            this._super()
+                .observe({
+                    active: [],
+                    previews: []
+                });
+
+            return this;
+        },
+
+        apply: function () {
+            this.extractActive();
+            
+            this.source.trigger('params.applyFilters');
+            this.source.reload();
+        },
+
+        reset: function (filter) {
+            filter ?
+                resetValue(filter) :
+                this.active.each(resetValue);
+
+            this.apply();
+        },
+
+        extractActive: function () {
+            var active = this.elems.filter(hasData);
+
+            this.active(active);
+
+            return this;
+        },
+
+        extractPreviews: function (elems) {
+            var previews = elems.map(extractPreview);
+
+            this.previews(_.compact(previews));
+
+            return this;
+        }
+    });
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/grid/filters/group.js b/app/code/Magento/Ui/view/base/web/js/grid/filters/group.js
new file mode 100644
index 0000000000000000000000000000000000000000..d59ba8fd942d41f53607587eecc69ecd8d5bd090
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/grid/filters/group.js
@@ -0,0 +1,32 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+    'underscore',
+    'Magento_Ui/js/form/components/group'
+], function (_, Group) {
+    'use strict';
+
+    return Group.extend({
+        defaults: {
+            template: 'ui/grid/filters/elements/group'
+        },
+
+        hasData: function () {
+            return this.elems.some(function (elem) {
+                return elem.delegate('hasData');
+            });
+        },
+
+        getPreview: function () {
+            var previews = this.elems.map(function (elem) {
+                if (elem.hasData()) {
+                    return elem.label + ': ' + elem.getPreview();
+                }
+            });
+
+            return _.compact(previews).join(' ');
+        }
+    });
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/grid/listing.js b/app/code/Magento/Ui/view/base/web/js/grid/listing.js
new file mode 100644
index 0000000000000000000000000000000000000000..3885e4f3a34d28f34ae5bc4d7be6e5731106afbd
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/grid/listing.js
@@ -0,0 +1,46 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+    'uiComponent',
+    'Magento_Ui/js/lib/spinner'
+], function (Component, loader) {
+    'use strict';
+
+    return Component.extend({
+        defaults: {
+            template: 'ui/grid/listing',
+            imports: {
+                rows: '<%= provider %>:data.items'
+            },
+            listens: {
+                '<%= provider %>:reload': 'showLoader',
+                '<%= provider %>:reloaded': 'hideLoader'
+            }
+        },
+
+        initialize: function () {
+            this._super()
+                .hideLoader();
+
+            return this;
+        },
+
+        hideLoader: function () {
+            loader.get(this.name).hide();
+        },
+
+        showLoader: function () {
+            loader.get(this.name).show();
+        },
+
+        getColspan: function () {
+            return this.elems().length;
+        },
+
+        hasData: function () {
+            return !!this.rows().length;
+        }
+    });
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/grid/massactions.js b/app/code/Magento/Ui/view/base/web/js/grid/massactions.js
new file mode 100644
index 0000000000000000000000000000000000000000..35c792feaba23e40c19c68f2609171c798983297
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/grid/massactions.js
@@ -0,0 +1,40 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+    'underscore',
+    'mageUtils',
+    'Magento_Ui/js/lib/collapsible'
+], function (_, utils, Collapsible) {
+    'use strict';
+
+    return Collapsible.extend({
+        defaults: {
+            template: 'ui/grid/actions',
+            noItems:  'You haven\'t selected any items!'
+        },
+
+        applyAction: function (action) {
+            var proceed = true,
+                selections = this.source.get('config.multiselect');
+
+            if (!selections || !selections.total) {
+                proceed = false;
+
+                alert(this.noItems);
+            }
+
+            if (proceed && action.confirm) {
+                proceed = window.confirm(action.confirm);
+            }
+
+            if (proceed) {
+                utils.submit({
+                    url: action.url,
+                    data: selections
+                });
+            }
+        }
+    });
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/grid/paging.js b/app/code/Magento/Ui/view/base/web/js/grid/paging.js
new file mode 100644
index 0000000000000000000000000000000000000000..cb6e5367cab328e9aa411d4023b9a6daa205b387
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/grid/paging.js
@@ -0,0 +1,148 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+    'ko',
+    'uiComponent'
+], function (ko, Component) {
+    'use strict';
+
+    /**
+     * Returns closest existing page number to page argument
+     * @param {Number} value
+     * @param {Number} max
+     * @returns {Number} closest existing page number
+     */
+    function getInRange(value, max) {
+        return Math.min(Math.max(1, value), max);
+    }
+
+    return Component.extend({
+        defaults: {
+            template: 'ui/grid/paging',
+            pageSize: 20,
+            current: 1,
+
+            imports: {
+                totalSelected: '<%= provider %>:config.multiselect.total',
+                totalRecords: '<%= provider %>:data.totalRecords'
+            },
+
+            exports: {
+                pageSize: '<%= provider %>:params.paging.pageSize',
+                current: '<%= provider %>:params.paging.current',
+                pages: '<%= provider %>:data.pages'
+            },
+
+            listens: {
+                'pageSize': 'onSizeChange',
+                'pageSize current': 'reload',
+                'pageSize totalRecords': 'countPages'
+            }
+        },
+
+        initialize: function () {
+            this._super()
+                .countPages();
+
+            return this;
+        },
+
+        initObservable: function () {
+            this._super();
+
+            this._current = ko.pureComputed({
+                read: function () {
+                    return +this.current();
+                },
+
+                /**
+                 * Validates page change according to user's input.
+                 * Sets current observable to result of validation.
+                 * Calls reload method then.
+                 */
+                write: function (value) {
+                    var valid;
+
+                    value = +value;
+                    valid = !isNaN(value) ? getInRange(value, this.pages()) : 1;
+
+                    this.current(valid);
+                    this._current.notifySubscribers(value);
+                },
+
+                owner: this
+            });
+
+            return this;
+        },
+
+        /**
+         * Increments current observable prop by val and call reload method
+         * @param {String} val
+         */
+        go: function (val) {
+            var current = this.current;
+
+            current(current() + val);
+        },
+
+        /**
+         * Calls go method with 1 as agrument
+         */
+        next: function () {
+            this.go(1);
+        },
+
+        /**
+         * Calls go method with -1 as agrument
+         */
+        prev: function () {
+            this.go(-1);
+        },
+
+        /**
+         * Compares current and pages observables and returns boolean result
+         *
+         * @returns {Boolean} is current equal to pages property
+         */
+        isLast: function () {
+            return this.current() === this.pages();
+        },
+
+        /**
+         * Compares current observable to 1.
+         *
+         * @returns {Boolean} is current page first
+         */
+        isFirst: function () {
+            return this.current() === 1;
+        },
+
+        reload: function () {
+            this.source.reload();
+        },
+
+        /**
+         * Calculates number of pages.
+         */
+        countPages: function () {
+            var pages = Math.ceil(this.totalRecords() / this.pageSize());
+
+            this.pages(pages || 1);
+        },
+
+        /**
+         * Is being triggered on user interaction with page size select.
+         * Resets current page to first if needed.
+         */
+        onSizeChange: function () {
+            var size = this.pageSize();
+
+            if (size * this.current() > this.totalRecords()) {
+                this.current(1);
+            }
+        }
+    });
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/grid/provider.js b/app/code/Magento/Ui/view/base/web/js/grid/provider.js
new file mode 100644
index 0000000000000000000000000000000000000000..52868c288ca8391c4851e0f7ab9cdf62a268ef69
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/grid/provider.js
@@ -0,0 +1,37 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+    'jquery',
+    'underscore',
+    'mageUtils',
+    'Magento_Ui/js/lib/provider'
+], function ($, _, utils, Provider) {
+    'use strict';
+
+    return Provider.extend({
+        initialize: function () {
+            utils.limit(this, 'reload', 50);
+            _.bindAll(this, 'onReload');
+
+            return this._super();
+        },
+
+        reload: function () {
+            this.trigger('reload');
+
+            $.ajax({
+                url: this.data.update_url,
+                method: 'GET',
+                data: this.get('params'),
+                dataType: 'json'
+            }).done(this.onReload);
+        },
+
+        onReload: function (data) {
+            this.set('data', data);
+            this.trigger('reloaded');
+        }
+    });
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/class.js b/app/code/Magento/Ui/view/base/web/js/lib/class.js
index 1cc6e8955cf81820349c0d61c8ada238ee11c5a5..be53c19ea135fb9566ecbfaece5ce7128e77afe3 100644
--- a/app/code/Magento/Ui/view/base/web/js/lib/class.js
+++ b/app/code/Magento/Ui/view/base/web/js/lib/class.js
@@ -3,8 +3,9 @@
  * See COPYING.txt for license details.
  */
 define([
-    'underscore'
-], function(_) {
+    'underscore',
+    'mageUtils'
+], function (_, utils) {
     'use strict';
 
     var superReg = /\b_super\b/;
@@ -15,7 +16,7 @@ define([
      * @param {Function} method - Method to be checked.
      * @returns {Boolean}
      */
-    function hasSuper(method){
+    function hasSuper(method) {
         return _.isFunction(method) && superReg.test(method);
     }
 
@@ -27,13 +28,13 @@ define([
      * @param {Function} method - Method to be wrapped.
      * @returns {Function} Wrapped method.
      */
-    function superWrapper(parent, name, method){
-        return function(){
-            var superTmp    = this._super,
-                args        = arguments,
+    function superWrapper(parent, name, method) {
+        return function () {
+            var superTmp = this._super,
+                args = arguments,
                 result;
 
-            this._super = function(){
+            this._super = function () {
                 var superArgs = arguments.length ? arguments : args;
 
                 return parent[name].apply(this, superArgs);
@@ -44,52 +45,49 @@ define([
             this._super = superTmp;
 
             return result;
-        }
+        };
     }
 
     /**
      * Analogue of Backbone.extend function.
      *
-     * @param  {Object} extender - 
-     *      Object, that describes the prototype of
+     * @param  {Object} extender - Object, that describes the prototype of
      *      created constructor.
-     * @param {...Object} Multiple amount of mixins.
      * @returns {Function} New constructor.
      */
-    function extend(extender){
-        var parent      = this,
+    function extend(extender) {
+        var parent = this,
+            defaults = extender.defaults || {},
             parentProto = parent.prototype,
-            defaults    = extender.defaults || {},
-            child,
-            childProto,
-            mixins;
+            child;
 
-        child = function(){
-            _.defaults(this, defaults);
-
-            parent.apply(this, arguments);
-        };
+        defaults = defaults || {};
+        extender = extender || {};
 
         delete extender.defaults;
 
-        childProto = child.prototype = Object.create(parentProto);
+        if (extender.hasOwnProperty('constructor')) {
+            child = extender.constructor;
+        } else {
+            child = function () {
+                parent.apply(this, arguments);
+            };
+        }
+
+        defaults = utils.extend({}, parent.defaults, defaults);
 
-        childProto.constructor = child;
+        child.prototype = Object.create(parentProto);
+        child.prototype.constructor = child;
 
-        _.each(extender, function(method, name){
-            childProto[name] = hasSuper(method) ?
+        _.each(extender, function (method, name) {
+            child.prototype[name] = hasSuper(method) ?
                 superWrapper(parentProto, name, method) :
                 method;
         });
 
-        mixins = _.toArray(arguments).slice(1);
-
-        mixins.forEach(function(mixin){
-            _.extend(childProto, mixin);
-        });
-
         child.__super__ = parentProto;
-        child.extend    = extend;
+        child.extend = extend;
+        child.defaults = defaults;
 
         return child;
     }
@@ -101,9 +99,10 @@ define([
         this.initialize.apply(this, arguments);
     }
 
-    Class.prototype.initialize = function(){};
+    Class.prototype.initialize = function () {};
 
     Class.extend = extend;
+    Class.defaults = {};
 
     return Class;
 });
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/form/components/collapsible.js b/app/code/Magento/Ui/view/base/web/js/lib/collapsible.js
similarity index 54%
rename from app/code/Magento/Ui/view/base/web/js/form/components/collapsible.js
rename to app/code/Magento/Ui/view/base/web/js/lib/collapsible.js
index 00b4768b37127a684fb8e9eea00274d9c0b4fe67..5b831ae4460aa4d82483a2d3ee02ae7adc320fb5 100644
--- a/app/code/Magento/Ui/view/base/web/js/form/components/collapsible.js
+++ b/app/code/Magento/Ui/view/base/web/js/lib/collapsible.js
@@ -3,22 +3,22 @@
  * See COPYING.txt for license details.
  */
 define([
-    'Magento_Ui/js/form/component'
-], function(Component) {
+    'uiComponent'
+], function (Component) {
     'use strict';
 
     return Component.extend({
         defaults: {
-            collapsible:    false,
-            opened:         true
+            opened: false,
+            collapsible: true
         },
 
         /**
          * Initializes 'opened' observable, calls 'initObservable' of parent
-         * 
+         *
          * @return {Object} - reference to instance
          */
-        initObservable: function(){
+        initObservable: function () {
             this._super()
                 .observe('opened');
 
@@ -27,25 +27,21 @@ define([
 
         /**
          * Toggles 'active' observable, triggers 'active' event
-         * 
+         *
          * @return {Object} - reference to instance
          */
-        toggle: function() {
-            var opened = this.opened,
-                active = opened(!opened());
-
-            this.trigger('active', active);
+        toggleOpened: function () {
+            if (this.collapsible) {
+                this.opened(!this.opened());
+            }
 
             return this;
         },
 
-        /**
-         * Invokes 'toggle' method if instance has 'collapsible' property set to true
-         */
-        onClick: function(){
-            if(this.collapsible){
-                this.toggle();
+        close: function () {
+            if (this.collapsible) {
+                this.opened(false);
             }
         }
     });
-});
\ No newline at end of file
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/component.js b/app/code/Magento/Ui/view/base/web/js/lib/component.js
deleted file mode 100644
index 7d179bcf36633a131021962d53eb57a06cc3964d..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/js/lib/component.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-define([
-    'Magento_Ui/js/lib/registry/registry'
-], function(registry) {
-    'use strict';
-
-    /**
-     * Extends configuration that will be retrieved from the data provider
-     * with configuration that is stored in a 'baseConfig' object.
-     * @param {Object} provider - DataProvider instance.
-     * @param {Object} baseConfig - Basic configuration.
-     * @returns {Object} Resulting configurational object.
-     */
-    function getConfig(provider, baseConfig) {
-        var configs     = provider.config.get('components'),
-            storeConfig = configs[baseConfig.name] || {};
-
-        return _.extend({
-            provider: provider
-        }, storeConfig, baseConfig);
-    }
-
-    /**
-     * Creates new instance of a grids' component.
-     * @param {Object} data -
-            Data object that was passed while creating component initializer.
-     * @param {Object} base -
-            Basic configuration.
-     */
-    function init(data, base) {
-        var providerName    = base.parent_name,
-            component       = providerName + ':' + base.name;
-
-        if (registry.has(component)) {
-            return;
-        }
-
-        registry.get(providerName, function(provider) {
-            var config = getConfig(provider, base);
-
-            registry.set(component, new data.constr(config));
-        });
-    }
-
-    return function(data) {
-        return init.bind(this, data);
-    };
-});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/component/core.js b/app/code/Magento/Ui/view/base/web/js/lib/component/core.js
new file mode 100644
index 0000000000000000000000000000000000000000..f5944f007f83e4bb005c576f0c005fb8c1b7faf3
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/lib/component/core.js
@@ -0,0 +1,222 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+    'ko',
+    'mageUtils',
+    'underscore',
+    'uiRegistry'
+], function (ko, utils, _, registry) {
+    'use strict';
+
+    /**
+     * Wrapper for ko.observable and ko.observableArray.
+     * Assignes one or another ko property to obj[key]
+     * @param  {Object} obj   - object to store property to
+     * @param  {String} key   - key
+     * @param  {*} value      - initial value of observable
+     */
+    function observe(obj, key, value) {
+        var method = Array.isArray(value) ? 'observableArray' : 'observable';
+
+        if (!ko.isObservable(obj[key])) {
+            obj[key] = ko[method](value);
+        } else {
+            obj[key](value);
+        }
+    }
+
+    return {
+        defaults: {
+            parentName: '<%= $data.getPart(name, -2) %>',
+            parentScope: '<%= $data.getPart(dataScope, -2) %>',
+            template: 'ui/collection',
+            containers: [],
+            _elems: []
+        },
+
+        initialize: function (options) {
+            _.bindAll(this, '_insert');
+
+            this.initConfig(options)
+                .initProperties()
+                .initObservable()
+                .initUnique()
+                .initLinks()
+                .setListners(this.listens);
+
+            return this;
+        },
+
+        initConfig: function (options) {
+            var defaults = this.constructor.defaults,
+                config = utils.extend({}, defaults, options);
+
+            config = utils.template(config, this);
+
+            _.extend(this, config);
+
+            return this;
+        },
+
+        /**
+         * Defines various properties.
+         *
+         * @returns {Component} Chainable.
+         */
+        initProperties: function () {
+            this.regions = [];
+            this.source = registry.get(this.provider);
+
+            return this;
+        },
+
+        /**
+         * Initializes observable properties.
+         *
+         * @returns {Component} Chainable.
+         */
+        initObservable: function () {
+            this.observe({
+                'elems': []
+            });
+
+            this.regions.forEach(function (region) {
+                this.observe(region, []);
+            }, this);
+
+            return this;
+        },
+
+        initLinks: function () {
+            _.each({
+                both: this.links,
+                exports: this.exports,
+                imports: this.imports
+            }, this.setLinks, this);
+
+            return this;
+        },
+
+        /**
+         * Initializes listeners of the unique property.
+         *
+         * @returns {Component} Chainable.
+         */
+        initUnique: function () {
+            var update = this.onUniqueUpdate.bind(this),
+                uniqueNs = this.uniqueNs;
+
+            this.hasUnique = this.uniqueProp && uniqueNs;
+
+            if (this.hasUnique) {
+                this.source.on(uniqueNs, update, this.name);
+            }
+
+            return this;
+        },
+
+        /**
+         * Called when current element was injected to another component.
+         *
+         * @param {Object} parent - Instance of a 'parent' component.
+         * @returns {Component} Chainable.
+         */
+        initContainer: function (parent) {
+            this.containers.push(parent);
+
+            return this;
+        },
+
+        /**
+         * Called when another element was added to current component.
+         *
+         * @param {Object} elem - Instance of an element that was added.
+         * @returns {Component} Chainable.
+         */
+        initElement: function (elem) {
+            elem.initContainer(this);
+
+            return this;
+        },
+
+        /**
+         * Splits incoming string and returns its' part specified by offset.
+         *
+         * @param {String} parts
+         * @param {Number} [offset]
+         * @param {String} [delimiter=.]
+         * @returns {String}
+         */
+        getPart: function (parts, offset, delimiter) {
+            delimiter = delimiter || '.';
+            parts = parts.split(delimiter);
+            offset = utils.formatOffset(parts, offset);
+
+            parts.splice(offset, 1);
+
+            return parts.join(delimiter) || '';
+        },
+
+        /**
+         * Returns path to components' template.
+         * @returns {String}
+         */
+        getTemplate: function () {
+            return this.template;
+        },
+
+        /**
+         * Updates property specified in uniqueNs
+         * if components' unique property is set to 'true'.
+         *
+         * @returns {Component} Chainable.
+         */
+        setUnique: function () {
+            var property = this.uniqueProp;
+
+            if (this[property]()) {
+                this.source.set(this.uniqueNs, this.name);
+            }
+
+            return this;
+        },
+
+        /**
+         * If 2 params passed, path is considered as key.
+         * Else, path is considered as object.
+         * Assignes props to this based on incoming params
+         * @param  {Object|String} path
+         */
+        observe: function (path) {
+            var type = typeof path;
+
+            if (type === 'string') {
+                path = path.split(' ');
+            }
+
+            if (Array.isArray(path)) {
+                path.forEach(function (key) {
+                    observe(this, key, this[key]);
+                }, this);
+            } else if (type === 'object') {
+                _.each(path, function (value, key) {
+                    observe(this, key, value);
+                }, this);
+            }
+
+            return this;
+        },
+
+        /**
+         * Callback which fires when property under uniqueNs has changed.
+         */
+        onUniqueUpdate: function (name) {
+            var active = name === this.name,
+                property = this.uniqueProp;
+
+            this[property](active);
+        }
+    };
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/component/links.js b/app/code/Magento/Ui/view/base/web/js/lib/component/links.js
new file mode 100644
index 0000000000000000000000000000000000000000..4434ca6896eeb5150ad679b8f7be9b8e5d724889
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/lib/component/links.js
@@ -0,0 +1,128 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+    'ko',
+    'underscore',
+    'mageUtils',
+    'Magento_Ui/js/lib/registry/registry'
+], function (ko, _, utils, registry) {
+    'use strict';
+
+    function extractData(str) {
+        var data = str.split(':');
+
+        return {
+            component: data[0],
+            prop: data[1]
+        };
+    }
+
+    function update(target, prop, value) {
+        if (_.isFunction(target[prop])) {
+            target[prop](value);
+        } else if (target.set) {
+            target.set(prop, value);
+        } else {
+            target[prop] = value;
+        }
+    }
+
+    function imports(owner, target, ownerProp, targetProp, auto) {
+        var callback = update.bind(null, owner, ownerProp),
+            value;
+
+        value = target.get ?
+            target.get(targetProp) :
+            utils.nested(target, targetProp);
+
+        if (ko.isObservable(value)) {
+            value.subscribe(callback);
+            value = value();
+        } else if (target.on) {
+            target.on(targetProp, callback);
+        }
+
+        if (auto && typeof value !== 'undefined') {
+            callback(value);
+        }
+    }
+
+    function exports(owner, target, ownerProp, targetProp, auto) {
+        var to = update.bind(null, target, targetProp);
+
+        ownerProp = owner[ownerProp];
+
+        ownerProp.subscribe(to);
+
+        if (auto) {
+            to(ownerProp());
+        }
+    }
+
+    function links(owner, target, ownerProp, direction) {
+        if (!ko.isObservable(owner[ownerProp]) && !_.isFunction(owner[ownerProp])) {
+            owner.observe(ownerProp);
+        }
+
+        target = extractData(target);
+
+        registry.get(target.component, function (component) {
+            var args = [owner, component, ownerProp, target.prop, true];
+
+            switch (direction) {
+                case 'imports':
+                    imports.apply(null, args);
+                    break;
+
+                case 'exports':
+                    exports.apply(null, args);
+                    break;
+
+                case 'both':
+                    imports.apply(null, args);
+                    exports.apply(null, args);
+                    break;
+            }
+        });
+    }
+
+    function listen(owner, target, callback) {
+        target = extractData(target);
+
+        if (!target.prop) {
+            target.prop = target.component;
+            target.component = owner.name;
+        }
+
+        registry.get(target.component, function (component) {
+            imports(owner, component, callback, target.prop);
+        });
+    }
+
+    return {
+        setLinks: function (data, direction) {
+            var owner = this;
+
+            _.each(data, function (target, prop) {
+                links(owner, target, prop, direction);
+            });
+        },
+
+        setListners: function (listeners) {
+            var owner = this;
+
+            _.each(listeners, function (callbacks, sources) {
+                sources = sources.split(' ');
+                callbacks = callbacks.split(' ');
+
+                sources.forEach(function (target) {
+                    callbacks.forEach(function (callback) {
+                        listen(owner, target, callback);
+                    });
+                });
+            });
+        }
+    };
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/component/main.js b/app/code/Magento/Ui/view/base/web/js/lib/component/main.js
new file mode 100644
index 0000000000000000000000000000000000000000..9b5f99cf7cb895c378c072e26103c579fd219df0
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/lib/component/main.js
@@ -0,0 +1,21 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+    'underscore',
+    './core',
+    './links',
+    './manip',
+    './traversal',
+    'Magento_Ui/js/lib/class',
+    'Magento_Ui/js/lib/ko/initialize'
+], function (_, core, links, manip, traversal, Class) {
+    'use strict';
+
+    var extenders;
+
+    extenders = _.extend({}, core, links, manip, traversal);
+
+    return Class.extend(extenders);
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/component/manip.js b/app/code/Magento/Ui/view/base/web/js/lib/component/manip.js
new file mode 100644
index 0000000000000000000000000000000000000000..301beed7381d053c19f734a094d00db2aada6205
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/lib/component/manip.js
@@ -0,0 +1,190 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+    'ko',
+    'underscore',
+    'mageUtils',
+    'uiRegistry'
+], function (ko, _, utils, registry) {
+    'use strict';
+
+    function getIndex(container, target) {
+        var result;
+
+        container.some(function (item, index) {
+            result = index;
+
+            return item && (item.name === target || item === target);
+        });
+
+        return result;
+    }
+
+    function compact(container) {
+        return container.filter(utils.isObject);
+    }
+
+    function reserve(container, elem, position) {
+        var offset = position,
+            target;
+
+        if (_.isObject(position)) {
+            target = position.after || position.before;
+            offset = getIndex(container, target);
+
+            if (position.after) {
+                ++offset;
+            }
+        }
+
+        offset = utils.formatOffset(container, offset);
+
+        container[offset] ?
+            container.splice(offset, 0, elem) :
+            container[offset] = elem;
+
+        return offset;
+    }
+
+    return {
+        getRegion: function (name) {
+            var regions = this.regions;
+
+            if (!regions[name]) {
+                regions[name] = ko.observable([]);
+            }
+
+            return regions[name];
+        },
+
+        updateRegion: function (items, name) {
+            var region = this.getRegion(name);
+
+            region(items);
+        },
+
+        /**
+         * Requests specified components to insert
+         * them into 'elems' array starting from provided position.
+         *
+         * @param {String} elem - Name of the component to insert.
+         * @param {Number} [position=-1] - Position at which to insert elements.
+         * @returns {Component} Chainable.
+         */
+        insert: function (elem, position) {
+            reserve(this._elems, elem, position);
+            registry.get(elem, this._insert);
+
+            return this;
+        },
+
+        /**
+         * Removes specified element from the 'elems' array.
+         *
+         * @param {Object} elem - Element to be removed.
+         * @returns {Component} Chainable.
+         */
+        remove: function (elem) {
+            utils.remove(this._elems, elem);
+            this._update();
+
+            return this;
+        },
+
+        /**
+         * Destroys current instance along with all of its' children.
+         */
+        destroy: function () {
+            this._dropHandlers()
+                ._clearData()
+                ._clearRefs();
+        },
+
+        /**
+         * Removes events listeners.
+         * @private
+         *
+         * @returns {Component} Chainable.
+         */
+        _dropHandlers: function () {
+            this.off();
+
+            this.source.off(this.name);
+
+            return this;
+        },
+
+        /**
+         * Clears all data associated with component.
+         * @private
+         *
+         * @returns {Component} Chainable.
+         */
+        _clearData: function () {
+            this.source.remove(this.dataScope);
+            this.source.remove('params.' + this.name);
+
+            return this;
+        },
+
+        /**
+         * Removes all references to current instance and
+         * calls 'destroy' method on all of its' children.
+         * @private
+         *
+         * @returns {Component} Chainable.
+         */
+        _clearRefs: function () {
+            registry.remove(this.name);
+
+            this.containers.forEach(function (parent) {
+                parent.remove(this);
+            }, this);
+
+            this.elems().forEach(function (child) {
+                child.destroy();
+            });
+
+            return this;
+        },
+
+        /**
+         * Inserts provided component into 'elems' array at a specified position.
+         * @private
+         *
+         * @param {Object} elem - Element to insert.
+         */
+        _insert: function (elem) {
+            var index = this._elems.indexOf(elem.name);
+
+            if (!~index) {
+                return;
+            }
+
+            this._elems[index] = elem;
+
+            this._update()
+                .initElement(elem);
+        },
+
+        /**
+         * Synchronizes multiple elements arrays with a core '_elems' container.
+         * Performs elemets grouping by theirs 'displayArea' property.
+         * @private
+         *
+         * @returns {Component} Chainable.
+         */
+        _update: function () {
+            var _elems = compact(this._elems),
+                grouped = _.groupBy(_elems, 'displayArea');
+
+            _.each(grouped, this.updateRegion, this);
+
+            this.elems(_elems);
+
+            return this;
+        }
+    };
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/component/traversal.js b/app/code/Magento/Ui/view/base/web/js/lib/component/traversal.js
new file mode 100644
index 0000000000000000000000000000000000000000..d94770d90f9e888b0ff08869c268663064e0c9d1
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/lib/component/traversal.js
@@ -0,0 +1,76 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+    'underscore',
+    'Magento_Ui/js/lib/events'
+], function (_, EventsBus) {
+    'use strict';
+
+    return _.extend({}, EventsBus, {
+        /**
+         * Tries to call specified method of a current component,
+         * otherwise delegates attempt to its' children.
+         *
+         * @param {String} target - Name of the method.
+         * @param [...] Arguments that will be passed to method.
+         * @returns {*} Result of the method calls.
+         */
+        delegate: function (target) {
+            var args = _.toArray(arguments);
+
+            target = this[target];
+
+            if (_.isFunction(target)) {
+                return target.apply(this, args.slice(1));
+            }
+
+            return this._delegate(args);
+        },
+
+        /**
+         * Calls 'delegate' method of all of it's children components.
+         * @private
+         *
+         * @param {Array} args - An array of arguments to pass to the next delegation call.
+         * @returns {Array} An array of delegation resutls.
+         */
+        _delegate: function (args) {
+            var result;
+
+            result = this.elems.map(function (elem) {
+                return elem.delegate.apply(elem, args);
+            });
+
+            return _.flatten(result);
+        },
+
+        /**
+         * Overrides 'EventsBus.trigger' method to implement events bubbling.
+         *
+         * @param {String} name - Name of the event.
+         * @param [...] Any number of arguments that should be to the events' handler.
+         * @returns {Boolean} False if event bubbling was canceled.
+         */
+        trigger: function () {
+            var args = _.toArray(arguments),
+                bubble = EventsBus.trigger.apply(this, args),
+                result;
+
+            if (!bubble) {
+                return false;
+            }
+
+            this.containers.forEach(function (parent) {
+                result = parent.trigger.apply(parent, args);
+
+                if (result === false) {
+                    bubble = false;
+                }
+            });
+
+            return !!bubble;
+        }
+    });
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/data_provider.js b/app/code/Magento/Ui/view/base/web/js/lib/data_provider.js
deleted file mode 100644
index 281f6afa6a5fa379063368469064c96d19556041..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/js/lib/data_provider.js
+++ /dev/null
@@ -1,113 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-define([
-    'underscore',
-    './rest',
-    'Magento_Ui/js/lib/storage/index',
-    'Magento_Ui/js/lib/class',
-    'Magento_Ui/js/lib/events'
-], function(_, Rest, storages, Class, EventsBus) {
-    'use strict';
-    
-    var defaults = {
-        stores: ['config', 'meta', 'data', 'params', 'dump']
-    };
-
-    var DataProvider = Class.extend({
-        /**
-         * Initializes DataProvider instance.
-         * @param {Object} settings - Settings to initialize object with.
-         */
-        initialize: function(settings) {
-            _.extend(this, defaults, settings);
-
-            this.initStorages()
-                .initClient();
-        },
-
-        /**
-         * Creates instances of storage objects.
-         * @returns {DataProvider} Chainable.
-         */
-        initStorages: function() {
-            var storage,
-                config;
-
-            this.stores.forEach(function(store) {
-                storage = storages[store];
-                config  = this[store];
-
-                this[store] = new storage(config);
-            }, this);
-
-            return this;
-        },
-
-        /**
-         * Creates instances of a REST client.
-         * @returns {DataProvider} Chainable.
-         */
-        initClient: function() {
-            var config = this.config.get('client');
-
-            this.client = new Rest(config);
-
-            this.client.on('read', this.onRead.bind(this));
-
-            return this;
-        },
-
-        /**
-         * Tries to retrieve data from server using REST client.
-         * Allways attaches cached parameters to request.
-         * @param {Object} [options] - Additional paramters to be attached. 
-         * @returns {DataProvider} Chainable.
-         */
-        refresh: function(options) {
-            var stored = this.params.get(),
-                params = _.extend({}, stored, options || {});
-
-            this.trigger('beforeRefresh');
-            this.client.read(params);
-
-            return this;
-        },
-
-        /**
-         * Updates list of storages with a specified data.
-         * @param {Object} data - Data to update storages with.
-         * @returns {DataProvider} Chainable.
-         */
-        updateStorages: function(data) {
-            var value;
-
-            this.stores.forEach(function(store) {
-                value = data[store];
-
-                if(value){
-                    this[store].set(value);
-                }
-            }, this);
-
-            return this;
-        },
-
-        /**
-         * Callback method that fires when REST client
-         * will resolve requets to the server.
-         * @param {Object} result - Server response.
-         */
-        onRead: function(result) {
-            result = {
-                data: result.data
-            };
-
-            this.updateStorages(result)
-                .trigger('refresh', result);
-        }
-    }, EventsBus);
-    
-    return DataProvider;
-});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/deferred_events.js b/app/code/Magento/Ui/view/base/web/js/lib/deferred_events.js
deleted file mode 100644
index 3b9dbd90425927e8d82a83fddbaa47930eca01d8..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/js/lib/deferred_events.js
+++ /dev/null
@@ -1,78 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-define([
-    'jquery',
-    './events'
-], function ($, EventBus) {
-    'use strict';
-
-    var events = {};
-
-    function isResolved(promise) {
-        return promise.state() === 'resolved';
-    };
-
-    function toArray(obj, from) {
-        return Array.prototype.slice.call(obj, from || 0);
-    };
-
-    function on(context, name, callback) {
-        return EventBus.on.call(context, name, callback);
-    };
-
-    function trigger(name) {
-        return EventBus.trigger.apply(this, toArray(arguments));
-    };
-
-    function getStorage(name) {
-        return events[name] || {};
-    };
-
-    function getCallbacks(name) {
-        var storage = getStorage(name);
-        return storage.callbacks || [];
-    };
-
-    return {
-        when: function (name, callback) {
-            var storage   = events[name]      = getStorage(name),
-                callbacks = storage.callbacks = getCallbacks(name),
-                promise   = storage.promise   = storage.promise || $.Deferred(),
-                args      = toArray(arguments),
-                resolveArgs;
-
-            if (isResolved(promise)) {
-                return on(this, name, callback);
-            }
-
-            if (~!callbacks.indexOf(callback)) {
-                callbacks.push(callback);
-            }
-
-            promise.done(function () {
-
-                callback.apply(this, arguments);
-                on(this, name, callback);
-
-            }.bind(this));
-
-            return this;
-        },
-
-        resolve: function (name) {
-            var args    = toArray(arguments, 1),
-                storage = events[name]    = getStorage(name),
-                promise = storage.promise = storage.promise || $.Deferred();
-
-            if (isResolved(promise)) {
-                return trigger.bind(this, name).apply(this, args);
-            }
-
-            promise.resolve.apply(promise, args);
-
-            return this;
-        }
-    }
-});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/events.js b/app/code/Magento/Ui/view/base/web/js/lib/events.js
index 00cb42852122575ecfb5a565f69d02e42432956d..7a8be3f5ad51a81ae69b5f2286978da3ed45b73a 100644
--- a/app/code/Magento/Ui/view/base/web/js/lib/events.js
+++ b/app/code/Magento/Ui/view/base/web/js/lib/events.js
@@ -4,7 +4,7 @@
  */
 define([
     'underscore'
-], function(_) {
+], function (_) {
     'use strict';
 
     function addHandler(events, ns, callback, name) {
@@ -20,19 +20,19 @@ define([
         return name ? events[name] : events;
     }
 
-    function keepHandler(ns, handler){
-        if(!ns){
+    function keepHandler(ns, handler) {
+        if (!ns) {
             return false;
         }
 
         return handler.ns !== ns;
     }
 
-    function trigger(handlers, args){
-        var bubble  = true,
+    function trigger(handlers, args) {
+        var bubble = true,
             callback;
 
-        handlers.forEach(function(handler){
+        handlers.forEach(function (handler) {
             callback = handler.callback;
 
             if (callback.apply(null, args) === false) {
@@ -46,10 +46,9 @@ define([
     return {
         /**
          * Calls callback when name event is triggered.
-         * @param  {String}     events
-         * @param  {Function}   callback
-         * @param  {Function}   ns
-         * @return {Object}     reference to this
+         * @param  {String}   events
+         * @param  {Function} callback
+         * @return {Object} reference to this
          */
         on: function (events, callback, ns) {
             var storage = getEvents(this),
@@ -69,20 +68,20 @@ define([
         },
 
         /**
-         * Removed callback from listening to target events
+         * Removed callback from listening to target event
          * @param  {String} ns
          * @return {Object} reference to this
          */
         off: function (ns) {
             var storage = getEvents(this),
-                filter  = keepHandler.bind(null, ns);
+                filter = keepHandler.bind(null, ns);
 
             _.each(storage, function (handlers, name) {
                 handlers = handlers.filter(filter);
 
                 handlers.length ?
-                    (storage[name] = handlers) :
-                    (delete storage[name]);
+                    storage[name] = handlers :
+                    delete storage[name];
             });
 
             return this;
@@ -95,9 +94,13 @@ define([
          */
         trigger: function (name) {
             var handlers = getEvents(this, name),
-                args     = _.toArray(arguments).slice(1);
+                args = _.toArray(arguments).slice(1);
+
+            if (_.isUndefined(handlers)) {
+                return true;
+            }
 
-            return _.isUndefined(handlers) || trigger(handlers, args);
+            return trigger(handlers, args);
         }
     };
 });
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/ko/bind/date.js b/app/code/Magento/Ui/view/base/web/js/lib/ko/bind/date.js
deleted file mode 100644
index ae14f38dd4d5f873641e5d919e2a36063a2e6699..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/js/lib/ko/bind/date.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-define([
-    'ko',
-    'moment',
-    'jquery',
-    'date-format-normalizer'
-], function(ko, moment, $, convert) {
-    'use strict';
-
-    ko.bindingHandlers.date = {
-
-        /**
-         * Reads passed date and format from valueAccessor, uses convert function to format it.
-         * Writes date to el.innerText using jQuery
-         * @param {HTMLElement} el - Element, that binding is applied to
-         * @param {Function} valueAccessor - Function that returns value, passed to binding
-         */
-        init: function(element, valueAccessor) {
-            var config = valueAccessor(),
-                format = convert(config.format),
-                date   = moment(config.value).format(format);
-
-            $(element).text(date);
-        }
-    };
-});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/ko/bind/outer_click.js b/app/code/Magento/Ui/view/base/web/js/lib/ko/bind/outer_click.js
index ec2823c793be641c03c0bef8f3acd901532e1756..843c126b663413058238b86dc03e5f82d2622f14 100644
--- a/app/code/Magento/Ui/view/base/web/js/lib/ko/bind/outer_click.js
+++ b/app/code/Magento/Ui/view/base/web/js/lib/ko/bind/outer_click.js
@@ -9,6 +9,14 @@ define([
 ], function (ko, $) {
     'use strict';
 
+    function clickWrapper(elem, callback, e) {
+        var target = e.target;
+
+        if (target !== elem && !elem.contains(target)) {
+            callback();
+        }
+    }
+
     ko.bindingHandlers.outerClick = {
 
         /**
@@ -19,15 +27,17 @@ define([
          * @param  {Object} viewModel - reference to viewmodel
          */
         init: function (element, valueAccessor, allBindings, viewModel) {
-            var callback = valueAccessor();
+            var callback = valueAccessor(),
+                wrapper;
 
             callback = callback.bind(viewModel);
+            wrapper = clickWrapper.bind(null, element, callback);
 
-            $(document).on('click', callback);
+            $(document).on('click', wrapper);
 
             ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
-                $(document).off('click', callback);
+                $(document).off('click', wrapper);
             });
         }
-    }
-});
\ No newline at end of file
+    };
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/ko/initialize.js b/app/code/Magento/Ui/view/base/web/js/lib/ko/initialize.js
index b8c32c121da6aa20930c724b511cc6084cb405ee..a2e303c11fe436872229169724caf8459b3fc60d 100644
--- a/app/code/Magento/Ui/view/base/web/js/lib/ko/initialize.js
+++ b/app/code/Magento/Ui/view/base/web/js/lib/ko/initialize.js
@@ -6,12 +6,10 @@
 define([
     'ko',
     './template/engine',
-    './bind/date',
     './bind/scope',
     './bind/datepicker',
     './bind/stop_propagation',
     './bind/outer_click',
-    './bind/class',
     './bind/keyboard',
     './bind/optgroup',
     './extender/observable_array'
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/ko/scope.js b/app/code/Magento/Ui/view/base/web/js/lib/ko/scope.js
deleted file mode 100644
index 65ee522bc2af1301ee2c3ca6726765546c581a6b..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/js/lib/ko/scope.js
+++ /dev/null
@@ -1,104 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-define([
-    'ko',
-    'underscore',
-    '../class',
-    './initialize'
-], function(ko, _, Class) {
-    'use strict';
-
-    /**
-     * Wrapper for ko.observable and ko.observableArray.
-     * Assignes one or another ko property to obj[key]
-     * @param  {Object} obj   - object to store property to
-     * @param  {String} key   - key
-     * @param  {*} value      - initial value of observable
-     */
-    function observe(obj, key, value){
-        var method = Array.isArray(value) ? 'observableArray' : 'observable';
-
-        obj[key] = ko[method](value);
-    }
-
-    return Class.extend({
-
-        /**
-         * If 2 params passed, path is considered as key.
-         * Else, path is considered as object.
-         * Assignes props to this based on incoming params
-         * @param  {Object|String} path
-         * @param  {*} value
-         */
-        observe: function(path, value) {
-            var type = typeof path;
-
-            if(arguments.length === 1){
-                if(type === 'string'){
-                    path = path.split(' ');
-                }
-
-                if(Array.isArray(path)){
-                    path.forEach(function(key){
-                        observe(this, key, this[key]);
-                    }, this);
-                }
-                else if(type==='object'){
-                    _.each(path, function(value, key){
-                        observe(this, key, value);
-                    }, this);
-                }
-            }
-            else if(type === 'string') {
-                observe(this, path, value);
-            }
-
-            return this;
-        },
-
-        /**
-         * Reads it's params from provider and stores it into its params object
-         * @return {Object} reference to instance
-         */
-        pushParams: function(){
-            var params      = this.params,
-                provider    = this.provider.params,
-                data        = {};
-
-            params.items.forEach(function(name) {
-                data[name] = this[name]();
-            }, this);
-
-            provider.set(params.dir, data);
-
-            return this;
-        },
-
-        /**
-         * Loops over params.items and writes it's corresponding {key: value} 
-         * pairs to this as observables.
-         * @return {Object} reference to instance
-         */
-        pullParams: function(){
-            var params      = this.params,
-                provider    = this.provider.params,
-                data        = provider.get(params.dir);
-
-            params.items.forEach(function(name) {
-                this[name](data[name]);
-            }, this);
-
-            return this;
-        },
-
-        /**
-         * Calls pushParams and calls refresh on this.provider
-         */
-        reload: function() {
-            this.pushParams()
-                .provider.refresh();
-        }
-    });
-});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/ko/template/engine.js b/app/code/Magento/Ui/view/base/web/js/lib/ko/template/engine.js
index eee3e1c6c08d2f8c0c7bc0948eab8e06e0dc3883..647cc2b985972513ce70f29d6b68d0774cb3a52d 100644
--- a/app/code/Magento/Ui/view/base/web/js/lib/ko/template/engine.js
+++ b/app/code/Magento/Ui/view/base/web/js/lib/ko/template/engine.js
@@ -5,9 +5,8 @@
 define([
     'ko',
     './observable_source',
-    '../../renderer/renderer',
-    'mage/apply/main'
-], function (ko, Source, Renderer, Mage) {
+    '../../renderer/renderer'
+], function (ko, Source, Renderer) {
     'use strict';
 
     var sources = {};
@@ -27,7 +26,7 @@ define([
     /**
      * Remote template engine class. Is used to be able to load remote templates via knockout template binding.
      */
-    var RemoteTemplateEngine = function() {};
+    var RemoteTemplateEngine = function () {};
     var NativeTemplateEngine = ko.nativeTemplateEngine;
 
     RemoteTemplateEngine.prototype = new NativeTemplateEngine;
@@ -42,9 +41,8 @@ define([
      * @param  {Object} options - options, passed to template binding
      * @return {TemplateSource} - object with methods 'nodes' and 'data'.
      */
-    RemoteTemplateEngine.prototype.makeTemplateSource = function(template, templateDocument, options) {
+    RemoteTemplateEngine.prototype.makeTemplateSource = function (template, templateDocument, options) {
         var source,
-            extenders = options.extenders || [],
             templateId;
 
         if (typeof template === 'string') {
@@ -55,9 +53,8 @@ define([
                 source = new Source(template);
                 sources[templateId] = source;
 
-                Renderer.render(template, extenders).done(function(rendered) {
+                Renderer.render(template).done(function (rendered) {
                     source.nodes(rendered);
-                    Mage.apply();
                 });
             }
 
@@ -99,4 +96,4 @@ define([
     };
 
     return new RemoteTemplateEngine;
-});
\ No newline at end of file
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/loader.js b/app/code/Magento/Ui/view/base/web/js/lib/loader.js
index 9949551220945a95b6b89ce08cfede0223be30ac..03d97b399d7130727a01ff43eb4264dfa3b82d72 100644
--- a/app/code/Magento/Ui/view/base/web/js/lib/loader.js
+++ b/app/code/Magento/Ui/view/base/web/js/lib/loader.js
@@ -11,26 +11,17 @@ define([
     /**
      * Formats path of type "path.to.template" to RequireJS compatible
      * @param  {String} path
-     * @returns {String} - formatted template path
+     * @return {String} - formatted template path
      */
     function formatTemplatePath(path) {
         return 'text!' + path.replace(/^([^\/]+)/g, '$1/template') + '.html';
     }
 
-    /**
-     * Waits for all items in passed array of promises to resolve.
-     * @param  {Array} promises - array of promises
-     * @returns {Deferred} - promise of promises to resolve
-     */
-    function waitFor(promises) {
-        return $.when.apply($, promises);
-    }
-
     /**
      * Removes license from incoming template
      *
      * @param  {String} tmpl
-     * @returns {String} - template without license
+     * @return {String} - template without license
      */
     function removeLicense(tmpl) {
         var regEx = /<!--[\s\S]*?-->/;
@@ -44,7 +35,7 @@ define([
      * Loads template by path, resolves promise with it if defined
      *
      * @param  {String} path
-     * @params  {Deferred} promise
+     * @param  {Deferred} promise
      */
     function load(path, promise) {
         require([path], function (template) {
@@ -59,12 +50,11 @@ define([
          * Loops over arguments and loads template for each.
          * @return {Deferred} - promise of templates to be loaded
          */
-        loadTemplate: function () {
-            var isLoaded = $.Deferred(),
-                templates = _.toArray(arguments);
+        loadTemplate: function (source) {
+            var isLoaded = $.Deferred();
 
-            waitFor(templates.map(this._loadTemplate)).done(function () {
-                isLoaded.resolve.apply(isLoaded, arguments);
+            this._loadTemplate(source).done(function (tmpl) {
+                isLoaded.resolve(tmpl);
             });
 
             return isLoaded.promise();
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/mixins/loader.js b/app/code/Magento/Ui/view/base/web/js/lib/mixins/loader.js
deleted file mode 100644
index 4e310b1ca86a992706cbc98941cf7d09075eae9e..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/js/lib/mixins/loader.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-define([
-    'Magento_Ui/js/lib/spinner'
-], function (spinner) {
-    'use strict';
-
-    return {
-        /**
-         * Activates spinner
-         * @return {Object} reference to instance
-         */
-        lock: function() {
-            spinner.show();
-
-            return this;
-        },
-
-        /**
-         * Deactivates spinner
-         * @return {Object} reference to instance
-         */
-        unlock: function() {
-            spinner.hide();
-
-            return this;
-        }
-    }
-});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/provider.js b/app/code/Magento/Ui/view/base/web/js/lib/provider.js
index 66454fee11c9bf0b5cdba395fe36c320f183d173..dafb8ad304893a957e261fabb503af434a79fe30 100644
--- a/app/code/Magento/Ui/view/base/web/js/lib/provider.js
+++ b/app/code/Magento/Ui/view/base/web/js/lib/provider.js
@@ -3,43 +3,92 @@
  * See COPYING.txt for license details.
  */
 define([
-    'jquery',
-    './data_provider',
-    'Magento_Ui/js/lib/registry/registry'
-], function($, DataProvider, registry) {
+    'underscore',
+    'mageUtils',
+    'Magento_Ui/js/lib/class',
+    'Magento_Ui/js/lib/events'
+], function (_, utils, Class, EventsBus) {
     'use strict';
 
-    /**
-     * Merges passed settings with preset ajax properties
-     * @param  {Object} settings
-     * @returns {Object} - mutated settings
-     */
-    function getConfig(settings) {
-        var config = settings.config,
-            client = config.client = config.client || {};
-
-        $.extend(true, client, {
-            ajax: {
-                data: {
-                    name: settings.name,
-                    form_key: FORM_KEY
-                }
-            }
-        });
+    function getStored(ns) {
+        var stored = localStorage.getItem(ns);
 
-        return settings;
+        return !_.isNull(stored) ? JSON.parse(stored) : {};
     }
 
-    /**
-     * Creates new data provider and register it by settings.name 
-     * @param {Object} settings
-     */
-    function init(settings) {
-        var name    = settings.name,
-            config  = getConfig(settings);
+    function store(ns, property, data) {
+        var stored = getStored(ns);
+
+        utils.nested(stored, property, data);
 
-        registry.set(name, new DataProvider(config));
+        localStorage.setItem(ns, JSON.stringify(stored));
     }
 
-    return init;
-});
\ No newline at end of file
+    var Provider = _.extend({
+        /**
+         * Initializes DataProvider instance.
+         * @param {Object} config - Settings to initialize object with.
+         */
+        initialize: function (config) {
+            _.extend(this.data = {}, config);
+
+            this.restore();
+
+            return this;
+        },
+
+        /**
+         * If path specified, returnes this.data[path], else returns this.data
+         * @param  {String} path
+         * @return {*} this.data[path] or simply this.data
+         */
+        get: function (path) {
+            return utils.nested(this.data, path);
+        },
+
+        /**
+         * Sets value property to path and triggers update by path, passing result
+         * @param {String|*} path
+         * @param {String|*} value
+         * @return {Object} reference to instance
+         */
+        set: function (path, value) {
+            var data = utils.nested(this.data, path),
+                diffs = utils.compare(data, value, path);
+
+            utils.nested(this.data, path, value);
+
+            diffs.changes.forEach(function (change) {
+                this.trigger(change.name, change.value, change);
+            }, this);
+
+            _.each(diffs.containers, function (changes, name) {
+                this.trigger(name, changes);
+            }, this);
+
+            return this;
+        },
+
+        restore: function () {
+            var stored = getStored(this.data.dataScope);
+
+            utils.extend(this.data, stored);
+        },
+
+        store: function (property, data) {
+            if (!data) {
+                data = this.get(property);
+            } else {
+                this.set(property, data);
+            }
+
+            store(this.data.dataScope, property, data);
+        },
+
+        remove: function (path) {
+            utils.nestedRemove(this.data, path);
+        }
+    }, EventsBus);
+
+    return Class.extend(Provider);
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/registry/events.js b/app/code/Magento/Ui/view/base/web/js/lib/registry/events.js
index 21969f43dc8529e879a2193ee4b70892b5136a42..cf4b3b13d10936ae149320b54ec767079a0e8241 100644
--- a/app/code/Magento/Ui/view/base/web/js/lib/registry/events.js
+++ b/app/code/Magento/Ui/view/base/web/js/lib/registry/events.js
@@ -4,7 +4,7 @@
  */
 define([
     'underscore',
-    'mage/utils'
+    'mageUtils'
 ], function (_, utils) {
     'use strict';
 
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/registry/registry.js b/app/code/Magento/Ui/view/base/web/js/lib/registry/registry.js
index db002ca2a3cf703b238b514691c7c74b4534e32d..8c0448aaa49b38d71181d480df436fb3949b392e 100644
--- a/app/code/Magento/Ui/view/base/web/js/lib/registry/registry.js
+++ b/app/code/Magento/Ui/view/base/web/js/lib/registry/registry.js
@@ -3,10 +3,10 @@
  * See COPYING.txt for license details.
  */
 define([
-    'mage/utils',
+    'mageUtils',
     './storage',
     './events'
-], function (utils, Storage, Events) {
+], function(utils, Storage, Events) {
     'use strict';
 
     function Registry() {
@@ -20,21 +20,22 @@ define([
         /**
          * Retrieves data from registry.
          *
-         * @param {(String|Array)} elems - An array of elements' names or
-         *      a string of names divided by spaces.
-         * @param {Function} [callback] - Callback function that will be triggered
+         * @params {(String|Array)} elems -
+         *      An array of elements' names or a string of names divided by spaces.
+         * @params {Function} [callback] -
+         *      Callback function that will be triggered
          *      when all of the elements are registered.
          * @returns {Array|*|Undefined}
          *      Returns either an array of elements
          *      or an element itself if only is requested.
          *      If callback function is specified then returns 'undefined'.
          */
-        get: function (elems, callback) {
+        get: function(elems, callback) {
             var records;
 
             elems = utils.stringToArray(elems) || [];
 
-            if (typeof callback == 'function') {
+            if (typeof callback !== 'undefined') {
                 this.events.wait(elems, callback);
             } else {
                 records = this.storage.get(elems);
@@ -45,11 +46,12 @@ define([
             }
         },
 
-        /**
+
+       /**
          * Sets data to registry.
          *
-         * @param {String} elem - Elements' name.
-         * @param {*} value - Value that will be assigned to the element.
+         * @params {String} elems - Elements' name.
+         * @params {*} value - Value that will be assigned to the element.
          * @returns {registry} Chainable.
          */
         set: function (elem, value) {
@@ -61,8 +63,8 @@ define([
 
         /**
          * Removes specified elements from a storage.
-         * @param {(String|Array)} elems - An array of elements' names or
-         *      a string of names divided by spaces.
+         * @params {(String|Array)} elems -
+         *      An array of elements' names or a string of names divided by spaces.
          * @returns {registry} Chainable.
          */
         remove: function (elems) {
@@ -76,8 +78,8 @@ define([
        /**
          * Checks whether specified elements has been registered.
          *
-         * @param {(String|Array)} elems - An array of elements' names or
-         *      a string of names divided by spaces.
+         * @params {(String|Array)} elems -
+         *      An array of elements' names or a string of names divided by spaces.
          * @returns {Boolean}
          */
         has: function (elems) {
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/registry/storage.js b/app/code/Magento/Ui/view/base/web/js/lib/registry/storage.js
index bf701810285e24c5589f2a1f28bb39b9f56c0f55..f7d95da8b4f622aea4d1e315dc7b6ae2d462a2ad 100644
--- a/app/code/Magento/Ui/view/base/web/js/lib/registry/storage.js
+++ b/app/code/Magento/Ui/view/base/web/js/lib/registry/storage.js
@@ -19,17 +19,12 @@ define([], function () {
          * @returns {Array} Array of values.
          */
         get: function (elems) {
-            var data = this.data,
-                record;
+            var data = this.data;
 
             elems = elems || [];
 
             return elems.map(function (elem) {
-                record = data[elem];
-
-                if (record) {
-                    return record.value;
-                }
+                return data[elem];
             });
         },
 
@@ -41,10 +36,9 @@ define([], function () {
          * returns {storage} Chainable.
          */
         set: function (elem, value) {
-            var data    = this.data,
-                record  = data[elem] = data[elem] || {};
+            var data  = this.data;
 
-            record.value = value;
+            data[elem] = value;
 
             return this;
         },
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/renderer/overrides.js b/app/code/Magento/Ui/view/base/web/js/lib/renderer/overrides.js
deleted file mode 100644
index 4569fc6d34d13b4f021e475c4a12e4ad09d3c0af..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/js/lib/renderer/overrides.js
+++ /dev/null
@@ -1,92 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-define(['jquery'], function($) {
-    'use strict';
-
-    return {
-
-        /**
-         * Removes passed html element.
-         * @param  {HTMLElement} oldPart - html element to remove
-         */
-        remove: function(oldPart) {
-            $(oldPart).remove();
-        },
-
-        /**
-         * Picks last node of newParts and replaces oldPart node with it.
-         * @param  {HTMLElement} oldPart  - html element to replace
-         * @param  {Array} newParts - array of html elements 
-         */
-        replace: function(oldPart, newParts) {
-            var newPart = _.last(newParts);
-
-            $(oldPart).replaceWith(newPart);
-        },
-
-        /**
-         * Picks last node of newParts and replaces oldPart node with it's children.
-         * @param  {HTMLElement} oldPart  - html element to replace
-         * @param  {HTMLElement} newParts - array of html elements 
-         */
-        body: function(oldPart, newParts) {
-            var newPart = _.last(newParts);
-
-            $(oldPart).replaceWith(newPart.children);
-        },
-
-        /**
-         * Picks the last item of newParts array and overides oldPart's html attributes with ones of it's own.
-         * @param  {HTMLElement} oldPart - target html element to update
-         * @param  {Array} newParts - array of html elements to get attributes from
-         */
-        update: function(oldPart, newParts) {
-            var newPart = _.last(newParts);
-
-            var attributes = newPart.attributes;
-            var value, name;
-
-            _.each(attributes, function(attr) {
-                value = attr.value;
-                name = attr.name;
-
-                if (attr.name.indexOf('data-part') !== -1) {
-                    return;
-                }
-
-                $(oldPart).attr(name, value);
-            });
-        },
-
-        /**
-         * Prepends oldPart with each html element's children from newParts array.
-         * @param  {HTMLElement} oldPart - html element to prepend to
-         * @param  {Array} newParts - array of html elements to get attributes from
-         */
-        prepend: function(oldPart, newParts) {
-            newParts.forEach(function (node) {
-                $(oldPart).prepend(node.children);
-            });
-        },
-
-        /**
-         * Appends oldPart with each html element's children from newParts array.
-         * @param  {HTMLElement} oldPart - html element to append to
-         * @param  {Array} newParts - array of html elements to get attributes from
-         */
-        append: function(oldPart, newParts) {
-            newParts.forEach(function (node) {
-                $(oldPart).append(node.children);
-            });
-        },
-
-        /**
-         * @return {Array} - array of strings representing available set of actions
-         */
-        getActions: function() {
-            return 'replace remove body update append prepend'.split(' ');
-        }
-    };
-});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/renderer/renderer.js b/app/code/Magento/Ui/view/base/web/js/lib/renderer/renderer.js
index 3237dfd4ffef689634a37860f0a10941c5ab2c0e..9da1291111f07e421eb1f41ca8b1ee6aa67bf1bb 100644
--- a/app/code/Magento/Ui/view/base/web/js/lib/renderer/renderer.js
+++ b/app/code/Magento/Ui/view/base/web/js/lib/renderer/renderer.js
@@ -4,53 +4,28 @@
  */
 define([
     '../loader',
-    './overrides',
     'jquery',
     'underscore'
-], function(loader, overrides, $, _) {
+], function (loader, $, _) {
     'use strict';
 
     return {
-
         /**
          * Renders template and it's extenders using this._parse function.
          * Loads all extenders then merges them and wraps into div[data-template-extend="parent"] where parent is target template.
          * If no extenders provider, simply loads target template and passes execution to _parse.
          * @param {String} template - string, representing path to core template and it's extenders.
-         * @param {Array} extenders - array of strings
-         * @return {Deferred} - Promise of template to be rendered. Is being resolved with array of HTML elements.
+         * @returns {Deferred} - Promise of template to be rendered. Is being resolved with array of HTML elements.
          */
-        render: function (template, extenders) {
+        render: function (template) {
             var isRendered = $.Deferred(),
-                parent = template,
-
-                extenders = extenders || [],
-                extendersToLoad = [],
-                extendersHtml = '',
-
                 resolve       = isRendered.resolve.bind(isRendered),
                 loadTemplate  = this._load.bind(this),
                 parseTemplate = this._parse.bind(this);
 
-            if (extenders.length) {
-
-                loadTemplate.apply(this, extenders).done(function () {
-
-                    toArray(arguments).forEach(function (chunk) {
-                        extendersHtml += chunk;
-                    });
-
-                    extendersHtml = '<div data-template-extend="' + parent+ '">' + extendersHtml + '</div>';
-
-                    parseTemplate(extendersHtml).done(resolve);
-
-                }); 
-            } else {
-
-                loadTemplate(parent)
-                    .then(parseTemplate)
-                    .done(resolve);
-            }
+            loadTemplate(template)
+                .then(parseTemplate)
+                .done(resolve);
 
             return isRendered.promise();
         },
@@ -73,186 +48,8 @@ define([
          * @param  {String} rawHtml - loaded raw text (html)
          * @return {Deferred} - Promise of template to be parsed. Is being resolved with array of HTML elements.
          */
-        _parse: function(rawHtml) {
-            var templatePath,
-                templateContainer,
-                extendNodes,
-                templatesToRender = [],
-                extendPointsToRender = [];
-
-            templateContainer = document.createElement('div');
-
-            wrap(toArray($.parseHTML(rawHtml)), templateContainer);
-
-            extendNodes          = getExtendNodesFrom(templateContainer);
-            templatesToRender    = extendNodes.map(extractTemplatePath, this)
-            extendPointsToRender = templatesToRender.map(this.render, this);
-
-            return waitFor(extendPointsToRender).then(function() {
-                var correspondingExtendNode,
-                    container,
-                    newParts = [],
-                    args = toArray(arguments);
-
-                args.forEach(function(renderedNodes, idx) {
-                    container = document.createElement('div');
-                    wrap(renderedNodes, container);
-
-                    correspondingExtendNode = extendNodes[idx];
-                    newParts = this._buildPartsMapFrom(correspondingExtendNode);
-
-                    $(correspondingExtendNode).empty();
-
-                    this._overridePartsOf(container, newParts)
-                        .replace(correspondingExtendNode);
-
-                }, this);
-
-                return toArray(templateContainer.childNodes);
-            }.bind(this));
-        },
-
-        /**
-         * Builds parst map from HTML element by looking for all available override actions selectors.
-         * @param  {HTMLElement} container - container to look up for new parts declarations
-         * @return {Object} - Map of parts to apply. E.g. { toolbar: { replace: [HTMLElement1, HTMLElement2], append: [HTMLElement3] } }
-         */
-        _buildPartsMapFrom: function(container) {
-            var partsMap = {},
-                actionNodes,
-                partSelector,
-                targetPart,
-                actions = overrides.getActions();
-
-            actions.forEach(function(action) {
-                partSelector = createActionSelectorFor(action);
-                actionNodes  = toArray(container.querySelectorAll(partSelector));
-
-                actionNodes.forEach(function(node) {
-                    targetPart = node.getAttribute('data-part-' + action);
-
-                    if (!partsMap[targetPart]) {
-                        partsMap[targetPart] = {};
-                    }
-
-                    targetPart = partsMap[targetPart];
-
-                    if (!targetPart[action]) {
-                        targetPart[action] = [];
-                    }
-
-                    targetPart[action].push(node);
-                });
-            });
-
-            return partsMap;
-        },
-
-        /**
-         * Loops over newParts map and invokes override actions for each found.
-         * @param  {HTMLElement} template - container to look for parts to be overrided by new ones.
-         * @param  {Object} newParts - the result of _buildPartsMapFrom method.
-         * @return {Object}
-         */
-        _overridePartsOf: function(template, newParts) {
-            var oldElement;
-
-            _.each(newParts, function(actions, partName) {
-                _.each(actions, function(newElements, action) {
-
-                    oldElement = template.querySelector(createPartSelectorFor(partName));
-                    overrides[action](
-                        oldElement,
-                        newElements
-                    );
-
-                });
-            });
-
-            return {
-
-                /**
-                 * Replaces extendNode with the result of overrides
-                 * @param  {HTMLElement} extendNode - initial container of new parts declarations
-                 */
-                replace: function(extendNode) {
-                    $(extendNode).replaceWith(template.childNodes);
-                }
-            }
+        _parse: function (rawHtml) {
+            return _.toArray($.parseHTML(rawHtml));
         }
     };
-
-    /**
-     * Extracts template path from node by [data-part-extend] attribute
-     * @param  {HTMLElement} node - node to look up for [data-part-extend] attr
-     * @return {String} - value of [data-part-extend] attribute
-     */
-    function extractTemplatePath(node) {
-        return node.getAttribute('data-template-extend');
-    }
-
-    /**
-     * Looks up for [data-template-extend] selector in container.
-     * @param  {HTMLElement} container - node to lookup
-     * @return {Array} - array of found HTML elements
-     */
-    function getExtendNodesFrom(container) {
-        return toArray(container.querySelectorAll('[data-template-extend]'))
-    }
-
-    /**
-     * Checks if passed object has keys.
-     * @param  {Object}  object - target object
-     * @return {Boolean} - true, if object has no keys
-     */
-    function isEmpty(object) {
-        return !Object.keys(object).length;
-    }
-
-    /**
-     * Wraps nodes into container
-     * @param  {Array} nodes - array of nodes
-     * @param  {HTMLElement} container - target container
-     */
-    function wrap(nodes, container) {
-        nodes.forEach(function (node) {
-            container.appendChild(node);
-        });
-    }
-
-    /**
-     * Creates action selector.
-     * @param  {String} action
-     * @return {String} - Action selector
-     */
-    function createActionSelectorFor(action) {
-        return '[data-part-' + action + ']';
-    }
-
-    /**
-     * Creates data-part selector.
-     * @param  {String} part
-     * @return {String} - Part selector
-     */
-    function createPartSelectorFor(part) {
-        return '[data-part="' + part + '"]';
-    }
-
-    /**
-     * Converts arrayLikeObject to array
-     * @param  {Object|Array} arrayLikeObject - target
-     * @return {Array} - result array
-     */
-    function toArray(arrayLikeObject) {
-        return Array.prototype.slice.call(arrayLikeObject);
-    }
-
-    /**
-     * Waits for all items in passed array of promises to resolve.
-     * @param  {Array} promises - array of promises
-     * @return {Deferred} - promise of promises to resolve
-     */
-    function waitFor(promises) {
-        return $.when.apply(this, promises);
-    }
-});
\ No newline at end of file
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/request_builder.js b/app/code/Magento/Ui/view/base/web/js/lib/request_builder.js
deleted file mode 100644
index a70d13af32c6450cce6825bd10e81218db2a2055..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/js/lib/request_builder.js
+++ /dev/null
@@ -1,141 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-/**
- * @returns {Function} Request builder function.
- */
-define([
-    'Magento_Ui/js/lib/utils'
-], function(utils) {
-    'use strict';
-
-    /**
-     * @param {String} - name of params set
-     * @param {Object} - params to convert
-     * @returns {String} - concatenated name/params pairs by custom logic and separator
-     * @private
-     */
-    function parseObject(name, value) {
-        var key,
-            result = [];
-
-        for (key in value) {
-            result.push(name + '[' + key + ']' + '=' + value[key])
-        }
-
-        return result.join('&');
-    }
-
-    /**
-     * @param {String} - name of property
-     * @param {String} - corresponding value
-     * @returns {String} - concatenated params by separator "="
-     * @private
-     */
-    function parseValue(name, value) {
-        return name + '=' + value;
-    }
-
-    /**
-     * Extracts sorting parameters from object and returns string representation of it.
-     * @param {Object} param - Sorting parameters object, e.g. { field: 'field_to_sort', dir: 'asc' }.
-     * @returns {String} - Chunk of url string that represents sorting params
-     * @private
-     */
-    function extractSortParams(params) {
-        var result,
-            sorting = params.sorting;
-
-        if (typeof sorting === 'undefined') {
-            return '';
-        }
-
-        result = '/sort/' + sorting.field + '/dir/' + sorting.direction;
-
-        delete params.sorting;
-
-        return result;
-    }
-
-    /**
-     * Extracts pager parameters from an object and returns it's string representation.
-     * @param {Object} params which contains "paging" params object.
-     * @returns {String} - Chunk of url string that represents pager params
-     * @private
-     */
-    function extractPagerParams(params) {
-        var result,
-            paging = params.paging;
-
-        if (typeof paging === 'undefined') {
-            return '';
-        }
-
-        result = '/limit/' + paging.pageSize + '/page/' + paging.current;
-
-        delete params.paging;
-
-        return result;
-    }
-
-    /**
-     * Formats filter data according to the type of it's value.
-     * @param {Object} filter - filter object to format.
-     * @returns {String} - Chunk of url string that represents filter's params
-     * @private
-     */
-    function formatFilter(filter) {
-        var name = filter.field,
-            value = filter.value;
-
-        return typeof value !== 'object' ?
-            parseValue(name, value) :
-            parseObject(name, value);
-    }
-
-    /**
-     * Formats and assembles filter data.
-     * @param {Object} params - object containing "filter" array.
-     * @returns {String} - Chunk of url string that represents filters
-     * @private
-     */
-    function extractFilterParams(params) {
-        var filters,
-            result;
-
-        filters = params.filter;
-
-        if (typeof filters === 'undefined' || !filters.length) {
-            return '';
-        }
-
-        result = filters.map(formatFilter).join('&');
-
-        result = '/filter/' + utils.btoa(encodeURI(result));
-
-        delete params.filter;
-
-        return result;
-    }
-
-    return function(root, params) {
-        var url,
-            lastChar;
-
-        lastChar = root.charAt(root.length - 1);
-
-        if (lastChar === '/') {
-            root = root.substr(0, root.length - 1);
-        }
-
-        url =
-            root +
-            extractSortParams(params) +
-            extractPagerParams(params) +
-            extractFilterParams(params);
-
-        return url;
-    };
-
-});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/rest.js b/app/code/Magento/Ui/view/base/web/js/lib/rest.js
deleted file mode 100644
index 2c29c393ad314cc0ea2759fad20e0440a2c9d6f7..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/js/lib/rest.js
+++ /dev/null
@@ -1,85 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-define([
-    'underscore',
-    'jquery',
-    'Magento_Ui/js/lib/utils',
-    'Magento_Ui/js/lib/class',
-    'Magento_Ui/js/lib/events',
-    './request_builder'
-], function(_, $, utils, Class, EventsBus, requestBuilder) {
-    'use strict';
-
-    var defaults = {
-        ajax: {
-            dataType: 'json'
-        }
-    };
-
-    return Class.extend({
-        initialize: function(config) {
-            $.extend(true, this.config = {}, defaults, config);
-        },
-
-        /**
-         * Sends ajax request using params and config passed to it and calls this.config.onRead when done.
-         * @param {Object} params - request body params
-         * @param {Object} config - config to build url from
-         */
-        read: function(params, config) {
-            config = this.createConfig(params, config);
-
-            $.ajax(config)
-                .done(this.onRead.bind(this));
-        },
-
-        /**
-         * Creates config for ajax call.
-         * @param {Object} params - request body params
-         * @param {Object} config - config to build url from
-         * @returns {Object} - merged config for ajax call
-         */
-        createConfig: function(params, config) {
-            var baseConf;
-
-            config = config || {};
-            params = params || {};
-
-            baseConf = {
-                url: requestBuilder(this.config.root, params),
-                data: params
-            };
-
-            return $.extend(true, baseConf, this.config.ajax, config);
-        },
-
-        /**
-         * Callback of ajax call.
-         * Parses results and triggers read event;
-         * @param  {Object|*} result - Result of ajax call.
-         */
-        onRead: function(result){
-            result = typeof result === 'string' ?
-                JSON.parse(result) :
-                result;
-
-            this.trigger('read', result);
-        },
-
-        /**
-         * Submits data using utils.submitAsForm
-         * @param {Object} config - object containing ajax options
-         */
-        submit: function(config){
-            var ajax = this.config.ajax,
-                data = ajax.data || {};
-
-            _.extend(config.data, data);
-
-            utils.submitAsForm(config);
-        }
-    }, EventsBus);
-
-});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/spinner.js b/app/code/Magento/Ui/view/base/web/js/lib/spinner.js
index 4a9eae7d96340bd74c59b178025686c14f601723..a610c194333530d7706ceb4c15fb368807e6acc8 100644
--- a/app/code/Magento/Ui/view/base/web/js/lib/spinner.js
+++ b/app/code/Magento/Ui/view/base/web/js/lib/spinner.js
@@ -7,8 +7,8 @@ define([
 ], function ($) {
     'use strict';
 
-    var selector    = '[data-role="spinner"]',
-        spinner     = $(selector);
+    var selector = '[data-role="spinner"]',
+        spinner = $(selector);
 
     return {
         show: function () {
@@ -22,5 +22,5 @@ define([
         get: function (id) {
             return $(selector + '[data-component="' + id + '"]');
         }
-    }
-});
\ No newline at end of file
+    };
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/storage/dump.js b/app/code/Magento/Ui/view/base/web/js/lib/storage/dump.js
deleted file mode 100644
index 8c904764da3fde329e62aefac46849b762dc453e..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/js/lib/storage/dump.js
+++ /dev/null
@@ -1,10 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-define([
-    './storage',
-    'Magento_Ui/js/lib/deferred_events'
-], function (Storage, DeferredEvents) {
-    return Storage.extend({}, DeferredEvents);
-});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/storage/index.js b/app/code/Magento/Ui/view/base/web/js/lib/storage/index.js
deleted file mode 100644
index ca58235fa19b4adbc060bc76bba9be29d4711b9e..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/js/lib/storage/index.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-/**
- * Assembles storages returning storage mapping
- */
-define([
-    './storage',
-    './meta',
-    './dump'
-], function(Storage, MetaStorage, DumpStorage){
-    'use strict';
-
-    return {
-        meta:   MetaStorage,
-        params: Storage,
-        config: Storage,
-        data:   Storage,
-        dump:   DumpStorage
-    }
-});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/storage/meta.js b/app/code/Magento/Ui/view/base/web/js/lib/storage/meta.js
deleted file mode 100644
index d3cee2931c4d68da898f7dc461c23c0ce7c7e761..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/js/lib/storage/meta.js
+++ /dev/null
@@ -1,186 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-define([
-    'underscore',
-    './storage'
-], function(_, Storage) {
-    'use strict';
-
-    /**
-     * Loops over first level of object looking for valueKey of typeof object values
-     * to be typeof object as well. Breaks loop on first entry on one.
-     * @param  {Object}  target
-     * @param  {String}  valueKey - complex to look for
-     * @return {Boolean}
-     */
-    function hasComplexValue(target, valueKey) {
-        var result = false,
-            key,
-            object;
-
-
-        for (key in target) {
-            object = target[key];
-
-            if (typeof object === 'object' && typeof object[valueKey] === 'object') {
-                result = true;
-                break;
-            }
-        }
-
-        return result;
-    }
-
-    /**
-     * Recursively loops over object's properties and converts it to array ignoring keys.
-     * If typeof 'value' properties is 'object', creates 'items' property and assigns
-     * execution of nestedObjectToArray on 'value' to it.
-     * If typeof 'value' key is not an 'object', is simply writes an object itself to result array. 
-     * @param  {Object} obj
-     * @return {Array} result array
-     */
-    function nestedObjectToArray(obj, valueKey) {
-        var target,
-            items = [];
-
-        for (var prop in obj) {
-
-            target = obj[prop];
-            if (typeof target[valueKey] === 'object') {
-
-                target.items = nestedObjectToArray(target[valueKey], valueKey);
-                delete target[valueKey];
-            }
-            items.push(target);
-        }
-
-        return items;
-    }
-
-    return Storage.extend({
-
-        /**
-         * Initializes data prop based on data argument.
-         * Calls initFields and initColspan methods 
-         * @param  {Object} config
-         */
-        initialize: function(data) {
-            this.data = data || {};
-
-            this.initFields()
-                .initColspan();
-        },
-
-        /**
-         * Formats fields property to compatible format.
-         * Processes those. Assignes fiedls to data.fields.
-         * @return {Object} - reference to instance
-         */
-        initFields: function(){
-            var data    = this.data,
-                fields  = data.fields;
-
-            fields = this._fieldsToArray(fields);
-
-            fields.forEach(this._processField, this);
-
-            data.fields = fields;
-
-            return this;
-        },
-
-        /**
-         * Assigns data.colspan to this.getVisible().length
-         * @return {Object} - reference to instance
-         */
-        initColspan: function(){
-            var visible = this.getVisible();
-
-            this.data.colspan = visible.length;
-
-            return this;
-        },
-
-        /**
-         * Assignes default params to field
-         * @param  {Object} field
-         * @return {Object} reference to instance
-         */
-        applyDefaults: function(field) {
-            var defaults = this.data.defaults;
-
-            if (defaults) {
-                _.defaults(field, defaults);
-            }
-
-            return this;
-        },
-
-        /**
-         * Format options based on those being nested
-         * @param  {Object} field
-         * @return {Object} reference to instance
-         */
-        formatOptions: function(field) {
-            var result,
-                options,
-                isNested;
-
-            options = field.options;
-
-            if (options) {
-                result      = {};
-                isNested    = hasComplexValue(options, 'value');
-
-                if(isNested){
-                    result = nestedObjectToArray(options, 'value');
-                }
-                else{
-                    _.each(options, function(option){
-                        result[option.value] = option.label;
-                    }); 
-                }   
-                                
-                field.options = result;
-            }
-
-            return this;
-        },
-
-        /**
-         * Returns filted by visible property fields array.
-         * @return {Array} filted by visible property fields array
-         */
-        getVisible: function(){
-            var fields  = this.data.fields;
-            
-            return fields.filter(function(field){
-                return field.visible;
-            });
-        },
-
-        /**
-         * Convertes fields object to array, assigning key to index property.
-         * @param  {Object} fields
-         * @return {Array} array of fields
-         */
-        _fieldsToArray: function(fields){
-            return _.map(fields, function(field, id){
-                field.index = id;
-                
-                return field;
-            });
-        },
-
-        /**
-         * Calls applyDefaults and formatOptions on field
-         * @param  {Object} field
-         */
-        _processField: function(field){
-            this.applyDefaults(field)
-                .formatOptions(field);
-        }
-    });
-});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/storage/storage.js b/app/code/Magento/Ui/view/base/web/js/lib/storage/storage.js
deleted file mode 100644
index e0075c746b5466e8d48e247ea3e9dd9eea7e0588..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/js/lib/storage/storage.js
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-define([
-    'underscore',
-    '../class',
-    '../events',
-    'mage/utils'
-], function(_, Class, EventsBus, utils) {
-    'use strict';
-
-    return Class.extend({
-
-        /**
-         * Inits this.data to incoming data
-         * @param  {Object} data
-         */
-        initialize: function(data) {
-            this.data = data || {};
-        },
-
-        /**
-         * If path specified, returnes this.data[path], else returns this.data
-         * @param  {String} path
-         * @return {*} this.data[path] or simply this.data
-         */
-        get: function(path) {
-            return utils.nested(this.data, path);
-        },
-
-        /**
-         * Sets value property to path and triggers update by path, passing result
-         * @param {String|*} path
-         * @param {String|*} value
-         * @return {Object} reference to instance
-         */
-        set: function(path, value){
-            var result = this._override.apply(this, arguments);
-
-            value   = result.value;
-            path    = result.path;
-
-            this.trigger('update', value);
-
-            if (path) {
-                this.trigger('update:' + path, value);
-            }
-
-            return this;
-        },
-
-        remove: function (path) {
-            utils.nestedRemove(this.data, path);
-
-            return this;
-        },
-        
-        /**
-         * Assignes props to this.data based on incoming params
-         * @param  {String|*} path
-         * @param  {*} value
-         * @return {Object}
-         */
-        _override: function(path, value) {
-            if (arguments.length > 1) {
-                utils.nested(this.data, path, value);
-            } else {
-                value = path;
-                path = false;
-
-                this.data = value;
-            }
-
-            return {
-                path: path,
-                value: value
-            };
-        }
-
-    }, EventsBus);
-});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/utils.js b/app/code/Magento/Ui/view/base/web/js/lib/utils.js
deleted file mode 100644
index dcc7c65e3255f6663273451b11916e8bc8c43f60..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/js/lib/utils.js
+++ /dev/null
@@ -1,79 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-define([
-    'underscore',
-    'mage/utils'
-], function(_, utils) {
-    'use strict';
-
-    var utils = {},
-        atobSupport,
-        btoaSupport;
-    
-    atobSupport = typeof atob === 'function';
-    btoaSupport = typeof btoa === 'function';
-
-    /** 
-     * Base64 encoding/decoding methods.
-     * First check for native support.
-     */
-    if( btoaSupport && atobSupport ){
-         _.extend(utils, {
-            atob: function(input){
-                return window.atob(input);
-            },
-
-            btoa: function(input){
-                return window.btoa(input);
-            }
-        });
-    }
-    else{
-        _.extend(utils, {
-            atob: function(input){
-                return Base64.decode(input)
-            },
-
-            btoa: function(input){
-                return Base64.encode(input);
-            }
-        });
-    }    
-
-    /**
-     * Submits specified data as a form object.
-     * @param {Object} params - Parameters of form.
-     */
-    utils.submitAsForm = function(params){  
-        var form,
-            field;
-
-        form = document.createElement('form');
-
-        form.setAttribute('method', params.method);
-        form.setAttribute('action', params.action);
-
-        _.each(params.data, function(value, name){
-            field = document.createElement('input');
-
-            if(typeof value === 'object'){
-                value = JSON.stringify(value);
-            }
-
-            field.setAttribute('name', name);
-            field.setAttribute('type', 'hidden');
-            
-            field.value = value;
-
-            form.appendChild(field);
-        });
-
-        document.body.appendChild(form);
-
-        form.submit();
-    };
-
-    return utils;
-});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/listing/filter.js b/app/code/Magento/Ui/view/base/web/js/listing/filter.js
deleted file mode 100644
index 95f58dde2c123d688562ca465e4973f51d57b909..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/js/listing/filter.js
+++ /dev/null
@@ -1,271 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-define([
-    'underscore',
-    'Magento_Ui/js/lib/ko/scope',
-    'Magento_Ui/js/lib/component'
-], function(_, Scope, Component) {
-    'use strict';
-
-    var BASE_PATH = 'Magento_Ui/js/listing/filter';
-
-    var defaults = {
-        types: {
-            filter_input:  BASE_PATH + '/input',
-            filter_select: BASE_PATH + '/select',
-            filter_range:  BASE_PATH + '/range',
-            filter_date:   BASE_PATH + '/date'
-        }
-    };
-
-    var Filter = Scope.extend({
-        /**
-         * Initializes instance properties 
-         * @param {Object} config - Filter component configuration
-         */
-        initialize: function(config) {
-            _.extend(this, config);
-
-            this.initObservable()
-                .loadControls();
-        },
-
-        /**
-         * Callback method that proceeds initialization of filter component.
-         */
-        proceed: function () {
-            this.extractFields()
-                .initFilters();
-        },
-
-        /**
-         * Initiates loading of filters constructors.
-         */
-        loadControls: function () {
-            var coreTypes = defaults.types,
-                paths,
-                types;
-
-            types = _.map(this.types, function (config, type) {
-                config.name = type;
-
-                if(!config.control){
-                   config.control = coreTypes[type];
-                }
-
-                return config;
-            });
-
-            paths = _.pluck(types, 'control');
-
-            require(paths, this.onControlsLoaded.bind(this, types));
-        },
-
-        /**
-         * Initializes observable properties of instance.
-         * @returns {Filter} Chainbale.
-         */
-        initObservable: function(){
-            this.observe({
-                isVisible:  false,
-                active:     [],
-                filters:    []
-            });
-
-            return this; 
-        },
-
-        /**
-         * Filters filterable fields and stores them to this.fields 
-         * @returns {Filter} Chainbale.
-         */
-        extractFields: function () {
-            var provider    = this.provider.meta,
-                fields      = provider.getVisible();
-
-            this.fields = fields.filter(function (field) {
-                return field.filterable;
-            });
-
-            return this;
-        },
-
-        /**
-         * Initializes filters by creating instances of
-         * corresponding classes found in controls by filter type.
-         * @returns {Filter} Chainbale.
-         */
-        initFilters: function () {
-            var controls = this.types,
-                config,
-                type,
-                filters,
-                control;
-
-            filters = this.fields.map(function (field) {
-                type    = (field.filter_type || field.input_type);
-                config  = controls && controls[type];
-                control = config.constr;
-
-                field.type     = type;
-                field.module   = config.module || 'ui';
-
-                return new control(field, config);
-            }, this);
-
-            this.filters(filters);
-
-            return this;
-        },
-
-        /**
-         * Extracts an array of non-empty filters.
-         * @returns {Array} Array of non-empty filters
-         */
-        getNotEmpty: function(){
-            return this.filters().filter(function(filter){
-                return !filter.isEmpty();
-            });
-        },
-
-        /**
-         * Writes the result of getNotEmpty to active observable.
-         * @returns {Filter} Chainbale.
-         */
-        findActive: function(){
-            this.active(this.getNotEmpty());
-
-            return this;
-        },
-
-        /**
-         * Returns an array filters' data.
-         * @param {Boolean} [all=false] -
-                Whether to extract data from all of the filters
-                or from only the active ones.
-         * @returns {Array} Array of filters' data.
-         */
-        getData: function(all){
-            var filters;
-
-            filters = all ? this.filters() : this.active();
-
-            return filters.map(function(filter){
-                return filter.dump();
-            });
-        },
-
-        /**
-         * Clears data of all filters or of specified one.
-         * @param {Object} [filter] - If specified, clears data only of this filter.
-         * @returns {Filter} Chainbale.
-         */
-        clearData: function(filter){
-            var active = this.active;
-
-            if(filter){
-                filter.reset();
-
-                active.remove(filter);
-            }
-            else{
-                this.filters().forEach(function (filter) {
-                    filter.reset();
-                });
-
-                active.removeAll();
-            }
-
-            return this;
-        },
-
-        /**
-         * Updates an array of active filters
-         * and reloads data provider with new filtering parameters.
-         * @returns {Filter} Chainbale.
-         */
-        apply: function () {
-            this.findActive()
-                .reload();
-
-            return this;
-        },
-
-        /**
-         * Clears filters and updates data provider with new filtering parameters.
-         * @param {Object} [filter] - If specified then clears only this filter. 
-         * @returns {Filter} Chainbale.
-         */
-        reset: function(filter){
-            this.clearData(filter)           
-                .reload();
-
-            return this;
-        },
-
-        /**
-         * Sets set of params to storage.
-         * @param {*} action - data to set to storage params
-         * @returns {Filter} Chainbale.
-         */
-        pushParams: function() {
-            var params = this.provider.params;
-
-            params.set('filter', this.getData());
-
-            return this;
-        },
-
-        /**
-         * @description Toggles isVisible observable property
-         */
-        toggle: function () {
-            this.isVisible(!this.isVisible());
-        },
-
-        /**
-         * @description Sets isVisible observable property to false
-         */
-        close: function () {
-            this.isVisible(false);
-        },
-
-        /**
-         * Resets specified filter using reset method
-         * @param  {Object} filter - filter to reset
-         */
-        onClear: function(filter) {
-            return this.reset.bind(this, filter);
-        },
-
-        /**
-         * Callback that fires when all of the filters constructors has been loaded.
-         * @param {Array} controlsMap - An array of availbale filter types and theirs configuration.       
-         */
-        onControlsLoaded: function (controlsMap) {
-            var controls = Array.prototype.slice.call(arguments, 1),
-                types = {},
-                control;
-
-            controls.forEach(function (constr, idx) {
-                control = controlsMap[idx];
-
-                delete control.control;
-                
-                control.constr = constr;
-
-                types[control.name] = control;
-            });
-
-            this.types = types;
-
-            this.proceed();
-        }
-    });
-
-    return Component({
-        constr: Filter
-    });
-});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/listing/filter/abstract.js b/app/code/Magento/Ui/view/base/web/js/listing/filter/abstract.js
deleted file mode 100644
index bf52c36dd9aa4478fa96a7cef7ce000e2bb82fe5..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/js/listing/filter/abstract.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-define([
-    'Magento_Ui/js/lib/ko/scope',
-    'underscore'
-], function (Scope, _) {
-    'use strict';
-    
-    return Scope.extend({
-
-        /**
-         * Extends instance with data passed.
-         * @param {Object} data - Item of "fields" array from grid configuration
-         * @param {Object} config - Filter configuration
-         */
-        initialize: function (data, config) {
-            _.extend(this, data);
-            this.config = config;
-
-            this.observe('output', '');
-        },
-
-        isEmpty: function () {},
-
-        /**
-         * Returns alias for filter item template
-         * @return {String}
-         */
-        getTemplate: function () {
-            return this.module + '/filter/' + this.type;
-        }
-    });
-});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/listing/filter/date.js b/app/code/Magento/Ui/view/base/web/js/listing/filter/date.js
deleted file mode 100644
index bff6c90fc63f7727483217c47ec08ddc1e88b964..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/js/listing/filter/date.js
+++ /dev/null
@@ -1,11 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-define([
-    './range'
-], function (Range) {
-    'use strict';
-    
-    return Range;
-});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/listing/filter/filters.js b/app/code/Magento/Ui/view/base/web/js/listing/filter/filters.js
deleted file mode 100644
index 147b2b1d508e7a4d8c745fa7cf1bafd65880c0fd..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/js/listing/filter/filters.js
+++ /dev/null
@@ -1,20 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-/** Assembles available filter controls and returns it's mapping. */
-define([
-    './input',
-    './select',
-    './range'
-], function (InputControl, SelectControl, RangeControl) {
-    'use strict';
-
-    return {
-        input:      InputControl,
-        select:     SelectControl,
-        date:       RangeControl,
-        range:      RangeControl,
-        store:      SelectControl
-    }
-});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/listing/filter/input.js b/app/code/Magento/Ui/view/base/web/js/listing/filter/input.js
deleted file mode 100644
index fdd6735151fff7d92e91d6755dcce103f63e10ab..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/js/listing/filter/input.js
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-define([
-    './abstract',
-    'underscore'
-], function (AbstractControl, _) {
-    'use strict';
-    
-    return AbstractControl.extend({
-
-        /**
-         * Invokes initialize method of parent class and initializes observable properties of instance.
-         * @param {Object} data - Item of "fields" array from grid configuration
-         * @param {Object} config - Filter configuration
-         */
-        initialize: function (data) {
-            this.constructor.__super__.initialize.apply(this, arguments);
-
-            this.observe('value', '');
-        },
-
-        /**
-         * Returnes true if this.value is falsy
-         * @return {Boolean} true if this.value is falsy, false otherwise
-         */
-        isEmpty: function(){
-            return !this.value();
-        },
-
-        /**
-         * Returns this.value(). Is used for displaying on UI.
-         * @return {[type]} [description]
-         */
-        display: function(){
-            return this.value();
-        },
-
-        /**
-         * Returns dump of instance's current state
-         * @returns {Object} - object which represents current state of instance
-         */
-        dump: function () {
-            this.output( this.display() );
-            
-            return {
-                field: this.index,
-                value: this.value()
-            };
-        },
-
-        /**
-         * Resets state properties of instance and calls dump method.
-         * @returns {Object} - object which represents current state of instance
-         */
-        reset: function () {
-            this.value(null);
-
-            return this.dump();
-        }
-    });
-});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/listing/filter/range.js b/app/code/Magento/Ui/view/base/web/js/listing/filter/range.js
deleted file mode 100644
index 69ac544fdb229f0581c28a51ba9bd9f77b9c9c67..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/js/listing/filter/range.js
+++ /dev/null
@@ -1,89 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-define([
-    './abstract',
-    'underscore'
-], function (AbstractControl, _) {
-    'use strict';
-    
-    return AbstractControl.extend({
-
-        /**
-         * Invokes initialize method of parent class and initializes observable properties of instance.
-         * @param {Object} data - Item of "fields" array from grid configuration
-         * @param {Object} config - Filter configuration
-         */
-        initialize: function (data, config) {
-            this.constructor.__super__.initialize.apply(this, arguments);
-
-            this.observe({
-                from: '',
-                to:   ''
-            });
-        },
-        
-        /**
-         * Creates dump copy of current state.
-         * @return {Object} dumped value object
-         */
-        getValues: function(){
-            var value   = {},
-                from    = this.from(),
-                to      = this.to();
-
-            if (from) {
-                value.from = from;
-            }
-
-            if (to) {
-                value.to = to;
-            }
-
-            return value;
-        },
-
-        /**
-         * Returns string value of current state for UI
-         * @return {String}
-         */
-        display: function(){
-            var values = this.getValues();
-
-            return _.map(values, function(value, name){
-                return name + ': ' + value;
-            }).join(' ');
-        },
-
-        /**
-         * Checkes if current state is empty.
-         * @return {Boolean}
-         */
-        isEmpty: function(){
-            return ( !this.to() && !this.from() );
-        },
-
-        /**
-         * Returns dump of instance's current state
-         * @returns {Object} - object which represents current state of instance
-         */
-        dump: function () {
-            this.output( this.display() );
-
-            return {
-                field: this.index,
-                value: this.getValues()
-            };
-        },
-
-        /**
-         * Resets state properties of instance and calls dump method.
-         * @returns {Object} - object which represents current state of instance
-         */
-        reset: function () {
-            this.to('');
-            this.from('');
-        }
-    });
-});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/listing/filter/select.js b/app/code/Magento/Ui/view/base/web/js/listing/filter/select.js
deleted file mode 100644
index 128cc59eb53b84530fee7c39591ddceeedbfef79..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/js/listing/filter/select.js
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-define([
-    './abstract',
-    'underscore'
-], function (AbstractControl, _) {
-    'use strict';
-
-    return AbstractControl.extend({
-
-        /**
-         * Invokes initialize method of parent class and initializes properties of instance.
-         * @param {Object} data - Item of "fields" array from grid configuration
-         * @param {Object} config - Filter configuration
-         */
-        initialize: function (data) {
-            this.constructor.__super__.initialize.apply(this, arguments);
-
-            this.caption = 'Select...';
-
-            this.observe('selected', '');
-
-            this.options = this.options ? this.formatOptions(this.options) : [];
-        },
-
-        /**
-         * Checkes if current state is empty.
-         * @return {Boolean}
-         */
-        isEmpty: function(){
-            var selected = this.selected();
-
-            return !(selected && selected.value);
-        },
-
-        /**
-         * Formats options property of instance.
-         * @param {Object} options - object representing options
-         * @returns {Array} - Options, converted to array
-         */
-        formatOptions: function (options) {
-            return _.map(options, function (value, key) {
-                return { value: key, label: value  };
-            });
-        },
-
-        /**
-         * Returns string value of current state for UI
-         * @return {String}
-         */
-        display: function(){
-            var selected = this.selected();
-
-            return selected && selected.label;
-        },
-
-        /**
-         * Returns dump of instance's current state
-         * @returns {Object} - object which represents current state of instance
-         */
-        dump: function () {
-            var selected = this.selected();
-
-            this.output( this.display() );
-
-            return {
-                field: this.index,
-                value: selected && selected.value
-            }
-        },
-
-        /**
-         * Resets state properties of instance and calls dump method.
-         * @returns {Object} - object which represents current state of instance
-         */
-        reset: function () {
-            this.selected(null);
-        }
-    });
-});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/listing/grid.js b/app/code/Magento/Ui/view/base/web/js/listing/grid.js
deleted file mode 100644
index e074902586342a9b8e7b80700eb565468462fcd2..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/js/listing/grid.js
+++ /dev/null
@@ -1,222 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-define([
-    'underscore',
-    'Magento_Ui/js/lib/component',
-    'Magento_Ui/js/lib/ko/scope',
-    'Magento_Ui/js/lib/mixins/loader',
-], function(_, Component, Scope, Loader) {
-    'use strict';
-
-    var Listing =  Scope.extend({
-
-        /**
-         * Extends instance with defaults and config, initializes observable properties.
-         * Updates provider with current state of instance. 
-         * @param  {Object} settings
-         */
-        initialize: function(settings) {
-            _.extend(this, settings);
-
-            this.initFields()
-                .initObservable()
-                .initListeners()
-                .updateItems();
-
-            this.unlock();
-        },
-
-        /**
-         * Initializes raw properties
-         * @return {Object} reference to instance
-         */
-        initFields: function(){
-            this.meta          = this.provider.meta;
-            this.fields        = this.meta.getVisible();
-            this.itemActionKey = this.meta.get('item_action');
-
-            return this;
-        },
-
-        /**
-         * Initializes observable properties of instance.
-         * @return {Object} - reference to instance
-         */
-        initObservable: function() {
-            this.observe({
-                rows:               [],
-                isLocked:           false,
-                colspan:            this.meta.get('colspan'),
-                extenders:          null,
-                templateExtenders:  []
-            });
-
-            return this;
-        },
-
-        /**
-         * Init instance's subscribtions
-         * @return {Object} - reference to instance
-         */
-        initListeners: function() {
-            var provider    = this.provider,
-                meta        = provider.meta,
-                dump        = provider.dump;
-
-            _.bindAll(this, 'lock', 'onRefresh', 'updateExtenders', 'updateColspan');
-
-            provider.on({
-                'beforeRefresh':    this.lock,
-                'refresh':          this.onRefresh
-            });
-
-            dump.when('update:extenders', this.updateExtenders);
-            meta.on('update:colspan', this.updateColspan);
-
-            return this;
-        },
-
-        /**
-         * Is being called when some component pushed it's extender to global storage.
-         * Preprocesses incoming array of extenders and sets the results into extenders
-         * and templateExtenders observable arrays
-         * @param  {Array} extenders
-         */
-        updateExtenders: function (extenders) {
-            var adjusted = extenders.reduce(function (adjusted, extender) {
-
-                adjusted[extender.as] = extender.name;
-                return adjusted;
-
-            }, {});
-            
-            this.extenders(adjusted);
-
-            this.templateExtenders(extenders.map(this.adjustTemplateExtender, this));
-        },
-
-        /**
-         * Fetches items from storage and stores it into rows observable array
-         * @return {Object} - reference to instance
-         */
-        updateItems: function() {
-            var items = this.provider.data.get('items');
-
-            this.rows(items.map(this.formatItem, this));
-
-            return this;
-        },
-
-        formatItem: function (item) {
-            var actions       = item.actions,
-                itemActionKey = this.itemActionKey,
-                itemAction;
-
-            if (actions) {
-                itemAction = actions[itemActionKey];
-                item.action_url = itemAction.href;
-
-                if (itemAction.hidden) {
-                    delete item.actions[itemActionKey];
-                }
-                
-                item.actions = _.map(item.actions, function (action) { return action });
-            }
-
-            return item;
-        },
-
-        applyItemActionFor: function (item) {
-            return this.redirectTo.bind(this, item.action_url);
-        },
-
-        /**
-         * Returns extender by name of component which set it.
-         * @param  {String} name
-         * @return {String} - Namespace string by which target component is registered in storage.
-         */
-        getExtender: function(name) {
-            var extenders = this.extenders();
-
-            return extenders ? (this.parent_name + ':' + extenders[name]) : null;
-        },
-
-        /**
-         * Returns path to template for arbitrary field
-         * @param  {String} field
-         * @return {String} - path to template
-         */
-        getCellTemplateFor: function(field) {
-            return this.getRootTemplatePath() + '/cell/' + field.data_type;
-        },
-
-        /**
-         * Returns object which represents template bindings params
-         * @return {Object} - template binding params
-         */
-        getTemplate: function() {
-            return {
-                name:      this.getRootTemplatePath(),
-                extenders: this.templateExtenders()
-            };
-        },
-
-        /**
-         * Generates template path for extender.
-         * @param  {Object} extender
-         * @return {String} - extender's template path
-         */
-        adjustTemplateExtender: function (extender) {
-            return this.getRootTemplatePath() + '/extender/' + extender.path;
-        },
-
-        /**
-         * Returns root template path for grid
-         * @return {String} - root template path
-         */
-        getRootTemplatePath: function() {
-            return 'ui/listing/grid';
-        },
-
-        /**
-         * Provider's refresh event's handler.
-         * Locks grid and updates items.
-         */
-        onRefresh: function() {
-            this.unlock()
-                .updateItems();
-        },
-
-        /**
-         * Updates colspan observable property
-         * @param  {String} colspan
-         */
-        updateColspan: function(colspan){
-            this.colspan(colspan);
-        },
-
-        /**
-         * Sets location.href to target url
-         * @param  {String} url
-         */
-        redirectTo: function (url) {
-            if (url) {
-                window.location.href = url;    
-            }
-        },
-
-        /**
-         * Indicates if rows observable array is empty
-         * @return {Boolean} [description]
-         */
-        hasData: function(){
-            return this.rows().length;
-        }
-    }, Loader);
-
-    return Component({
-        constr: Listing
-    });
-});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/listing/massaction.js b/app/code/Magento/Ui/view/base/web/js/listing/massaction.js
deleted file mode 100644
index 2c559de58d1dc287e2c11a6309f19af27e29f105..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/js/listing/massaction.js
+++ /dev/null
@@ -1,414 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-define([
-    'jquery',
-    'underscore',
-    'Magento_Ui/js/lib/ko/scope',
-    'Magento_Ui/js/lib/component',
-    'mage/translate'
-], function ($, _, Scope, Component) {
-    'use strict';
-
-    function capitaliseFirstLetter(string) {
-        return string.charAt(0).toUpperCase() + string.slice(1);
-    }
-
-    var defaults = {
-        actions:        [],
-        deleteMsg:      $.mage.__("Are you sure you want to delete these records?"),
-        notSelected:    $.mage.__("You haven't selected any items!"),
-        selects: [
-            { value: 'selectAll',    label: 'Select all'                },
-            { value: 'deselectAll',  label: 'Deselect all'              },
-            { value: 'selectPage',   label: 'Select all on this page'   },
-            { value: 'deselectPage', label: 'Deselect all on this page' }
-        ],
-        selectableTemplate: 'selectable'
-    };
-
-    var MassActions = Scope.extend({
-
-        /**
-         * Extends instance with defaults and config, initializes observable properties.
-         * Updates storage with current state of instance.
-         * @param {Object} config
-         */
-        initialize: function (config) {
-            _.extend(this, defaults, config);
-
-            this.initObservable()
-                .initProperties()
-                .formatActions()
-                .attachTemplateExtender()
-                .initListeners()
-                .countPages();
-        },
-
-        /**
-         * Initializes observable properties of instance.
-         * @returns {MassActions} Chainable.
-         */
-        initObservable: function () {
-            this.observe({
-                selected:           this.selected || [],
-                excluded:           [],
-                allSelected:        this.allSelected || false,
-                actionsVisible:     false,
-                menuVisible:        false,
-                hasMultiplePages:      ''
-            });
-
-            this.selected.subscribe(this.onSelectionsChange.bind(this));
-
-            return this;
-        },
-
-        /**
-         * Initializes instance properties
-         * @returns {MassActions} Chainable.
-         */
-        initProperties: function () {
-            var provider = this.provider.meta;
-
-            this.indexField = provider.get('index_field');
-
-            return this;
-        },
-
-        /**
-         * Convertes incoming optins to compatible format
-         * @returns {MassActions} Chainable.
-         */
-        formatActions: function(){
-            var actions = this.actions;
-
-            if(!Array.isArray(actions)){
-
-                this.actions = _.map(actions, function(action, name){
-                    action.value = name;
-
-                    return action;
-                });
-            }
-
-            return this;
-        },
-
-        /**
-         * Attaches it's template to provider.dump's extenders
-         * @returns {MassActions} Chainable.
-         */
-        attachTemplateExtender: function () {
-            var provider    = this.provider,
-                dump        = provider.dump,
-                meta        = provider.meta,
-                colspan     = meta.get('colspan'),
-                extenders   = dump.get('extenders');
-
-            if(!this.selectableTemplate) {
-                return this;
-            }
-
-            extenders.push({
-                path:   this.selectableTemplate,
-                name:   this.name,
-                as:     'massaction'
-            });
-
-            dump.resolve('update:extenders', extenders);
-            meta.set('colspan', colspan + 1);
-
-            return this;
-        },
-
-        /**
-         * Init instance's subscribtions
-         * @returns {MassActions} Chainable.
-         */
-        initListeners: function(){
-            this.provider.on('refresh', this.onRefresh.bind(this));
-
-            return this;
-        },
-
-        /**
-         * Prepares params object, which represents the current state of instance.
-         * @returns {Object} - params object
-         */
-        buildParams: function () {           
-            if (this.allSelected()) {
-
-                return {
-                    all_selected: true,
-                    excluded: this.excluded()
-                };
-            }
-
-            return {
-                selected: this.selected()
-            };
-        },
-        
-        /**
-         * Toggles observable property based on area argument.
-         * @param {String} area - Name of the area to be toggled.
-         */
-        toggle: function(area){
-            var visible = this[area];
-
-            visible(!visible());
-        },
-
-        /**
-         * Sets actionsVisible to false
-         */
-        hideActions: function () {
-            this.actionsVisible(false);
-        },
-
-        /**
-         * Sets menuVisible to false
-         */
-        hideMenu: function () {
-            this.menuVisible(false);
-        },
-
-        /**
-         * Updates storage's params by the current state of instance
-         * and hides dropdowns.
-         * @param {String} action
-         */
-        setAction: function (action) {
-            return function(){
-                this.submit(action)
-                    .hideActions();
-            }.bind(this);
-        },
-
-        /**
-         * Sends actions's data to server.
-         * @param {Object} action - An action object.
-         * @returns {MassActions} Chainable.
-         */
-        submit: function(action) {
-            var client      = this.provider.client,
-                value       = action.value,
-                confirmed   = true;
-
-            if (!this.count) {
-                confirmed = false;
-
-                alert(this.notSelected);
-            } else if (value === 'delete') {
-                confirmed = confirm(this.deleteMsg);
-            }
-
-            if (confirmed) {
-                client.submit({
-                    method: 'post',
-                    action: action.url,
-                    data: {
-                        massaction: this.buildParams()
-                    }
-                });
-            }
-
-            return this;
-        },
-
-        /**
-         * Retrieve all id's from available records.
-         * @param {Boolean} [exclude] - Whether to exclude not selected ids' from result.
-         * @returns {Array} An array of ids'.
-         */
-        getIds: function(exclude){
-            var items   = this.provider.data.get('items'),
-                ids     = _.pluck(items, this.indexField);
-
-            return exclude ?
-                _.difference(ids, this.excluded()) :
-                ids;    
-        },
-
-        /**
-         * Sets isAllSelected observable to true and selects all items on current page.
-         */
-        selectAll: function () {
-            this.allSelected(true);
-            
-            this.clearExcluded()
-                .selectPage();
-        },
-
-        /**
-         * Sets isAllSelected observable to false and deselects all items on current page.
-         */
-        deselectAll: function () {
-            this.allSelected(false);
-            this.deselectPage();
-        },
-
-        /**
-         * Selects all items on current page, adding their ids to selected observable array
-         */
-        selectPage: function () {
-            this.selected(this.getIds());
-        },
-
-        /**
-         * Deselects all items on current page, emptying selected observable array
-         */
-        deselectPage: function () {
-            this.selected.removeAll();
-        },
-        
-        updateExcluded: function(selected) {
-            var excluded    = this.excluded(),
-                fromPage    = _.difference(this.getIds(), selected);
-
-            excluded = _.union(excluded, fromPage);
-
-            excluded = _.difference(excluded, selected);
-
-            this.excluded(excluded);
-
-            return this;
-        },
-
-        /**
-         * Clears the array of not selected records.
-         * @returns {MassActions} Chainable.
-         */
-        clearExcluded: function(){
-            this.excluded.removeAll();
-
-            return this;
-        },
-
-        /**
-         * Returns handler for row click
-         * @param  {String} url
-         * @return {Function} click handler
-         */
-        redirectTo: function (url) {
-
-            /**
-             * Sets location.href to target url
-             */
-            return function () {
-                window.location.href = url;
-            }
-        },
-
-        /**
-         * Gets current pages count and assignes it's being more than one to
-         *     hasMultiplePages observable.
-         * @returns {MassActions} Chainable.
-         */
-        countPages: function() {
-            var provider = this.provider.data;
-
-            this.pages = provider.get('pages');
-
-            this.hasMultiplePages(this.pages > 1);
-
-            return this;
-        },
-
-        /**
-         * Counts number of 'selected' items. 
-         * @returns {MassActions} Chainable.
-         */
-        countSelect: function() {
-            var provider    = this.provider,
-                total       = provider.data.get('totalCount'),
-                excluded    = this.excluded().length,
-                count       = this.selected().length;
-
-            if (this.allSelected()) {
-                count = total - excluded;
-            }
-
-            provider.meta.set('selected', count);
-
-            this.count = count;
-
-            return this;
-        },
-
-        /**
-         * If isAllSelected is true, deselects all, else selects all
-         */
-        toggleSelectAll: function () {
-            var isAllSelected = this.allSelected();
-
-            isAllSelected ? this.deselectAll() : this.selectAll();
-        },
-
-        /**
-         * Looks up for corresponding to passed action checker method,
-         * and returnes it's result. If method not found, returnes true;
-         * @param {String} action - e.g. selectAll, deselectAll
-         * @returns {Boolean} should action be visible
-         */
-        shouldBeVisible: function (action) {
-            var checker = this['should' + capitaliseFirstLetter(action) + 'BeVisible'];
-
-            return checker ? checker.call(this) : true;
-        },
-
-        /**
-         * Checkes if selectAll action supposed to be visible
-         * @returns {Boolean}
-         */
-        shouldSelectAllBeVisible: function () {
-            return !this.allSelected() && this.hasMultiplePages();
-        },
-
-        /**
-         * Checkes if deselectAll action supposed to be visible
-         * @returns {Boolean}
-         */
-        shouldDeselectAllBeVisible: function () {
-            return this.allSelected() && this.hasMultiplePages();
-        },
-
-        onToggle: function(area){
-            return this.toggle.bind(this, area);
-        },
-
-        /**
-         * Creates handler for applying action (e.g. selectAll)
-         * @param {String} action
-         * @returns {Function} - click handler
-         */
-        onApplySelect: function (action) {
-            return function(){
-                this.menuVisible(false);
-                this[action]();
-            }.bind(this);
-        },
-
-        /**
-         * Updates state according to changes of provider.
-         */
-        onRefresh: function () {
-            if( this.allSelected() ){
-                this.selected(this.getIds(true));
-            }
-
-            this.countPages();
-        },
-
-        onSelectionsChange: function(selected){
-            this.updateExcluded(selected)
-                .countSelect();
-        }
-    });
-
-    return Component({
-        constr: MassActions
-    });
-});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/listing/paging.js b/app/code/Magento/Ui/view/base/web/js/listing/paging.js
deleted file mode 100644
index c32df63ed9b108c39bad296081b2e6abade4b1a2..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/js/listing/paging.js
+++ /dev/null
@@ -1,191 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-define([
-    'underscore',
-    '../lib/ko/scope',
-    '../lib/component'
-], function(_, Scope, Component) {
-    'use strict';
-
-    var defaults = {
-        sizes: [5, 10, 20, 30, 50, 100, 200],
-        params: {
-            dir: 'paging',
-            items: ['pageSize', 'current']
-        }
-    };
-
-    var Paging = Scope.extend({
-
-        /**
-         * Extends instance with defaults and config, initializes observable properties.
-         * Updates storage with current state of instance. 
-         * @param  {Object} config
-         */
-        initialize: function(config) {
-            _.extend(this, defaults, config);
-
-            this.initObservable(config)
-                .initProvider()
-                .pushParams();
-        },
-
-        /**
-         * Initializes observable properties of instance.
-         * @return {Object} - reference to instance
-         */
-        initObservable: function(config) {
-            var data = this.provider.data.get();
-
-            this.observe({
-                'pages':        data.pages || 1,
-                'totalCount':   data.totalCount,
-                'current':      this.current,
-                'pageSize':     this.pageSize,
-                'selected':     0
-            });
-
-            return this;
-        },
-
-        /**
-         * Subscribes on provider's events
-         * @returns {Paging} Chainable.
-         */
-        initProvider: function(){
-            var provider    = this.provider,
-                params      = provider.params,
-                meta        = provider.meta;
-
-            _.bindAll(this, 'drop', 'onRefresh', 'pullParams', 'updateSelected');
-
-            provider.on('refresh', this.onRefresh);
-            
-            meta.on('update:selected', this.updateSelected);
-
-            params.on({
-                'update:filter':    this.drop,
-                'update:sorting':   this.drop,
-                'update:paging':    this.pullParams
-            });
-
-            return this;
-        },
-
-        /**
-         * Increments current observable prop by val and call reload method 
-         * @param {String} val
-         */
-        go: function(val) {
-            var current = this.current;
-
-            current(current() + val);
-
-            this.reload();
-        },
-
-        /**
-         * Calls go method with 1 as agrument
-         */
-        next: function() {
-            this.go(1);
-        },
-
-        /**
-         * Calls go method with -1 as agrument
-         */
-        prev: function() {
-            this.go(-1);
-        },
-
-        /**
-         * Compares current and pages observables and returns boolean result
-         * @return {Boolean} is current equal to pages property
-         */
-        isLast: function() {
-            return this.current() === this.pages();
-        },
-
-        /**
-         * Compares current observable to 1
-         * @return {Boolean} is current page first
-         */
-        isFirst: function() {
-            return this.current() === 1;
-        },
-
-        /**
-         * Returns closest existing page number to page argument
-         * @param  {Number} page
-         * @return {Number} closest existing page number
-         */
-        getInRange: function(page) {
-            return Math.min(Math.max(1, page), this.pages());
-        },
-        
-        /**
-         * Sets current observable to 1 and calls pushParams method
-         */
-        drop: function() {
-            this.current(1);
-
-            this.pushParams();
-        },
-
-        /**
-         * Updates number of selected items.
-         * @param {Number} count - New number of selected items.
-         */
-        updateSelected: function(count){
-            this.selected(count);
-        },
-
-        /**
-         * Is being called on provider's refresh event.
-         * Updates totalCount and pages observables
-         */
-        onRefresh: function() {
-            var data = this.provider.data.get();
-
-            this.totalCount(data.totalCount);
-            this.pages(data.pages || 1);
-        },
-
-        /**
-         * Is being triggered on user interaction with page size select.
-         * Resets current page to first if needed.
-         */
-        onSizeChange: function() {
-            var size = this.pageSize();
-
-            if (size * this.current() > this.totalCount()) {
-                this.current(1);
-            }
-
-            this.reload();
-        },
-
-        /**
-         * Validates page change according to user's input.
-         * Sets current observable to result of validation.
-         * Calls reload method then.
-         */
-        onPageChange: function() {
-            var current,
-                valid;
-
-            current = +this.current();
-            valid = !isNaN(current) ? this.getInRange(current) : 1;
-
-            this.current(valid);
-
-            this.reload();
-        }
-    });
-
-    return Component({
-        constr: Paging
-    });
-});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/listing/sorting.js b/app/code/Magento/Ui/view/base/web/js/listing/sorting.js
deleted file mode 100644
index 31b9812713c32d285a76f33d1672d27bfbf0eaf3..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/js/listing/sorting.js
+++ /dev/null
@@ -1,133 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-define([
-    'underscore',
-    'Magento_Ui/js/lib/ko/scope',
-    'Magento_Ui/js/lib/component'
-], function(_, Scope, Component) {
-    'use strict';
-    
-    var defaults = {
-        dirs: {
-            asc: 'sort-arrow-asc',
-            desc: 'sort-arrow-desc'
-        },
-        params: {
-            dir: 'sorting',
-            items: ['field', 'direction']
-        },
-        initialDir: 'asc',
-        noSort: 'not-sort',
-        templateExtender: 'sortable'
-    };
-
-    var Sorting = Scope.extend({
-
-        /**
-         * Extends instance with defaults and config, initializes observable properties.
-         * Updates storage with current state of instance. 
-         * @param  {Object} config
-         */
-        initialize: function(config) {
-            _.extend(this, defaults, config);
-            
-            this.initObservable()
-                .attachTemplateExtender()
-                .pushParams();
-        },
-
-        /**
-         * Initializes observable properties of instance.
-         * @returns {Sorting} Chainable.
-         */
-        initObservable: function(){
-            this.observe('field direction');
-
-            return this;
-        },
-
-        /**
-         * Attaches it's template to provider.dump's extenders
-         * @returns {Sorting} Chainable.
-         */
-        attachTemplateExtender: function () {
-            var dump        = this.provider.dump,
-                extenders   = dump.get('extenders');
-                
-            extenders.push({
-                path: this.templateExtender,
-                name: this.name,
-                as:   'sorting'
-            });
-
-            dump.resolve('update:extenders', extenders);
-
-            return this;
-        },
-
-        /**
-         * Generates css class for indicating sorting state for field. 
-         * @param {String} id - identifier of field to be sorted
-         * @returns {String} - css class.
-         */
-        setClass: function(id) {
-            return this.isSorted(id) ?
-                this.dirs[this.direction()] :
-                this.noSort;
-        },
-
-        /**
-         * Toggles observable dir property betweeen 'asc' and 'desc' values.
-         */
-        toggleDirection: function() {
-            var dir = this.direction;
-
-            dir(dir() === 'asc' ? 'desc' : 'asc');
-        },
-
-        /**
-         * Sets currently sorted field and initial sorting type for it.
-         * @param {String} id - identifier of field to be sorted
-         */
-        setSort: function(id) {
-            this.field(id);
-            this.direction(this.initialDir);
-        },
-
-        /**
-         * Sorts by field and reloads storage.
-         * @param {(String|Number)} id - Identifier of field to be sorted.
-         */
-        sortBy: function(id) {
-            this.isSorted(id) ?
-                this.toggleDirection() :
-                this.setSort(id);
-
-            this.reload();
-        },
-
-        /**
-         * Checks if the field is currently sorted.
-         * @param {String} id - identifier of field to be sorted
-         * @returns {Boolean} true, if target field is sorted already, false otherwise
-         */
-        isSorted: function(id) {
-            return id === this.field();
-        },
-
-        /**
-         * Returns function to handle user's click (workaround for knockout.js).
-         * @param {Object} field
-         * @returns {Function} - click handler
-         */
-        onClick: function(field) {
-            return this.sortBy.bind(this, field.index);
-        }
-    });
-
-    return Component({
-        constr: Sorting
-    });
-});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/templates/area.html b/app/code/Magento/Ui/view/base/web/templates/area.html
index 867908c0f8eeda3b65128cfb31653bda3bea0aee..eee2d4a8c630dcf93ab48c1911ed1b0b7237de1b 100644
--- a/app/code/Magento/Ui/view/base/web/templates/area.html
+++ b/app/code/Magento/Ui/view/base/web/templates/area.html
@@ -4,7 +4,6 @@
  * See COPYING.txt for license details.
  */
 -->
-
 <!-- ko if: wasActivated -->
     <div data-bind="visible: active">
         <!-- ko foreach: elems -->
diff --git a/app/code/Magento/Ui/view/base/web/templates/content/content.html b/app/code/Magento/Ui/view/base/web/templates/content/content.html
index c3d84628b7721cfd63b07a65ab4e66e623b122c9..ad90f63cd4282170e5322957e7bda90ac42f2291 100644
--- a/app/code/Magento/Ui/view/base/web/templates/content/content.html
+++ b/app/code/Magento/Ui/view/base/web/templates/content/content.html
@@ -7,7 +7,7 @@
 <div data-bind="html: content, attr: {class: element.cssclass ? element.cssclass : 'admin__scope-old'}"></div>
 
 <!--ko if: showSpinner -->
-<div data-role="spinner" class="grid-loading-mask" data-bind="visible: loading">
-    <div class="spinner"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></div>
+<div data-role="spinner" class="admin__data-grid-loading-mask" data-bind="visible: loading">
+    <span class="grid-loader"></span>
 </div>
 <!-- /ko -->
diff --git a/app/code/Magento/Ui/view/base/web/templates/filter.html b/app/code/Magento/Ui/view/base/web/templates/filter.html
deleted file mode 100644
index 0f95ab6ae6e9cf87ce69cc39a9d99c3ed9d75f1b..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/templates/filter.html
+++ /dev/null
@@ -1,42 +0,0 @@
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<div class="filters">
-    <button class="action filters-toggle" data-bind="click: toggle, css: { active: isVisible }">
-        <span data-bind="text: $t('Filter')"></span>
-    </button>
-    <div class="form filters-form" data-bind="visible: isVisible" data-part="filter-form">
-        <fieldset class="filters-fieldset fieldset">
-            <legend class="legend filters-legend">
-                <span data-bind="text: $t('Advanced filter')"></span>
-            </legend><br />
-            <!-- ko foreach: { data: filters, as: 'item' } -->
-            <!-- ko template: item.getTemplate() --><!-- /ko -->
-            <!-- /ko -->
-        </fieldset>
-        <div class="actions filters-actions">
-            <button class="action secondary action-reset" data-bind="click: reset" type="button"><span data-bind="text: $t('Reset')"></span></button>
-            <button class="action primary action-apply" data-bind="click: apply" type="button"><span data-bind="text: $t('Apply')"></span></button>
-            <button class="action secondary action-close" data-bind="click: close" type="button"><span data-bind="text: $t('Close')"></span></button>
-        </div>
-    </div>
-    <div class="filters-current" data-bind="css: {active: active().length}">
-        <ul class="filters-items items">
-            <!-- ko foreach: { data: active, as: 'filter' } -->
-
-            <li class="filters-item item">
-                <strong class="item-label" data-bind="text: $t(filter.label)"></strong>
-                <span class="item-value" data-bind="text: $t(filter.output)"></span>
-                <button data-bind="click: $parent.onClear(filter)" type="button" class="action action-remove"><span data-bind="text: $t('Remove')"></span></button>
-            </li>
-
-            <!-- /ko -->
-        </ul>
-        <button data-bind="click: reset" class="action action-clear">
-            <span data-bind="text: $t('Clear all')"></span>
-        </button>
-    </div>
-</div>
diff --git a/app/code/Magento/Ui/view/base/web/templates/filter/filter_date.html b/app/code/Magento/Ui/view/base/web/templates/filter/filter_date.html
deleted file mode 100644
index 644aad7f8301f550f871700dbe25381e5b608b11..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/templates/filter/filter_date.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<fieldset class="field field-range field-date">
-    <legend class="label">
-        <span data-bind="text: label"></span>
-    </legend><br />
-    <div class="control">
-        <div class="fields group group-2">
-            <div class="field field-range-from">
-                <label class="label"><span data-bind="text: $t('From')"></span></label>
-                <div class="control">
-                    <input type="text" class="input-text no-changes" data-bind="datepicker: { storage: from, options: config }, attr: {placeholder: $t('From')}">
-                </div>
-            </div>
-            <div class="field field-range-to">
-                <label class="label"><span data-bind="text: $t('To')"></span></label>
-                <div class="control">
-                    <input type="text" class="input-text no-changes" data-bind="datepicker: { storage: to, options: config }, attr: {placeholder: $t('To')}">
-                </div>
-            </div>
-        </div>
-    </div>
-</fieldset>
diff --git a/app/code/Magento/Ui/view/base/web/templates/filter/filter_input.html b/app/code/Magento/Ui/view/base/web/templates/filter/filter_input.html
deleted file mode 100644
index 0550a3907fca34af7173d0b75d40e9edd0b64327..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/templates/filter/filter_input.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<div class="field">
-    <label class="label" data-bind="attr: {for: index}">
-        <span data-bind="text: label"></span>
-    </label>
-    <div class="control">
-        <input data-bind="value: value, attr: {id: index}" class="input-text" type="text">
-    </div>
-</div>
diff --git a/app/code/Magento/Ui/view/base/web/templates/filter/filter_range.html b/app/code/Magento/Ui/view/base/web/templates/filter/filter_range.html
deleted file mode 100644
index f34b97cb89bb854436ba71d072a0b520b8f88873..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/templates/filter/filter_range.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<fieldset class="field field-range">
-    <legend class="label">
-        <span data-bind="text: label"></span>
-    </legend><br />
-    <div class="control">
-        <div class="fields group group-2">
-            <div class="field field-range-from">
-                <label class="label"><span data-bind="text: $t('From')"></span></label>
-                <div class="control hide-picker">
-                    <input type="text" class="input-text no-changes" data-bind="value: from, attr: {placeholder: $t('From')}">
-                </div>
-            </div>
-            <div class="field field-range-to">
-                <label class="label"><span data-bind="text: $t('To')"></span></label>
-                <div class="control hide-picker">
-                    <input type="text" class="input-text no-changes" data-bind="value: to, attr: {placeholder: $t('To')}">
-                </div>
-            </div>
-        </div>
-    </div>
-</fieldset>
diff --git a/app/code/Magento/Ui/view/base/web/templates/filter/filter_select.html b/app/code/Magento/Ui/view/base/web/templates/filter/filter_select.html
deleted file mode 100644
index 22be5c2d159a35a11acc731c8d6fc61c641c4216..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/templates/filter/filter_select.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<div class="field">
-    <label class="label" data-bind="attr: {for: index}">
-        <span data-bind="text: label"></span>
-    </label>
-    <div class="control">
-        <select data-bind="attr: {id: index}, options: options, value: selected, optionsText: 'label', optionsCaption: caption" class="select"></select>
-    </div>
-</div>
diff --git a/app/code/Magento/Ui/view/base/web/templates/form/components/collection.html b/app/code/Magento/Ui/view/base/web/templates/form/components/collection.html
index 5fd7ccc4bfed8874636abd5fa9c154c65ffc6422..05234c4afad7ace8a0e7261599b03eddf7c26260 100644
--- a/app/code/Magento/Ui/view/base/web/templates/form/components/collection.html
+++ b/app/code/Magento/Ui/view/base/web/templates/form/components/collection.html
@@ -10,12 +10,12 @@
         <!-- ko foreach: { data: element.elems, as: 'element' } -->
             <li class="address-list-item" data-bind="css: { 'ui-state-active': element.active }, click: activate">
                 <div class="address-list-item-actions">
-                    <button class="action-delete" type="button" data-bind="click: $parent.removeChild(element)">
+                    <button class="action-delete" type="button" data-bind="click: $parent.removeChild.bind($parent, element)">
                         <span data-bind="text: $parent.removeLabel"></span>
                     </button>
                 </div>
                 <!-- ko template: previewTpl --><!-- /ko -->
-                <div data-bind="foreach: { data: element.head, as: 'element' }, stopPropagation: true">
+                <div data-bind="foreach: { data:  element.getRegion('head'), as: 'element' }, stopPropagation: true">
                     <!-- ko template: element.getTemplate() --><!-- /ko -->
                 </div>
             </li>
@@ -35,7 +35,7 @@
                     <span data-bind="text: $parent.label"></span>
                 </legend>
                 <br>
-                <!-- ko foreach: { data: element.body, as: 'element' } -->
+                <!-- ko foreach: { data: element.getRegion('body'), as: 'element' } -->
                     <!-- ko template: element.getTemplate() --><!-- /ko -->
                 <!-- /ko -->
             </fieldset>
diff --git a/app/code/Magento/Ui/view/base/web/templates/form/components/collection/item.html b/app/code/Magento/Ui/view/base/web/templates/form/components/collection/item.html
deleted file mode 100644
index f274c3fe90f9396d739d94618104f4c4a0f7755d..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/templates/form/components/collection/item.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-
-<!-- ko foreach: { data: elems, as: 'element' } -->
-    <!-- ko template: element.getTemplate() --><!-- /ko -->    
-<!-- /ko -->
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/templates/form/components/collection/preview.html b/app/code/Magento/Ui/view/base/web/templates/form/components/collection/preview.html
index eed7c6acc697fbc9ce46ac7e1b9392a2064ada52..96ac887a7fb4aa9d40b21aea255d860c71048313 100644
--- a/app/code/Magento/Ui/view/base/web/templates/form/components/collection/preview.html
+++ b/app/code/Magento/Ui/view/base/web/templates/form/components/collection/preview.html
@@ -9,7 +9,7 @@
         data: formatPreviews([
             "prefix firstname middlename lastname suffix",
             "company",
-            "street",
+            "street_container",
             {
                 items: "city region_id postcode",
                 separator: ", "
diff --git a/app/code/Magento/Ui/view/base/web/templates/form/element/checkbox.html b/app/code/Magento/Ui/view/base/web/templates/form/element/checkbox.html
index 1f712a604aba029f64399a5063e0faf8e964a7a3..01dca8a5b9318157f562333f27546e07f3d0e081 100644
--- a/app/code/Magento/Ui/view/base/web/templates/form/element/checkbox.html
+++ b/app/code/Magento/Ui/view/base/web/templates/form/element/checkbox.html
@@ -8,12 +8,7 @@
     <input type="checkbox" class="admin__control-checkbox" data-bind="checked: value, attr: { id: uid, disabled: disabled, name: inputName }, hasFocus: focused">
 
     <label class="admin__field-label" data-bind="checked: value, attr: { for: uid }">
-        <!-- ko if: $parent.isSingle() -->
-            <span data-bind="text: description"></span>
-        <!-- /ko -->
-        <!-- ko if: !$parent.isSingle() -->
-            <span data-bind="text: description || label"></span>
-        <!-- /ko -->
+        <span data-bind="text: description || label"></span>
     </label>
 
     <!-- ko if: notice -->
diff --git a/app/code/Magento/Ui/view/base/web/templates/form/element/textarea.html b/app/code/Magento/Ui/view/base/web/templates/form/element/textarea.html
index 8aa979d0658994b3bb64d9f397e991f1bb4891bd..fa1f88ddc1fc2fdee3578b0799b5519c5ab2d8af 100644
--- a/app/code/Magento/Ui/view/base/web/templates/form/element/textarea.html
+++ b/app/code/Magento/Ui/view/base/web/templates/form/element/textarea.html
@@ -4,6 +4,7 @@
  * See COPYING.txt for license details.
  */
 -->
+
 <textarea class="admin__control-textarea" data-bind="
     value: value,
     hasFocus: focused,
diff --git a/app/code/Magento/Ui/view/base/web/templates/group/field.html b/app/code/Magento/Ui/view/base/web/templates/form/field.html
similarity index 69%
rename from app/code/Magento/Ui/view/base/web/templates/group/field.html
rename to app/code/Magento/Ui/view/base/web/templates/form/field.html
index e01470fa2aed8f7e15547bcc6c2e20f909bb9f69..8ba9dc8d3474a539de251007e8f994bb2e4e163f 100644
--- a/app/code/Magento/Ui/view/base/web/templates/group/field.html
+++ b/app/code/Magento/Ui/view/base/web/templates/form/field.html
@@ -4,22 +4,22 @@
  * See COPYING.txt for license details.
  */
 -->
-<div class="admin__field" data-bind="css: {'_required': element.required, '_disabled': element.disabled, '_error': element.error}">
+<div class="admin__field" data-bind="visible: visible, css: {'_required': element.required, '_disabled': element.disabled, '_error': element.error}">
 
     <!-- ko if: element.label -->
-    <label class="admin__field-label" data-bind="attr: { for: element.uid }, css: {'_dublicated': element.label === $parent.label}">
+    <label class="admin__field-label" data-bind="attr: { for: element.uid }">
         <span data-bind="text: element.label"></span>
     </label>
     <!-- /ko -->
 
     <div class="admin__field-control">
         <!-- ko ifnot: element.hasAddons() -->
-            <!-- ko template: element.getTemplate() --><!-- /ko -->
+            <!-- ko template: element.elementTmpl --><!-- /ko -->
         <!-- /ko -->
 
         <!-- ko if: element.hasAddons() -->
             <div class="admin__control-addon">
-                <!-- ko template: element.getTemplate() --><!-- /ko -->
+                <!-- ko template: element.elementTmpl --><!-- /ko -->
 
                 <!-- ko if: element.addbefore -->
                     <label class="admin__addon-prefix" data-bind="attr: { for: element.uid }"><span data-bind="text: element.addbefore"></span></label>
@@ -39,10 +39,9 @@
             <div class="admin__field-note" data-bind="attr: { id: element.noticeId }"><span data-bind="text: element.notice"></span></div>
         <!-- /ko -->
 
-        <!-- ko if: $parent.isSingle() -->
-             <!-- ko if: element.error() && !element.hidden() -->
-                <label class="admin__field-error" data-bind="attr: { for: element.uid }, text: element.error"></label>
-            <!-- /ko -->
+        <!-- ko if: element.error() -->
+            <label class="admin__field-error" data-bind="attr: { for: element.uid }, text: element.error"></label>
         <!-- /ko -->
     </div>
 </div>
+<!-- /ko -->
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/templates/fieldset/fieldset.html b/app/code/Magento/Ui/view/base/web/templates/form/fieldset.html
similarity index 89%
rename from app/code/Magento/Ui/view/base/web/templates/fieldset/fieldset.html
rename to app/code/Magento/Ui/view/base/web/templates/form/fieldset.html
index 7a5dc7460dc556de2f622e73d39f25f079d80126..159511ae9c30c14519ec7fc19a5978a7602b5402 100644
--- a/app/code/Magento/Ui/view/base/web/templates/fieldset/fieldset.html
+++ b/app/code/Magento/Ui/view/base/web/templates/form/fieldset.html
@@ -4,9 +4,9 @@
  * See COPYING.txt for license details.
  */
 -->
-<!-- ko if: elems -->
+
 <div class="admin__fieldset-wrapper" data-bind="css: {'collapsable-wrapper': collapsible, 'opened': opened}">
-    <div class="admin__fieldset-wrapper-title" tabindex="3" data-bind="click: onClick, keyboard: { 13: toggle }">
+    <div class="admin__fieldset-wrapper-title" tabindex="3" data-bind="click: toggleOpened, keyboard: { 13: toggleOpened }">
         <strong class="title">
             <span data-bind="text: label"></span>
         </strong>
@@ -19,4 +19,3 @@
         </fieldset>
     </div>
 </div>
-<!-- /ko -->
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/actions.html b/app/code/Magento/Ui/view/base/web/templates/grid/actions.html
new file mode 100644
index 0000000000000000000000000000000000000000..685936aa8430382b59ff1b065c74e244aadcd24a
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/templates/grid/actions.html
@@ -0,0 +1,29 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<div class="col-xs-2">
+    <div
+        class="action-select-wrap"
+        data-bind="css: {'_active': opened},
+           click: toggleOpened,
+           outerClick: close">
+        <button
+            class="action-select"
+            data-bind="title: $t('Select Items')">
+            <span data-bind="text: $t('Actions')"></span>
+        </button>
+        <ul
+            class="action-menu"
+            data-bind="css: {'_active': opened},
+                       foreach: {data: actions, as: 'action'}">
+            <li data-bind="click: $parent.applyAction.bind($parent, action)">
+            <span
+                class="action-menu-item"
+                data-bind="text: label"></span>
+            </li>
+        </ul>
+    </div>
+</div>
diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/cells/actions.html b/app/code/Magento/Ui/view/base/web/templates/grid/cells/actions.html
new file mode 100644
index 0000000000000000000000000000000000000000..1ef5fc1177e73194f9bf29a7d27554c85de47a6f
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/templates/grid/cells/actions.html
@@ -0,0 +1,30 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+
+<td class="data-grid-actions-cell">
+    <!-- ko if: getDisplayed(row[field.index]).length > 1 -->
+    <div class="action-select-wrap _active">
+        <button class="action-select">
+            <span data-bind="text: $t('Select')"></span>
+        </button>
+        <ul class="action-menu _active">
+            <li>
+                <a
+                    class="action-menu-item"
+                    data-bind="attr: {href: displayed[0].href},
+                               text: displayed[0].label"></a>
+            </li>
+        </ul>
+    </div>
+    <!-- /ko -->
+    <!-- ko ifnot: getDisplayed(row[field.index]).length > 1 -->
+    <a
+        class="action-menu-item"
+        data-bind="attr: {href: displayed[0].href},
+                               text: displayed[0].label"></a>
+    <!-- /ko -->
+</td>
diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/cells/multiselect.html b/app/code/Magento/Ui/view/base/web/templates/grid/cells/multiselect.html
new file mode 100644
index 0000000000000000000000000000000000000000..81e6b2c5bc3706a042daf1f6e2b3725e84b681c4
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/templates/grid/cells/multiselect.html
@@ -0,0 +1,18 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+
+<td class="data-grid-checkbox-cell">
+    <label class="data-grid-checkbox-cell-inner">
+        <input
+            class="admin__control-checkbox"
+            type="checkbox"
+            data-bind="checked: selected,
+                   value: row[indexField],
+                   attr: {id: 'check' + row[indexField]}">
+        <label data-bind="attr: {for: 'check' + row[indexField]}"></label>
+    </label>
+</td>
diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/cells/text.html b/app/code/Magento/Ui/view/base/web/templates/grid/cells/text.html
new file mode 100644
index 0000000000000000000000000000000000000000..aff66b7cc2c68a98579a076540dfe22a674c6654
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/templates/grid/cells/text.html
@@ -0,0 +1,16 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+
+<!-- ko if: isClickable(row) -->
+<td 
+    data-bind="click: redirect.bind($data, getClickUrl(row)),
+               html: getLabel(row[field.index])"
+    data-action="grid-row-edit"></td>
+<!-- /ko -->
+<!-- ko ifnot: isClickable(row) -->
+<td data-bind="html: getLabel(row[field.index])"></td>
+<!-- /ko -->
diff --git a/app/code/Magento/Ui/view/base/web/templates/listing/grid/cell/store.html b/app/code/Magento/Ui/view/base/web/templates/grid/columns/actions.html
similarity index 52%
rename from app/code/Magento/Ui/view/base/web/templates/listing/grid/cell/store.html
rename to app/code/Magento/Ui/view/base/web/templates/grid/columns/actions.html
index c6e156ce8e99032c45c93a7c6992787a08785547..ff0980dbe37979d4568ec2b5b8d7d41e6772fb6d 100644
--- a/app/code/Magento/Ui/view/base/web/templates/listing/grid/cell/store.html
+++ b/app/code/Magento/Ui/view/base/web/templates/grid/columns/actions.html
@@ -4,6 +4,7 @@
  * See COPYING.txt for license details.
  */
 -->
-<td data-part="body.row.cell">
-    <span data-bind="html: row[field.index]"></span>
-</td>
\ No newline at end of file
+
+<th class="data-grid-th data-grid-actions-cell">
+    <span data-bind="text: label"></span>
+</th>
diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/columns/multiselect.html b/app/code/Magento/Ui/view/base/web/templates/grid/columns/multiselect.html
new file mode 100644
index 0000000000000000000000000000000000000000..8553c127d60cbe35ea144d206a96c5294e389cc0
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/templates/grid/columns/multiselect.html
@@ -0,0 +1,41 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+
+<th class="data-grid-multiselect-cell">
+    <div
+        class="action-multiselect-wrap"
+        data-bind="css: { '_active': menuVisible, '_disabled': !totalRecords()},
+                   outerClick: hideMenu">
+        <input
+            id="mass-select-checkbox"
+            class="admin__control-checkbox"
+            type="checkbox"
+            data-bind="checked: allSelected,
+                       event: { change: toggleSelectAll },
+                       css: { '_indeterminate': indetermine },
+                       enable: totalRecords">
+        <label for="mass-select-checkbox"></label>
+        <button
+            class="action-multiselect-toggle"
+            data-toggle="dropdown"
+            data-bind="css: { '_active': menuVisible },
+                       click: toggleMenu,
+                       enable: totalRecords">
+            <span data-bind="text: $t('Options')"></span>
+        </button>
+        <ul
+            class="action-menu"
+            data-bind="click: hideMenu">
+            <!-- ko foreach: actions -->
+            <li data-bind="click: $parent[value].bind($parent),
+                           visible: $parent.isActionRelevant(value)">
+                <span class="action-menu-item" data-bind="text: label"></span>
+            </li>
+            <!-- /ko -->
+        </ul>
+    </div>
+</th>
diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/columns/text.html b/app/code/Magento/Ui/view/base/web/templates/grid/columns/text.html
new file mode 100644
index 0000000000000000000000000000000000000000..9f708c21f093a5f8c4e9a6c53eddd3ee2adb04a5
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/templates/grid/columns/text.html
@@ -0,0 +1,20 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+
+<!-- ko if: sortable -->
+    <th
+        class="data-grid-th _sortable"
+        data-bind="css: sortClass, click: sort">
+        <span data-bind="text: label"></span>
+    </th>
+<!-- /ko -->
+
+<!-- ko ifnot: sortable -->
+    <th class="data-grid-th">
+        <span data-bind="text: label"></span>
+    </th>
+<!-- /ko -->
diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/controls/columns.html b/app/code/Magento/Ui/view/base/web/templates/grid/controls/columns.html
new file mode 100644
index 0000000000000000000000000000000000000000..fafa87cfc8b505d1005959c03d513081ac382a7e
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/templates/grid/controls/columns.html
@@ -0,0 +1,45 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<div data-bind="css: {_active: opened}, outerClick: close" class="admin__action-dropdown-wrap admin__data-grid-action-columns">
+    <button
+        class="admin__action-dropdown"
+        type="button"
+        data-bind="click: toggleOpened"
+        data-toggle="dropdown"
+        aria-haspopup="true">
+        <span class="admin__action-dropdown-text" data-bind="text: $t('Columns')"></span>
+    </button>
+    <div data-bind="css: {_overflow: hasOverflow()}" class="admin__action-dropdown-menu admin__data-grid-action-columns-menu">
+        <div class="admin__action-dropdown-menu-header">
+            <span data-bind="text: getHeaderMessage($t('<%- visible %> out of <%- total %> visible'))"></span>
+        </div>
+        <div class="admin__action-dropdown-menu-content">
+            <!-- ko foreach: elems -->
+            <div class="admin__field-option">
+                <input data-bind="attr: {id: 'grid-controls-columns-' + index}, disable: $parent.isDisabled($data), checked: visible"
+                       class="admin__control-checkbox" type="checkbox"/>
+                <label data-bind="text: label, attr: {for: 'grid-controls-columns-' + index}" class="admin__field-label"></label>
+            </div>
+            <!-- /ko -->
+        </div>
+        <div class="admin__action-dropdown-menu-footer">
+            <div class="admin__action-dropdown-footer-secondary-actions">
+                <button data-bind="click: reset" class="action-tertiary" type="button">
+                    <span data-bind="text: $t('Reset')"></span>
+                </button>
+            </div>
+            <div class="admin__action-dropdown-footer-main-actions">
+                <button data-bind="click: cancel" class="action-tertiary" type="button">
+                    <span data-bind="text: $t('Cancel')"></span>
+                </button>
+                <button data-bind="click: apply" class="action-secondary" type="button">
+                    <span data-bind="text: $t('Apply')"></span>
+                </button>
+            </div>
+        </div>
+    </div>
+</div>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/controls/view.html b/app/code/Magento/Ui/view/base/web/templates/grid/controls/view.html
new file mode 100644
index 0000000000000000000000000000000000000000..fc4e1bd8656b7687d787b082da6b1fe0f3d7e000
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/templates/grid/controls/view.html
@@ -0,0 +1,60 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+
+<div
+    class="admin__action-dropdown-wrap admin__data-grid-action-bookmarks _hide"
+    data-bind="css: {_active: opened, _disabled: !collapsible}, outerClick: close">
+    <button
+        class="admin__action-dropdown"
+        type="button"
+        data-bind="click: toggleOpened"
+        data-toggle="dropdown"
+        aria-haspopup="true">
+        <span class="admin__action-dropdown-text">Default View</span>
+    </button>
+    <ul class="admin__action-dropdown-menu">
+        <!-- ko foreach: {data: sampleData, as: 'view'} -->
+        <li
+            data-bind="css: {_edit: false}">
+            <div class="action-dropdown-menu-item-edit">
+                <input
+                    class="admin__control-text"
+                    data-bind="value: view.label"
+                    type="text">
+                <button
+                    class="action-submit"
+                    type="button">
+                    <span>Submit</span>
+                </button>
+                <div class="action-dropdown-menu-item-actions">
+                    <button
+                        class="action-delete"
+                        type="button">
+                        <span>Delete</span>
+                    </button>
+                </div>
+            </div>
+            <div class="action-dropdown-menu-item">
+                <a
+                    class="action-dropdown-menu-link"
+                    href=""
+                    data-bind="text: view.label"></a>
+                <div class="action-dropdown-menu-item-actions">
+                    <button
+                        class="action-edit"
+                        type="button">
+                        <span>Edit</span>
+                    </button>
+                </div>
+            </div>
+        </li> 
+        <!-- /ko -->
+        <li class="action-dropdown-menu-item-last">
+            <a href="">Save Current View</a>
+        </li> 
+    </ul>
+</div>
diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/date.html b/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/date.html
new file mode 100644
index 0000000000000000000000000000000000000000..9fbd4a2b336d69242c5e00d56fa9ca247ebee274
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/date.html
@@ -0,0 +1,27 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+
+<div class="admin__form-field">
+    <label
+        class="admin__form-field-label"
+        data-bind="attr: {for: uid}">
+        <span data-bind="text: label"></span>
+    </label>
+    <div class="admin__form-field-control">
+        <input
+            class="admin__control-text"
+            type="text"
+            data-bind="hasFocus: focused,
+                       datepicker: { storage: value, options: options },
+                       attr: {
+                           value: value,
+                           name: inputName,
+                           'aria-describedby': noticeId,
+                           disabled: disabled
+                       }" />
+    </div>
+</div>
diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/group.html b/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/group.html
new file mode 100644
index 0000000000000000000000000000000000000000..a0374eb43cbacd05d18bc163641bd9198edc4b57
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/group.html
@@ -0,0 +1,15 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+
+<fieldset class="admin__form-field">
+    <legend class="admin__form-field-legend">
+        <span data-bind="text: label"></span>
+    </legend>
+    <!-- ko foreach: elems -->
+        <!-- ko template: getTemplate() --><!-- /ko -->
+    <!-- /ko -->
+</fieldset>
diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/input.html b/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/input.html
new file mode 100644
index 0000000000000000000000000000000000000000..8e93919ff881319024fc23dea95dd2e17fc37635
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/input.html
@@ -0,0 +1,27 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+
+<div class="admin__form-field">
+    <label
+        class="admin__form-field-label"
+        data-bind="attr: {for: uid}">
+        <span data-bind="text: label"></span>
+    </label>
+    <div class="admin__form-field-control">
+        <input
+            class="admin__control-text"
+            type="text"
+            data-bind="value: value,
+                       hasFocus: focused,
+                       attr: {
+                           name: inputName,
+                           'aria-describedby': noticeId,
+                           id: uid,
+                           disabled: disabled
+                       }" />
+    </div>
+</div>
diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/select.html b/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/select.html
new file mode 100644
index 0000000000000000000000000000000000000000..abd2502ba19b07f80d55f191ddd6bc587acedc61
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/select.html
@@ -0,0 +1,31 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+
+<div class="admin__form-field">
+    <label
+        class="admin__form-field-label"
+        data-bind="attr: {for: uid}">
+        <span data-bind="text: label"></span>
+    </label>
+    <div class="admin__field-control">
+        <select
+            class="admin__control-select"
+            data-bind="attr: {
+                           name: inputName,
+                           id: uid,
+                           disabled: disabled,
+                           'aria-describedby': noticeId,
+                           placeholder: placeholder
+                       },
+                       hasFocus: focused,
+                       optgroup: options,
+                       value: value,
+                       optionsCaption: caption,
+                       optionsValue: 'value',
+                       optionsText: 'label'"/>
+    </div>
+</div>
diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/filters/filters.html b/app/code/Magento/Ui/view/base/web/templates/grid/filters/filters.html
new file mode 100644
index 0000000000000000000000000000000000000000..ddda29706153af351d5faf217d1fc13459005783
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/templates/grid/filters/filters.html
@@ -0,0 +1,108 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+
+<div class="data-grid-search-control-wrap">
+    <input
+        class="admin__control-text data-grid-search-control"
+        placeholder="Search by keyword"
+        type="text"/>
+    <button
+        class="action-submit"
+        type="submit"><span data-bind="text: $t('Search')"></span></button>
+    <ul class="action-menu _active">
+        <li>
+            <a class="action-menu-item" href>Lorem</a>
+        </li>
+        <li>
+            <a class="action-menu-item" href>Lorem 1</a>
+        </li>
+        <li>
+            <a class="action-menu-item" href>Lorem 2</a>
+        </li>
+    </ul>
+</div>
+
+<div class="data-grid-filters-actions-wrap">
+    <div class="data-grid-filters-action-wrap">
+        <button
+            class="action-default _active"
+            data-action="grid-filter-expand"
+            data-bind="click: toggleOpened, css: { _active: opened }">
+            <span data-bind="text: $t('Filters')"></span>
+        </button>
+    </div>
+</div>
+
+<div
+    class="admin__data-grid-filters-current"
+    data-bind="css: {_show: active().length && !opened()}">
+    <div class="admin__current-filters-title-wrap">
+        <span
+            class="admin__current-filters-title"
+            data-bind="text: $t('Active filters:')"></span>
+    </div>
+    <div class="admin__current-filters-list-wrap">
+        <ul class="admin__current-filters-list">
+            <!-- ko foreach: previews -->
+            <li>
+                <span data-bind="text: label + ':'"></span>
+                <span data-bind="text: preview"></span>
+                <button
+                    class="action-remove"
+                    data-bind="click: $parent.reset.bind($parent, elem)"
+                    type="button">
+                    <span data-bind="text: $t('Remove')"></span>
+                </button>
+            </li>
+            <!-- /ko -->
+        </ul>
+    </div>
+</div>
+
+<div
+    class="admin__data-grid-filters-wrap"
+    data-bind="css: { _show: opened }"
+    data-part="filter-form">
+
+    <fieldset class="admin__fieldset admin__data-grid-filters">
+        <legend class="admin__filters-legend">
+            <span data-bind="text: $t('Advanced filter')"></span>
+        </legend>
+        <!-- ko foreach: elems -->
+        <!-- ko template: getTemplate() --><!-- /ko -->
+        <!-- /ko -->
+    </fieldset>
+
+    <div class="admin__data-grid-filters-footer">
+        <div class="admin__footer-secondary-actions">
+            <button
+                class="action-tertiary"
+                type="button"
+                data-action="grid-filter-reset"
+                data-bind="click: reset">
+                <span data-bind="text: $t('Reset')"></span>
+            </button>
+        </div>
+        <div class="admin__footer-main-actions">
+            <button
+                class="action-tertiary"
+                type="button"
+                data-action="grid-filter-cancel"
+                data-bind="click: close">
+                <span data-bind="text: $t('Cancel')"></span>
+            </button>
+            <button
+                class="action-secondary"
+                type="button"
+                data-action="grid-filter-apply"
+                data-bind="click: apply">
+                <span data-bind="text: $t('Apply Filters')"></span>
+            </button>
+        </div>
+    </div>
+
+</div>
diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/listing.html b/app/code/Magento/Ui/view/base/web/templates/grid/listing.html
new file mode 100644
index 0000000000000000000000000000000000000000..544a998a4dbc79e0dc08f0297b8d3821cf0d9fc1
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/templates/grid/listing.html
@@ -0,0 +1,38 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+
+<table class="data-grid">
+    <thead data-part="head">
+        <tr data-part="head.row">
+            <!-- ko foreach: elems -->
+                <!-- ko if: visible -->
+                    <!-- ko template: getHeader() --><!-- /ko -->
+                <!-- /ko -->
+            <!-- /ko -->
+        </tr>
+    </thead>
+    <tbody data-part="body">
+        <!-- ko if: hasData() -->
+            <!-- ko foreach: { data: rows, as: 'row' } -->
+                <tr data-part="body.row">
+                    <!-- ko foreach: { data: $parent.elems, as: 'field' }  -->
+                        <!-- ko if: visible -->
+                            <!-- ko template: getBody() --><!-- /ko -->
+                        <!-- /ko -->
+                    <!-- /ko -->
+                </tr>
+            <!-- /ko -->
+        <!-- /ko -->
+
+        <!-- ko ifnot: hasData() -->
+            <tr class="data-grid-tr-no-data">
+                <td data-bind="attr: { colspan: getColspan() },
+                               text: $t('We couldn\'t find any records.')"></td>
+            </tr>
+        <!-- /ko -->
+    </tbody>
+</table>
diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/paging.html b/app/code/Magento/Ui/view/base/web/templates/grid/paging.html
new file mode 100644
index 0000000000000000000000000000000000000000..9f4f5cc2fdcb5101d7e3969bf9e06ae1be8e0af9
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/templates/grid/paging.html
@@ -0,0 +1,50 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<div class="col-xs-3">
+    <div class="admin__control-support-text">
+        <span data-bind="text: totalRecords"></span> records found
+        <!-- ko if: totalSelected -->
+        (<span data-bind="text: totalSelected"></span> selected)
+        <!-- /ko -->
+    </div>
+</div>
+
+<div class="col-xs-7 admin__data-grid-pager-wrap">
+    <select
+        id="perPage"
+        class="admin__control-select"
+        data-bind="options: options,
+                   value: pageSize,
+                   optionsValue: 'value',
+                   optionsText: 'label'"></select>
+    <label class="admin__control-support-text" for="perPage">per page</label>
+
+    <div class="admin__data-grid-pager">
+        <button
+            class="action-previous"
+            type="button"
+            data-bind="css: { disabled: isFirst() },
+                   click: prev">
+            <span>Previous page</span>
+        </button>
+        <input
+            id="pageCurrent"
+            class="admin__control-text"
+            data-bind="value: _current"
+            type="number" />
+        <label class="admin__control-support-text" for="pageCurrent">
+            of <span data-bind="text: pages"></span>
+        </label>
+        <button
+            class="action-next"
+            data-bind="css: { disabled: isLast() },
+                       click: next">
+            <span>Next page</span>
+        </button>
+    </div>
+
+</div>
diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/toolbar.html b/app/code/Magento/Ui/view/base/web/templates/grid/toolbar.html
new file mode 100644
index 0000000000000000000000000000000000000000..0812e3fe862d2fac42f48fdd80ead31355f23107
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/templates/grid/toolbar.html
@@ -0,0 +1,24 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+
+<div class="admin__data-grid-header">
+    <div class="admin__data-grid-header-row">
+        <div class="admin__data-grid-actions-wrap">
+            <!-- ko foreach: getRegion('dataGridActions') -->
+                <!-- ko template: getTemplate() --><!-- /ko -->
+            <!-- /ko -->
+        </div>
+        <!-- ko foreach: getRegion('dataGridFilters') -->
+            <!-- ko template: getTemplate() --><!-- /ko -->
+        <!-- /ko -->
+    </div>
+    <div class="admin__data-grid-header-row row row-gutter">
+        <!-- ko foreach: getRegion('bottom') -->
+            <!-- ko template: getTemplate() --><!-- /ko -->
+        <!-- /ko -->
+    </div>
+</div>
diff --git a/app/code/Magento/Ui/view/base/web/templates/group/group.html b/app/code/Magento/Ui/view/base/web/templates/group/group.html
index 519aefbcee9f2dae72e0db9fd75f74738d8aeba8..7db2db6edfd14dfb0de0a56abf7ccedc026d1a59 100644
--- a/app/code/Magento/Ui/view/base/web/templates/group/group.html
+++ b/app/code/Magento/Ui/view/base/web/templates/group/group.html
@@ -4,8 +4,6 @@
  * See COPYING.txt for license details.
  */
 -->
-
-<!-- ko if: element.isMultiple() -->
 <fieldset class="admin__field" data-bind="css: {'_required': element.required}">
     <legend class="admin__field-label">
         <span data-bind="text: element.label"></span>
@@ -13,14 +11,14 @@
     <div class="admin__field-control" data-bind="css: {'admin__control-fields': element.breakLine, 'admin__control-grouped': !element.breakLine}">
         <!-- ko foreach: { data: elems, as: 'element' } -->
 
-            <!-- ko ifnot: element.hidden -->
+            <!-- ko if: element.visible() -->
 
                 <!-- ko ifnot: (element.input_type == 'checkbox' || element.input_type == 'radio') -->
                     <!-- ko template: $parent.fieldTemplate --><!-- /ko -->
                 <!-- /ko -->
 
                 <!-- ko if: (element.input_type == 'checkbox' || element.input_type == 'radio') -->
-                    <!-- ko template: element.getTemplate() --><!-- /ko -->
+                    <!-- ko template: element.elementTmpl --><!-- /ko -->
                 <!-- /ko -->
 
             <!-- /ko -->
@@ -28,20 +26,9 @@
         <!-- /ko -->
 
         <!-- ko foreach: { data: elems, as: 'element' } -->
-            <!-- ko if: element.error() && !element.hidden() -->
+            <!-- ko if: element.error() && element.visible() -->
                 <label class="admin__field-error" data-bind="attr: { for: uid }, text: element.error"></label>
             <!-- /ko -->
         <!-- /ko -->
     </div>
 </fieldset>
-<!-- /ko -->
-
-<!-- ko if: element.isSingle() -->
-
-    <!-- ko foreach: { data: elems, as: 'element' } -->
-
-        <!-- ko template: $parent.fieldTemplate --><!-- /ko -->
-
-    <!-- /ko -->
-
-<!-- /ko -->
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/templates/listing/grid.html b/app/code/Magento/Ui/view/base/web/templates/listing/grid.html
deleted file mode 100644
index 6349b6c08e146c12c320bd78e811d9d437fe739d..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/templates/listing/grid.html
+++ /dev/null
@@ -1,36 +0,0 @@
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<div class="hor-scroll">
-    <table class="data">
-        <thead data-part="head">
-            <tr class="headings" data-part="head.row">
-                <!-- ko foreach: { data: fields, as: 'field' } -->
-                <th>
-                    <span data-bind="text: field.label"></span>
-                </th>
-                <!-- /ko -->
-            </tr>
-        </thead>
-        <tbody data-part="body">
-            <!-- ko if: hasData() -->
-                <!-- ko foreach: { data: rows, as: 'row' } -->
-                    <tr data-part="body.row" class="even pointer" data-bind="click: $parent.applyItemActionFor(row)">
-                        <!-- ko foreach: { data: $parent.fields, as: 'field' }  -->
-                            <!-- ko template: $parents[1].getCellTemplateFor(field) --><!-- /ko -->
-                        <!-- /ko -->
-                    </tr>
-                <!-- /ko -->
-            <!-- /ko -->
-
-             <!-- ko ifnot: hasData() -->
-                <tr class="even">
-                    <td class="empty-text" data-bind="attr: { colspan: colspan }, text: $t('We couldn\'t find any records.')"></td>
-                </tr>
-             <!-- /ko -->
-        </tbody>
-    </table>
-</div>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/templates/listing/grid/cell/actions.html b/app/code/Magento/Ui/view/base/web/templates/listing/grid/cell/actions.html
deleted file mode 100644
index 0ebd67b45eecddff54c777e51ee68c6d63380e20..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/templates/listing/grid/cell/actions.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<td data-part="body.row.cell" data-bind="stopPropagation: true">
-    <div data-bind="if: window.Array.isArray(row[field.index])">
-        <div data-bind="foreach: { data: row[field.index], as: 'action' }">
-            <a target="_blank" data-bind="attr: { href: action.href }, text: action.label"></a>
-        </div>
-    </div>
-    <div data-bind="ifnot: window.Array.isArray(row[field.index])">
-        <a target="_blank" data-bind="attr: { href: row[field.index].href }, text: row[field.index].label"></a>
-    </div>
-</td>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/templates/listing/grid/cell/date.html b/app/code/Magento/Ui/view/base/web/templates/listing/grid/cell/date.html
deleted file mode 100644
index 0bed40dd404be7b7b11bc99a19b57225ec46f6ed..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/templates/listing/grid/cell/date.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<td data-part="body.row.cell">
-    <span data-bind="date: { value: row[field.index], format: field.date_format }"></span>
-</td>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/templates/listing/grid/cell/text.html b/app/code/Magento/Ui/view/base/web/templates/listing/grid/cell/text.html
deleted file mode 100644
index 5ee35346b921d02384022322173b18ea8a0372bb..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/templates/listing/grid/cell/text.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<td data-part="body.row.cell">
-    <span data-bind="'if': 'options' in $data">
-        <span data-bind="text: options[row[index]]"></span>
-    </span>
-    <span data-bind="ifnot: 'options' in $data">
-        <span data-bind="text: row[field.index]"></span>
-    </span>
-</td>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/templates/listing/grid/extender/selectable.html b/app/code/Magento/Ui/view/base/web/templates/listing/grid/extender/selectable.html
deleted file mode 100644
index b3a385c92b8fd62b2cdce54188fcecdb5dc15837..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/templates/listing/grid/extender/selectable.html
+++ /dev/null
@@ -1,38 +0,0 @@
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<table>
-    <thead>
-        <tr data-part-prepend="head.row">
-            <th class="col-select col-massaction" data-bind="scope: $parent.getExtender('massaction')">
-                <div class="mass-select" data-bind="outerClick: hideMenu, stopPropagation: true">
-                    <label class="field choice mass-select-field">
-                        <input type="checkbox" id="mass-select-checkbox" data-bind="checked: allSelected, event: { 'change': toggleSelectAll }">
-                    </label>
-                    <button class="mass-select-toggle" data-toggle="dropdown" data-bind="css: { 'active': menuVisible }, click: onToggle('menuVisible')">
-                        <span data-bind="text: $t('Options')"></span>
-                    </button>
-                    <ul class="mass-select-menu" data-bind="css: { 'active': menuVisible } ">
-                        <!-- ko foreach: { data: selects , as: 'action' } -->
-                        <li data-bind="click: $parent.onApplySelect(action.value), visible: $parent.shouldBeVisible(action.value)">
-                            <span data-bind="text: $t(action.label)"></span>
-                        </li>
-                        <!-- /ko -->
-                    </ul>
-                </div>
-            </th>
-        </tr>
-    </thead>
-    <tbody>
-        <tr data-part-prepend="body.row">
-            <td class="col-select col-massaction" data-bind="scope: $parent.getExtender('massaction'), stopPropagation: true">
-                <label class="select-box" data-bind="stopPropagation: true">
-                    <input type="checkbox" class="massaction-checkbox" data-bind="checked: selected, value: row[indexField]">
-                </label>
-            </td>
-        </tr>
-    </tbody>
-</table>
diff --git a/app/code/Magento/Ui/view/base/web/templates/listing/grid/extender/sortable.html b/app/code/Magento/Ui/view/base/web/templates/listing/grid/extender/sortable.html
deleted file mode 100644
index 10d0d3f92cd477c62943917ea3846024903d5ed6..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/templates/listing/grid/extender/sortable.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<table>
-    <thead data-part-replace="head" data-bind="scope: getExtender('sorting')">
-        <tr class="headings" data-part="head.row">
-            <!-- ko foreach: { data: $parent.fields, as: 'field' } -->
-            <th>
-                <!-- ko if: field.sortable -->
-                <span>
-                    <a href="#" data-bind="text: field.label, css: $parent.setClass(field.index), click: $parent.onClick(field)"></a>
-                </span>
-                <!-- /ko -->
-                
-                <!-- ko ifnot: field.sortable -->
-                <span data-bind="text: field.label"></span>
-                <!-- /ko -->
-            </th>
-            <!-- /ko -->
-        </tr>
-    </thead>
-</table>
diff --git a/app/code/Magento/Ui/view/base/web/templates/massaction.html b/app/code/Magento/Ui/view/base/web/templates/massaction.html
deleted file mode 100644
index 547c92de838807804ce6e2607c2f19b3f0b41dd1..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/templates/massaction.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<div title="Select Items" class="actions-split" data-bind="css: {'active': actionsVisible}, stopPropagation: true, outerClick: hideActions">
-    <button title="Actions" class="action-default scalable add" data-bind="click: onToggle('actionsVisible')">
-        <span data-bind="text: $t('Actions')"></span>
-    </button>
-    <button title="" class="action-toggle scalable add" data-toggle="dropdown" data-bind="click: onToggle('actionsVisible'), css: {active: actionsVisible}">
-        <span data-bind="text: $t('Select')"></span>
-    </button>
-    <ul class="dropdown-menu" data-bind="css: {'active': actionsVisible}, foreach: {data: actions, as: 'action'}">
-        <li data-bind="click: $parent.setAction(action)"><span class="item" data-bind="text: label"></span></li>
-    </ul>
-</div>
diff --git a/app/code/Magento/Ui/view/base/web/templates/pageactions.html b/app/code/Magento/Ui/view/base/web/templates/pageactions.html
deleted file mode 100644
index caf4d917fadfaaa6827f1a25cbd45682bbfa747d..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/templates/pageactions.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<div class="page-main-actions">
-    <div class="page-actions-placeholder"></div>
-    <div data-mage-init='{"floatingHeader": {}}' class="page-actions" data-ui-id="page-actions-toolbar-content-header">
-        <div class="page-actions-inner" data-title="Pages">
-            <div class="page-actions-buttons">
-                <!-- ko foreach: actions -->
-                <button data-bind="
-                            attr: {title: $t(label)},
-                            css: {primary: type === 'primary'},
-                            click: $parent.redirectTo(url)"
-                        type="button"
-                        class="action- scalable add"
-                        data-ui-id="cms-page-add-button">
-                    <span data-bind="text: $t(label)"></span>
-                </button>
-                <!-- /ko -->
-            </div>
-        </div>
-    </div>
-</div>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/templates/pagination.html b/app/code/Magento/Ui/view/base/web/templates/pagination.html
deleted file mode 100644
index 9046c0f4a1c4b063b7c0df6f04f22d846eae397b..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/base/web/templates/pagination.html
+++ /dev/null
@@ -1,32 +0,0 @@
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<span data-part="left">
-    <span class="pages-total-found">
-        <strong data-bind="text: totalCount"></strong> records found
-         <!-- ko if: selected -->
-        (<strong data-bind="text: selected"></strong> selected)
-        <!-- /ko -->
-    </span>
-    <label class="view-pages">
-        View
-        <select data-bind="options: sizes, value: pageSize, event: { change: onSizeChange}"></select>
-        per page.
-    </label>
-</span>
-<span data-part="right">
-    <span data-bind="css: { disabled: isFirst() }, click: prev" class="action-previous">
-        <span>Previous page</span>
-    </span>
-    <input data-bind="value: current, event: {change: onPageChange}" type="text" class="input-text page" />
-    <span class="pages-total">
-        of
-        <span data-bind="text: pages"></span>
-    </span>
-    <span data-bind="css: { disabled: isLast() }, click: next" class="action-next">
-        <span>Next page</span>
-    </span>
-</span>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/templates/tab.html b/app/code/Magento/Ui/view/base/web/templates/tab.html
index d2ff2cd5e890392506e6bae7d6455af70a97965c..8f11fa286ba637260a49d267c52f8f1690e48024 100644
--- a/app/code/Magento/Ui/view/base/web/templates/tab.html
+++ b/app/code/Magento/Ui/view/base/web/templates/tab.html
@@ -5,8 +5,8 @@
  */
 -->
 <div class="admin__page-nav">
-    <div class="admin__page-nav-title" data-bind="css: { '_collapsible': collapsible, '_opened': opened() && collapsible }, click: toggle, click: onClick, keyboard: { 13: onClick }">
-        <strong tabindex="1" data-bind="text: label, keyboard: { 13: toggle }"></strong>
+    <div class="admin__page-nav-title" data-bind="css: { '_collapsible': collapsible, '_opened': opened && collapsible }, click: toggleOpened, keyboard: { 13: toggleOpened }">
+        <strong tabindex="1" data-bind="text: label, keyboard: { 13: toggleOpened }"></strong>
     </div>
     <ul class="admin__page-nav-items items" data-bind="visible: opened">
         <!-- ko foreach: elems -->
diff --git a/app/code/Magento/Ups/composer.json b/app/code/Magento/Ups/composer.json
index 3fed6bdce1e18410c2fc17a53d32f8a93d940f78..d22db469d42c92b9f0b1f004872435abbcc3bf9b 100644
--- a/app/code/Magento/Ups/composer.json
+++ b/app/code/Magento/Ups/composer.json
@@ -3,18 +3,18 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-sales": "0.74.0-beta6",
-        "magento/module-shipping": "0.74.0-beta6",
-        "magento/module-directory": "0.74.0-beta6",
-        "magento/module-catalog-inventory": "0.74.0-beta6",
-        "magento/module-quote": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-sales": "0.74.0-beta7",
+        "magento/module-shipping": "0.74.0-beta7",
+        "magento/module-directory": "0.74.0-beta7",
+        "magento/module-catalog-inventory": "0.74.0-beta7",
+        "magento/module-quote": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/UrlRewrite/composer.json b/app/code/Magento/UrlRewrite/composer.json
index 1156b7cb79022a4f0caf8e293c1b752ecc4d0cef..b49e137af5d05c8943bcee48f4e13d54db8c4648 100644
--- a/app/code/Magento/UrlRewrite/composer.json
+++ b/app/code/Magento/UrlRewrite/composer.json
@@ -3,17 +3,17 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-catalog-url-rewrite": "0.74.0-beta6",
-        "magento/module-cms": "0.74.0-beta6",
-        "magento/module-cms-url-rewrite": "0.74.0-beta6",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-catalog-url-rewrite": "0.74.0-beta7",
+        "magento/module-cms": "0.74.0-beta7",
+        "magento/module-cms-url-rewrite": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/User/Controller/Adminhtml/User/Edit.php b/app/code/Magento/User/Controller/Adminhtml/User/Edit.php
index 3d3ad64cd201a0bf5cc7eb3691852ab451317e21..39ac43d55391ba02f47089b28233a7f13e791d86 100644
--- a/app/code/Magento/User/Controller/Adminhtml/User/Edit.php
+++ b/app/code/Magento/User/Controller/Adminhtml/User/Edit.php
@@ -6,6 +6,8 @@
  */
 namespace Magento\User\Controller\Adminhtml\User;
 
+use Magento\Framework\Locale\Resolver;
+
 class Edit extends \Magento\User\Controller\Adminhtml\User
 {
     /**
@@ -25,7 +27,7 @@ class Edit extends \Magento\User\Controller\Adminhtml\User
                 return;
             }
         } else {
-            $model->setInterfaceLocale(\Magento\Framework\Locale\ResolverInterface::DEFAULT_LOCALE);
+            $model->setInterfaceLocale(Resolver::DEFAULT_LOCALE);
         }
 
         // Restore previously entered form data from session
diff --git a/app/code/Magento/User/composer.json b/app/code/Magento/User/composer.json
index 1d387c17899055557bb811a7c3024d38b90ef587..6c4a9d182196217ea7a011ad8894f37a11884cb4 100644
--- a/app/code/Magento/User/composer.json
+++ b/app/code/Magento/User/composer.json
@@ -3,15 +3,15 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-authorization": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-integration": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-authorization": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-integration": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Usps/composer.json b/app/code/Magento/Usps/composer.json
index 382961b5610b48750b1aa3e64d77e46433cae688..5e50dcbc46c23ff314332a4aabc477379b318927 100644
--- a/app/code/Magento/Usps/composer.json
+++ b/app/code/Magento/Usps/composer.json
@@ -3,20 +3,20 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-shipping": "0.74.0-beta6",
-        "magento/module-directory": "0.74.0-beta6",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/module-sales": "0.74.0-beta6",
-        "magento/module-catalog-inventory": "0.74.0-beta6",
-        "magento/module-quote": "0.74.0-beta6",
-        "magento/module-config": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-shipping": "0.74.0-beta7",
+        "magento/module-directory": "0.74.0-beta7",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/module-sales": "0.74.0-beta7",
+        "magento/module-catalog-inventory": "0.74.0-beta7",
+        "magento/module-quote": "0.74.0-beta7",
+        "magento/module-config": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "lib-libxml": "*",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Variable/composer.json b/app/code/Magento/Variable/composer.json
index ececb67d0ec8b20c51576dfe0b271f50a9c98015..87583d867fa2eec4500366d36c5b7cc4363f89cf 100644
--- a/app/code/Magento/Variable/composer.json
+++ b/app/code/Magento/Variable/composer.json
@@ -3,14 +3,14 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0|~5.6.0",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-email": "0.74.0-beta6",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-email": "0.74.0-beta7",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Version/composer.json b/app/code/Magento/Version/composer.json
index 7bb5e528673b62f88d0c668ab148cdae4dfbcd35..804db0bd8f4ec5d5119b4bfd830bb59eba08f679 100644
--- a/app/code/Magento/Version/composer.json
+++ b/app/code/Magento/Version/composer.json
@@ -3,11 +3,11 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/framework": "0.74.0-beta6",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Webapi/Controller/Rest/Router/Route.php b/app/code/Magento/Webapi/Controller/Rest/Router/Route.php
index 5c125c29611d9e2000436a7147329dfa449ab729..03e6d2fd8ca06eb864bfa318af4a91182e8c1bb7 100644
--- a/app/code/Magento/Webapi/Controller/Rest/Router/Route.php
+++ b/app/code/Magento/Webapi/Controller/Rest/Router/Route.php
@@ -69,7 +69,7 @@ class Route implements RouterInterface
                 $this->variables[$key] = substr($value, 1);
                 $value = null;
             }
-            $result[$key] = strtolower($value);
+            $result[$key] = $value;
         }
         return $result;
     }
@@ -92,19 +92,12 @@ class Route implements RouterInterface
     /**
      * Retrieve unified requested path
      *
-     * Lowercase all path chunks, except variables names.
-     * E.g. the path '/V1/Categories/:categoryId' will be converted to '/v1/categories/:categoryId'.
-     *
      * @param string $path
      * @return array
      */
     protected function getPathParts($path)
     {
-        $result = explode('/', trim($path, '/'));
-        array_walk($result, function (&$item) {
-            $item = substr($item, 0, 1) === ":" ? $item : strtolower($item);
-        });
-        return $result;
+        return explode('/', trim($path, '/'));
     }
 
     /**
diff --git a/app/code/Magento/Webapi/Controller/Soap/Request/Handler.php b/app/code/Magento/Webapi/Controller/Soap/Request/Handler.php
index 25d196ce6a80461109ec3246bbe3a5bb895cfa22..ec73bd7236c104f5364b03433e83d8c622e12414 100644
--- a/app/code/Magento/Webapi/Controller/Soap/Request/Handler.php
+++ b/app/code/Magento/Webapi/Controller/Soap/Request/Handler.php
@@ -15,6 +15,7 @@ use Magento\Framework\Webapi\ServiceInputProcessor;
 use Magento\Webapi\Controller\Soap\Request as SoapRequest;
 use Magento\Framework\Webapi\Exception as WebapiException;
 use Magento\Webapi\Model\Soap\Config as SoapConfig;
+use Magento\Framework\Reflection\MethodsMap;
 
 /**
  * Handler of requests to SOAP server.
@@ -48,6 +49,9 @@ class Handler
     /** @var DataObjectProcessor */
     protected $_dataObjectProcessor;
 
+    /** @var MethodsMap */
+    protected $methodsMapProcessor;
+
     /**
      * Initialize dependencies.
      *
@@ -58,6 +62,7 @@ class Handler
      * @param SimpleDataObjectConverter $dataObjectConverter
      * @param ServiceInputProcessor $serviceInputProcessor
      * @param DataObjectProcessor $dataObjectProcessor
+     * @param MethodsMap $methodsMapProcessor
      */
     public function __construct(
         SoapRequest $request,
@@ -66,7 +71,8 @@ class Handler
         AuthorizationInterface $authorization,
         SimpleDataObjectConverter $dataObjectConverter,
         ServiceInputProcessor $serviceInputProcessor,
-        DataObjectProcessor $dataObjectProcessor
+        DataObjectProcessor $dataObjectProcessor,
+        MethodsMap $methodsMapProcessor
     ) {
         $this->_request = $request;
         $this->_objectManager = $objectManager;
@@ -75,6 +81,7 @@ class Handler
         $this->_dataObjectConverter = $dataObjectConverter;
         $this->serviceInputProcessor = $serviceInputProcessor;
         $this->_dataObjectProcessor = $dataObjectProcessor;
+        $this->methodsMapProcessor = $methodsMapProcessor;
     }
 
     /**
@@ -149,7 +156,7 @@ class Handler
     protected function _prepareResponseData($data, $serviceClassName, $serviceMethodName)
     {
         /** @var string $dataType */
-        $dataType = $this->_dataObjectProcessor->getMethodReturnType($serviceClassName, $serviceMethodName);
+        $dataType = $this->methodsMapProcessor->getMethodReturnType($serviceClassName, $serviceMethodName);
         $result = null;
         if (is_object($data)) {
             $result = $this->_dataObjectConverter
diff --git a/app/code/Magento/Webapi/Model/Rest/Config.php b/app/code/Magento/Webapi/Model/Rest/Config.php
index dfee1d873c02158645f482b3fe7242ecc5636bfe..51d0e67d7803603ef4ff02e6db406f041166b2d9 100644
--- a/app/code/Magento/Webapi/Model/Rest/Config.php
+++ b/app/code/Magento/Webapi/Model/Rest/Config.php
@@ -67,7 +67,7 @@ class Config
         /** @var $route \Magento\Webapi\Controller\Rest\Router\Route */
         $route = $this->_routeFactory->createRoute(
             'Magento\Webapi\Controller\Rest\Router\Route',
-            $this->_formatRoutePath($routeData[self::KEY_ROUTE_PATH])
+            $routeData[self::KEY_ROUTE_PATH]
         );
 
         $route->setServiceClass($routeData[self::KEY_CLASS])
@@ -78,22 +78,6 @@ class Config
         return $route;
     }
 
-    /**
-     * Lowercase all parts of the given route path except for the path parameters.
-     *
-     * @param string $routePath The route path (e.g. '/V1/Categories/:categoryId')
-     * @return string The modified route path (e.g. '/v1/categories/:categoryId')
-     */
-    protected function _formatRoutePath($routePath)
-    {
-        $routePathParts = explode('/', $routePath);
-        $pathParts = [];
-        foreach ($routePathParts as $pathPart) {
-            $pathParts[] = substr($pathPart, 0, 1) === ":" ? $pathPart : strtolower($pathPart);
-        }
-        return implode('/', $pathParts);
-    }
-
     /**
      * Get service base URL
      *
diff --git a/app/code/Magento/Webapi/Test/Unit/Controller/Rest/Router/RouteTest.php b/app/code/Magento/Webapi/Test/Unit/Controller/Rest/Router/RouteTest.php
index 6732d012dc1e726e29e4afab132711759d4ce7f9..4a9192b36882b9f69a66755af08cd3f050374beb 100644
--- a/app/code/Magento/Webapi/Test/Unit/Controller/Rest/Router/RouteTest.php
+++ b/app/code/Magento/Webapi/Test/Unit/Controller/Rest/Router/RouteTest.php
@@ -95,10 +95,7 @@ class RouteTest extends \PHPUnit_Framework_TestCase
             ['/V1/one/two/:threeValue/four/:fiveValue', '/V1/one/two/3/four/5', ['threeValue' => 3, 'fiveValue' => 5]],
 
             ['/v1/One', '/v1/One', []],
-            ['/v1/oNe', '/V1/one', []],
-            ['/v1/onE', '/V1/oNe', []],
 
-            ['/v1/One/:twoValue', '/V1/one/2', ['twoValue' => 2]],
             ['/v1/oNe/:TwoValue', '/v1/oNe/2', ['TwoValue' => 2]],
             ['/v1/onE/:twovalue', '/v1/onE/2', ['twovalue' => 2]],
 
@@ -108,6 +105,9 @@ class RouteTest extends \PHPUnit_Framework_TestCase
             ['/V1/one-one/:two_value', '/V1/one-one/2', ['two_value' => 2]],
 
             // Error
+            ['/v1/oNe', '/V1/one', false],
+            ['/v1/onE', '/V1/oNe', false],
+            ['/v1/One/:twoValue', '/V1/one/2', false],
             ['/V1/one', '/V1/two', false],
             ['/V1/one/:twoValue', '/V1/one', false],
             ['/V1/one/two', '/V1/one', false],
diff --git a/app/code/Magento/Webapi/Test/Unit/Controller/Soap/Request/HandlerTest.php b/app/code/Magento/Webapi/Test/Unit/Controller/Soap/Request/HandlerTest.php
index 2800d5466585fdc8eec97ba82dd53d7f5fee0c93..8c3741c3b8d48c86e0e876125cee6558a2c3a403 100644
--- a/app/code/Magento/Webapi/Test/Unit/Controller/Soap/Request/HandlerTest.php
+++ b/app/code/Magento/Webapi/Test/Unit/Controller/Soap/Request/HandlerTest.php
@@ -40,6 +40,9 @@ class HandlerTest extends \PHPUnit_Framework_TestCase
     /** @var \Magento\Framework\Reflection\DataObjectProcessor|\PHPUnit_Framework_MockObject_MockObject */
     protected $_dataObjectProcessorMock;
 
+    /** @var \Magento\Framework\Reflection\MethodsMap|\PHPUnit_Framework_MockObject_MockObject */
+    protected $_methodsMapProcessorMock;
+
     /** @var array */
     protected $_arguments;
 
@@ -67,7 +70,13 @@ class HandlerTest extends \PHPUnit_Framework_TestCase
         );
         $this->_dataObjectProcessorMock = $this->getMock(
             'Magento\Framework\Reflection\DataObjectProcessor',
-            ['getMethodReturnType'],
+            [],
+            [],
+            '',
+            false);
+        $this->_methodsMapProcessorMock = $this->getMock(
+            'Magento\Framework\Reflection\MethodsMap',
+            [],
             [],
             '',
             false);
@@ -80,7 +89,8 @@ class HandlerTest extends \PHPUnit_Framework_TestCase
             $this->_authorizationMock,
             $this->_dataObjectConverter,
             $this->_serviceInputProcessorMock,
-            $this->_dataObjectProcessorMock
+            $this->_dataObjectProcessorMock,
+            $this->_methodsMapProcessorMock
         );
         parent::setUp();
     }
@@ -128,10 +138,6 @@ class HandlerTest extends \PHPUnit_Framework_TestCase
             ->method('process')
             ->will($this->returnArgument(2));
 
-        $this->_dataObjectProcessorMock->expects($this->any())->method('getMethodReturnType')
-            ->with($className, $methodName)
-            ->will($this->returnValue('string'));
-
         /** Execute SUT. */
         $this->assertEquals(
             ['result' => $serviceResponse],
diff --git a/app/code/Magento/Webapi/Test/Unit/Model/DataObjectProcessorTest.php b/app/code/Magento/Webapi/Test/Unit/Model/DataObjectProcessorTest.php
index 3453c7e1d7951de030d96012f813477fe73efd4b..c3f586d835a8d3c3d1d85e3626e258680541441c 100644
--- a/app/code/Magento/Webapi/Test/Unit/Model/DataObjectProcessorTest.php
+++ b/app/code/Magento/Webapi/Test/Unit/Model/DataObjectProcessorTest.php
@@ -23,7 +23,21 @@ class DataObjectProcessorTest extends \PHPUnit_Framework_TestCase
     protected function setup()
     {
         $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
-        $this->dataObjectProcessor = $objectManager->getObject('Magento\Framework\Reflection\DataObjectProcessor');
+        $methodsMapProcessor = $objectManager->getObject(
+            'Magento\Framework\Reflection\MethodsMap',
+            [
+                'fieldNamer' => $objectManager->getObject('Magento\Framework\Reflection\FieldNamer'),
+                'typeProcessor' => $objectManager->getObject('Magento\Framework\Reflection\TypeProcessor'),
+            ]
+        );
+        $this->dataObjectProcessor = $objectManager->getObject(
+            'Magento\Framework\Reflection\DataObjectProcessor',
+            [
+                'methodsMapProcessor' => $methodsMapProcessor,
+                'typeCaster' => $objectManager->getObject('Magento\Framework\Reflection\TypeCaster'),
+                'fieldNamer' => $objectManager->getObject('Magento\Framework\Reflection\FieldNamer'),
+            ]
+        );
         parent::setUp();
     }
 
diff --git a/app/code/Magento/Webapi/Test/Unit/Model/Files/TestDataInterface.php b/app/code/Magento/Webapi/Test/Unit/Model/Files/TestDataInterface.php
index 1b4f971c2c3a447261a22ce6bb898311813e65b7..2010509ff416165858cbdcb1b1d3b3ae298c9759 100644
--- a/app/code/Magento/Webapi/Test/Unit/Model/Files/TestDataInterface.php
+++ b/app/code/Magento/Webapi/Test/Unit/Model/Files/TestDataInterface.php
@@ -8,11 +8,23 @@ namespace Magento\Webapi\Test\Unit\Model\Files;
 
 interface TestDataInterface
 {
+    /**
+     * @return string
+     */
     public function getId();
 
+    /**
+     * @return string
+     */
     public function getAddress();
 
+    /**
+     * @return string
+     */
     public function isDefaultShipping();
 
+    /**
+     * @return string
+     */
     public function isRequiredBilling();
 }
diff --git a/app/code/Magento/Webapi/composer.json b/app/code/Magento/Webapi/composer.json
index c2e4ec4dacb4f073ed7c35ac5a1a557e8c27db70..4097e63655d1654cbe39c0a5d767abaf613abbcf 100644
--- a/app/code/Magento/Webapi/composer.json
+++ b/app/code/Magento/Webapi/composer.json
@@ -3,18 +3,18 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-authorization": "0.74.0-beta6",
-        "magento/module-integration": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-authorization": "0.74.0-beta7",
+        "magento/module-integration": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "suggest": {
-        "magento/module-user": "0.74.0-beta6"
+        "magento/module-user": "0.74.0-beta7"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Webapi/etc/di.xml b/app/code/Magento/Webapi/etc/di.xml
index 12b661f639c428c681b98b1df7c0f5a8131da632..c58acdbf51c4b9e3252745d425b3d365e2a60449 100644
--- a/app/code/Magento/Webapi/etc/di.xml
+++ b/app/code/Magento/Webapi/etc/di.xml
@@ -22,11 +22,17 @@
     <type name="Magento\Framework\Xml\Parser" shared="false" />
     <type name="Magento\Framework\Code\Scanner\DirectoryScanner" shared="false" />
     <type name="Magento\Server\Reflection" shared="false" />
-    <type name="Magento\Framework\Reflection\DataObjectProcessor">
+    <type name="Magento\Framework\Reflection\MethodsMap">
         <arguments>
             <argument name="cache" xsi:type="object">Magento\Framework\App\Cache\Type\Webapi</argument>
         </arguments>
     </type>
+    <type name="Magento\Framework\Reflection\DataObjectProcessor">
+        <arguments>
+            <argument name="extensionAttributesProcessor" xsi:type="object">Magento\Framework\Reflection\ExtensionAttributesProcessor\Proxy</argument>
+            <argument name="customAttributesProcessor" xsi:type="object">Magento\Framework\Reflection\CustomAttributesProcessor\Proxy</argument>
+        </arguments>
+    </type>
     <type name="Magento\Integration\Model\ConfigBasedIntegrationManager">
         <plugin name="webapiSetup" type="Magento\Webapi\Model\Plugin\Manager" />
     </type>
diff --git a/app/code/Magento/Webapi/etc/webapi_rest/di.xml b/app/code/Magento/Webapi/etc/webapi_rest/di.xml
index 48420045d4afca1644c159d3fa68a541cd8c403a..7941e76f564b0fa13986a9847e250a34f36d383c 100644
--- a/app/code/Magento/Webapi/etc/webapi_rest/di.xml
+++ b/app/code/Magento/Webapi/etc/webapi_rest/di.xml
@@ -71,4 +71,25 @@
     <type name="Magento\Framework\Authorization">
         <plugin name="guestAuthorization" type="Magento\Webapi\Model\Plugin\GuestAuthorization" />
     </type>
+
+    <!-- Configuration to check that the permissions are checked on fields -->
+    <virtualType name="Magento\Framework\Reflection\ExtensionAttributesProcessorPermissionChecked" type="Magento\Framework\Reflection\ExtensionAttributesProcessor">
+        <arguments>
+            <argument name="isPermissionChecked" xsi:type="boolean">true</argument>
+            <argument name="dataObjectProcessor" xsi:type="object">Magento\Framework\Reflection\DataObjectProcessor\Proxy</argument>
+        </arguments>
+    </virtualType>
+    <virtualType name="Magento\Framework\Reflection\DataObjectProcessorPermissionChecked" type="Magento\Framework\Reflection\DataObjectProcessor">
+        <arguments>
+            <argument name="extensionAttributesProcessor" xsi:type="object">Magento\Framework\Reflection\ExtensionAttributesProcessorPermissionChecked</argument>
+            <argument name="customAttributesProcessor" xsi:type="object">Magento\Framework\Reflection\CustomAttributesProcessor\Proxy</argument>
+        </arguments>
+    </virtualType>
+
+    <type name="Magento\Framework\Webapi\ServiceOutputProcessor">
+        <arguments>
+            <argument name="dataObjectProcessor" xsi:type="object">Magento\Framework\Reflection\DataObjectProcessorPermissionChecked</argument>
+        </arguments>
+    </type>
+    <!-- End of configuration to check that permissions are checked on fields -->
 </config>
diff --git a/app/code/Magento/Webapi/etc/webapi_soap/di.xml b/app/code/Magento/Webapi/etc/webapi_soap/di.xml
index 6d5607c49c18dc46d9e6d9cbc429bc11f4a26467..c8cabfba0ac2529cb3365da99ae129086bee75fe 100644
--- a/app/code/Magento/Webapi/etc/webapi_soap/di.xml
+++ b/app/code/Magento/Webapi/etc/webapi_soap/di.xml
@@ -39,4 +39,26 @@
     <type name="Magento\Framework\Authorization">
         <plugin name="guestAuthorization" type="Magento\Webapi\Model\Plugin\GuestAuthorization" />
     </type>
+
+    <!-- Configuration to check that the permissions are checked on fields -->
+    <virtualType name="Magento\Framework\Reflection\ExtensionAttributesProcessorPermissionChecked" type="Magento\Framework\Reflection\ExtensionAttributesProcessor">
+        <arguments>
+            <argument name="isPermissionChecked" xsi:type="boolean">true</argument>
+            <argument name="dataObjectProcessor" xsi:type="object">Magento\Framework\Reflection\DataObjectProcessor\Proxy</argument>
+        </arguments>
+    </virtualType>
+    <virtualType name="Magento\Framework\Reflection\DataObjectProcessorPermissionChecked" type="Magento\Framework\Reflection\DataObjectProcessor">
+        <arguments>
+            <argument name="extensionAttributesProcessor" xsi:type="object">Magento\Framework\Reflection\ExtensionAttributesProcessorPermissionChecked</argument>
+            <argument name="customAttributesProcessor" xsi:type="object">Magento\Framework\Reflection\CustomAttributesProcessor\Proxy</argument>
+        </arguments>
+    </virtualType>
+
+    <type name="Magento\Webapi\Controller\Soap\Request\Handler">
+        <arguments>
+            <argument name="dataObjectProcessor" xsi:type="object">Magento\Framework\Reflection\DataObjectProcessorPermissionChecked</argument>
+        </arguments>
+    </type>
+    <!-- End of configuration to check that permissions are checked on fields -->
+
 </config>
diff --git a/app/code/Magento/Weee/Model/Observer.php b/app/code/Magento/Weee/Model/Observer.php
index daca840e903b7e2e8c0f11390a84c259a66ff837..08831d28845bc7fb62e842af1178310da6208160 100644
--- a/app/code/Magento/Weee/Model/Observer.php
+++ b/app/code/Magento/Weee/Model/Observer.php
@@ -194,4 +194,37 @@ class Observer extends \Magento\Framework\Model\AbstractModel
         $response->setTypes($types);
         return $this;
     }
+
+    /**
+     * Modify the options config for the front end to resemble the weee final price
+     *
+     * @param   \Magento\Framework\Event\Observer $observer
+     * @return  $this
+     */
+    public function getPriceConfiguration(\Magento\Framework\Event\Observer $observer)
+    {
+        if ($this->_weeeData->isEnabled()) {
+            $priceConfigObj=$observer->getData('configObj');
+            $priceConfig=$priceConfigObj->getConfig();
+            if (is_array($priceConfig)) {
+                foreach ($priceConfig as $keyConfigs => $configs) {
+                    if (is_array($configs)) {
+                        if (array_key_exists('prices', $configs)) {
+                            $priceConfig[$keyConfigs]['prices']['weeePrice'] = [
+                                'amount' => $configs['prices']['finalPrice']['amount'],
+                            ];
+                        } else {
+                            foreach ($configs as $keyConfig => $config) {
+                                $priceConfig[$keyConfigs][$keyConfig]['prices']['weeePrice'] = [
+                                    'amount' => $config['prices']['finalPrice']['amount'],
+                                ];
+                            }
+                        }
+                    }
+                }
+            }
+            $priceConfigObj->setConfig($priceConfig);
+        }
+        return $this;
+    }
 }
diff --git a/app/code/Magento/Weee/Pricing/Render/Adjustment.php b/app/code/Magento/Weee/Pricing/Render/Adjustment.php
index 2272c719cb94c6b6196e023f0540071693975efb..f13c044532f0514e0c230b8f51ae88b045d060b1 100644
--- a/app/code/Magento/Weee/Pricing/Render/Adjustment.php
+++ b/app/code/Magento/Weee/Pricing/Render/Adjustment.php
@@ -61,6 +61,14 @@ class Adjustment extends AbstractAdjustment
         return $this->toHtml();
     }
 
+    /**
+     * @return float
+     */
+    public function getRawFinalAmount()
+    {
+        return $this->finalAmount;
+    }
+
     /**
      * Obtain adjustment code
      *
diff --git a/app/code/Magento/Weee/Test/Unit/Model/ObserverTest.php b/app/code/Magento/Weee/Test/Unit/Model/ObserverTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..63a13abb53622e5f93590a1586d695fb17e18707
--- /dev/null
+++ b/app/code/Magento/Weee/Test/Unit/Model/ObserverTest.php
@@ -0,0 +1,80 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+/**
+ * Test class for \Magento\Weee\Model\Observer
+ */
+namespace Magento\Weee\Test\Unit\Model;
+
+use \Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+
+class ObserverTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * Tests the methods that rely on the ScopeConfigInterface object to provide their return values
+     *
+     */
+    public function testGetPriceConfiguration()
+    {
+        $testArray=[
+            [
+                [
+                    'prices' =>
+                        [
+                            'finalPrice' => [
+                                    'amount' => 31.50,
+                            ],
+                        ],
+                ],
+                [
+                    'prices' =>
+                        [
+                            'finalPrice' =>[
+                                'amount' => 31.50,
+                            ],
+                        ],
+                ],
+            ],
+        ];
+
+        $configObj = new \Magento\Framework\Object(
+            [
+                'config' => $testArray,
+            ]
+        );
+
+        $testArrayWithWeee=$testArray;
+        $testArrayWithWeee[0][0]['prices']['weeePrice']= [
+            'amount' => $testArray[0][0]['prices']['finalPrice']['amount'],
+        ];
+        $testArrayWithWeee[0][1]['prices']['weeePrice']= [
+            'amount' => $testArray[0][1]['prices']['finalPrice']['amount'],
+        ];
+
+        $weeHelper=$this->getMock('Magento\Weee\Helper\Data', [], [], '', false);
+        $weeHelper->expects($this->any())
+            ->method('isEnabled')
+            ->will($this->returnValue(true));
+
+        $observerObject=$this->getMock('Magento\Framework\Event\Observer', [], [], '', false);
+
+        $observerObject->expects($this->any())
+            ->method('getData')
+            ->with('configObj')
+            ->will($this->returnValue($configObj));
+
+         $objectManager = new ObjectManager($this);
+         $weeeObserverObject = $objectManager->getObject(
+             'Magento\Weee\Model\Observer',
+             [
+                 'weeeData' => $weeHelper,
+             ]
+         );
+         $weeeObserverObject->getPriceConfiguration($observerObject);
+
+         $this->assertEquals($testArrayWithWeee, $configObj->getData('config'));
+    }
+}
diff --git a/app/code/Magento/Weee/composer.json b/app/code/Magento/Weee/composer.json
index 9b11852f84fd425b09a62737597c797ddcdd31d8..ba4b15374bad4320414343956952ec2ac5fd3000 100644
--- a/app/code/Magento/Weee/composer.json
+++ b/app/code/Magento/Weee/composer.json
@@ -3,20 +3,20 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/module-tax": "0.74.0-beta6",
-        "magento/module-sales": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-directory": "0.74.0-beta6",
-        "magento/module-eav": "0.74.0-beta6",
-        "magento/module-customer": "0.74.0-beta6",
-        "magento/module-quote": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/module-tax": "0.74.0-beta7",
+        "magento/module-sales": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-directory": "0.74.0-beta7",
+        "magento/module-eav": "0.74.0-beta7",
+        "magento/module-customer": "0.74.0-beta7",
+        "magento/module-quote": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Weee/etc/events.xml b/app/code/Magento/Weee/etc/events.xml
index b6ef0f804b1fd72258baff580d5257b90dd1a31e..f4300f38b2369817d96c1902c29c57d378676f17 100644
--- a/app/code/Magento/Weee/etc/events.xml
+++ b/app/code/Magento/Weee/etc/events.xml
@@ -9,4 +9,7 @@
     <event name="catalog_entity_attribute_save_before">
         <observer name="weee" instance="Magento\Weee\Model\Observer" method="assignBackendModelToAttribute" shared="false" />
     </event>
+    <event name="catalog_product_option_price_configuration_after">
+        <observer name="weee" instance="Magento\Weee\Model\Observer" method="getPriceConfiguration" shared="false" />
+    </event>
 </config>
diff --git a/app/code/Magento/Weee/view/base/templates/pricing/adjustment.phtml b/app/code/Magento/Weee/view/base/templates/pricing/adjustment.phtml
index 86267dea51a757c481bff1d110c6ce121cd41a5e..f8a77699ff4d9356fa99cf9eed5925efbc1b3a3d 100644
--- a/app/code/Magento/Weee/view/base/templates/pricing/adjustment.phtml
+++ b/app/code/Magento/Weee/view/base/templates/pricing/adjustment.phtml
@@ -28,5 +28,7 @@ $closeBrace = ')';
               data-label="<?php echo $block->renderWeeeTaxAttributeName($weeeTaxAttribute); ?>"><?php echo $block->renderWeeeTaxAttribute($weeeTaxAttribute); ?></span>
     <?php endforeach; ?>
     <span class="price-final_price"
+          data-price-type="weeePrice"
+          data-price-amount="<?php echo $block->getRawFinalAmount(); ?>"
           data-label="<?php echo __('Final Price'); ?>"><?php echo $block->getFinalAmount(); ?></span>
 <?php endif; ?>
diff --git a/app/code/Magento/Widget/composer.json b/app/code/Magento/Widget/composer.json
index e1ebbafa7d489f3a823f28fee6e691289851c00b..3cf33ee5654bfca968013901005b5e9157b0abcc 100644
--- a/app/code/Magento/Widget/composer.json
+++ b/app/code/Magento/Widget/composer.json
@@ -3,17 +3,17 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-cms": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/module-theme": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
-        "magento/module-variable": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-cms": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/module-theme": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
+        "magento/module-variable": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Wishlist/Block/Adminhtml/WishlistTab.php b/app/code/Magento/Wishlist/Block/Adminhtml/WishlistTab.php
index 2f393bf6d2c40e0d1e80974d5854187c8bd994df..6a6d83a1bdabef4d2d3f7d7c47b50a9c157b574a 100644
--- a/app/code/Magento/Wishlist/Block/Adminhtml/WishlistTab.php
+++ b/app/code/Magento/Wishlist/Block/Adminhtml/WishlistTab.php
@@ -5,17 +5,16 @@
  */
 namespace Magento\Wishlist\Block\Adminhtml;
 
-use Magento\Backend\Block\Template\Context;
-use Magento\Customer\Controller\RegistryConstants;
 use Magento\Framework\Registry;
+use Magento\Backend\Block\Template\Context;
 use Magento\Ui\Component\Layout\Tabs\TabWrapper;
+use Magento\Ui\Component\Layout\Tabs\TabInterface;
+use Magento\Customer\Controller\RegistryConstants;
 
 /**
  * Class WishlistTab
- *
- * @package Magento\Wishlist\Block\Adminhtml
  */
-class WishlistTab extends TabWrapper
+class WishlistTab extends TabWrapper implements TabInterface
 {
     /**
      * Core registry
diff --git a/app/code/Magento/Wishlist/Controller/Index/Add.php b/app/code/Magento/Wishlist/Controller/Index/Add.php
index 5adebd054bbefa21b0b84c0147be8988fd6a0ad9..3f307ad116dd84ad63d0befb0adde4a4919654a7 100755
--- a/app/code/Magento/Wishlist/Controller/Index/Add.php
+++ b/app/code/Magento/Wishlist/Controller/Index/Add.php
@@ -1,6 +1,5 @@
 <?php
 /**
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
@@ -11,6 +10,7 @@ use Magento\Framework\App\Action;
 use Magento\Framework\Exception\NotFoundException;
 use Magento\Framework\Exception\NoSuchEntityException;
 use Magento\Wishlist\Controller\IndexInterface;
+use Magento\Framework\Controller\ResultFactory;
 
 class Add extends Action\Action implements IndexInterface
 {
@@ -50,7 +50,7 @@ class Add extends Action\Action implements IndexInterface
     /**
      * Adding new item
      *
-     * @return void
+     * @return \Magento\Framework\Controller\Result\Redirect
      * @throws NotFoundException
      * @SuppressWarnings(PHPMD.CyclomaticComplexity)
      * @SuppressWarnings(PHPMD.NPathComplexity)
@@ -73,10 +73,11 @@ class Add extends Action\Action implements IndexInterface
         }
 
         $productId = isset($requestParams['product']) ? (int)$requestParams['product'] : null;
-
+        /** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */
+        $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
         if (!$productId) {
-            $this->_redirect('*/');
-            return;
+            $resultRedirect->setPath('*/');
+            return $resultRedirect;
         }
 
         try {
@@ -87,8 +88,8 @@ class Add extends Action\Action implements IndexInterface
 
         if (!$product || !$product->isVisibleInCatalog()) {
             $this->messageManager->addError(__('We can\'t specify a product.'));
-            $this->_redirect('*/');
-            return;
+            $resultRedirect->setPath('*/');
+            return $resultRedirect;
         }
 
         try {
@@ -112,9 +113,7 @@ class Add extends Action\Action implements IndexInterface
                 $referer = $this->_redirect->getRefererUrl();
             }
 
-
-            /** @var $helper \Magento\Wishlist\Helper\Data */
-            $helper = $this->_objectManager->get('Magento\Wishlist\Helper\Data')->calculate();
+            $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()),
@@ -130,6 +129,7 @@ class Add extends Action\Action implements IndexInterface
             $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
 
-        $this->_redirect('*', ['wishlist_id' => $wishlist->getId()]);
+        $resultRedirect->setPath('*', ['wishlist_id' => $wishlist->getId()]);
+        return $resultRedirect;
     }
 }
diff --git a/app/code/Magento/Wishlist/Controller/Index/Allcart.php b/app/code/Magento/Wishlist/Controller/Index/Allcart.php
index fa7720947034110bf0d80155aa23b7d08960498d..7cf5a187a5687bace697d03101e9ad7e78c8b8c3 100644
--- a/app/code/Magento/Wishlist/Controller/Index/Allcart.php
+++ b/app/code/Magento/Wishlist/Controller/Index/Allcart.php
@@ -1,6 +1,5 @@
 <?php
 /**
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
@@ -12,6 +11,7 @@ use Magento\Framework\App\Action\Context;
 use Magento\Wishlist\Controller\IndexInterface;
 use Magento\Wishlist\Controller\WishlistProviderInterface;
 use Magento\Wishlist\Model\ItemCarrier;
+use Magento\Framework\Controller\ResultFactory;
 
 class Allcart extends Action\Action implements IndexInterface
 {
@@ -51,21 +51,26 @@ class Allcart extends Action\Action implements IndexInterface
     /**
      * Add all items from wishlist to shopping cart
      *
-     * @return void
+     * @return \Magento\Framework\Controller\ResultInterface
      */
     public function execute()
     {
+        /** @var \Magento\Framework\Controller\Result\Forward $resultForward */
+        $resultForward = $this->resultFactory->create(ResultFactory::TYPE_FORWARD);
         if (!$this->formKeyValidator->validate($this->getRequest())) {
-            $this->_forward('noroute');
-            return;
+            $resultForward->forward('noroute');
+            return $resultForward;
         }
 
         $wishlist = $this->wishlistProvider->getWishlist();
         if (!$wishlist) {
-            $this->_forward('noroute');
-            return;
+            $resultForward->forward('noroute');
+            return $resultForward;
         }
+        /** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */
+        $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
         $redirectUrl = $this->itemCarrier->moveAllToCart($wishlist, $this->getRequest()->getParam('qty'));
-        $this->getResponse()->setRedirect($redirectUrl);
+        $resultRedirect->setUrl($redirectUrl);
+        return $resultRedirect;
     }
 }
diff --git a/app/code/Magento/Wishlist/Controller/Index/Cart.php b/app/code/Magento/Wishlist/Controller/Index/Cart.php
index 61a80f8ca58ee312f0bbf5d1572b86c15395b383..5274e565c1b029777fdc7d6ec9d8753f5e7d64dc 100644
--- a/app/code/Magento/Wishlist/Controller/Index/Cart.php
+++ b/app/code/Magento/Wishlist/Controller/Index/Cart.php
@@ -1,15 +1,14 @@
 <?php
 /**
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
 namespace Magento\Wishlist\Controller\Index;
 
 use Magento\Framework\App\Action;
-use Magento\Framework\App\ResponseInterface;
 use Magento\Wishlist\Controller\IndexInterface;
 use Magento\Catalog\Model\Product\Exception as ProductException;
+use Magento\Framework\Controller\ResultFactory;
 
 /**
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
@@ -41,11 +40,6 @@ class Cart extends Action\Action implements IndexInterface
      */
     protected $cartHelper;
 
-    /**
-     * @var \Magento\Framework\Json\Helper\Data
-     */
-    protected $jsonHelper;
-
     /**
      * @var \Magento\Wishlist\Model\Item\OptionFactory
      */
@@ -77,8 +71,6 @@ class Cart extends Action\Action implements IndexInterface
      * @param \Magento\Framework\Escaper $escaper
      * @param \Magento\Wishlist\Helper\Data $helper
      * @param \Magento\Checkout\Helper\Cart $cartHelper
-     * @param \Magento\Framework\Json\Helper\Data $jsonHelper
-     *
      * @SuppressWarnings(PHPMD.ExcessiveParameterList)
      */
     public function __construct(
@@ -91,8 +83,7 @@ class Cart extends Action\Action implements IndexInterface
         \Magento\Catalog\Helper\Product $productHelper,
         \Magento\Framework\Escaper $escaper,
         \Magento\Wishlist\Helper\Data $helper,
-        \Magento\Checkout\Helper\Cart $cartHelper,
-        \Magento\Framework\Json\Helper\Data $jsonHelper
+        \Magento\Checkout\Helper\Cart $cartHelper
     ) {
         $this->wishlistProvider = $wishlistProvider;
         $this->quantityProcessor = $quantityProcessor;
@@ -103,7 +94,6 @@ class Cart extends Action\Action implements IndexInterface
         $this->escaper = $escaper;
         $this->helper = $helper;
         $this->cartHelper = $cartHelper;
-        $this->jsonHelper = $jsonHelper;
         parent::__construct($context);
     }
 
@@ -113,22 +103,25 @@ class Cart extends Action\Action implements IndexInterface
      * If Product has required options - item removed from wishlist and redirect
      * to product view page with message about needed defined required options
      *
-     * @return ResponseInterface
+     * @return \Magento\Framework\Controller\ResultInterface
      * @SuppressWarnings(PHPMD.CyclomaticComplexity)
      * @SuppressWarnings(PHPMD.NPathComplexity)
      */
     public function execute()
     {
         $itemId = (int)$this->getRequest()->getParam('item');
-
+        /** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */
+        $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
         /* @var $item \Magento\Wishlist\Model\Item */
         $item = $this->itemFactory->create()->load($itemId);
         if (!$item->getId()) {
-            return $this->_redirect('*/*');
+            $resultRedirect->setPath('*/*');
+            return $resultRedirect;
         }
         $wishlist = $this->wishlistProvider->getWishlist($item->getWishlistId());
         if (!$wishlist) {
-            return $this->_redirect('*/*');
+            $resultRedirect->setPath('*/*');
+            return $resultRedirect;
         }
 
         // Set qty
@@ -197,12 +190,13 @@ class Cart extends Action\Action implements IndexInterface
         $this->helper->calculate();
 
         if ($this->getRequest()->isAjax()) {
-            $this->getResponse()->representJson(
-                $this->jsonHelper->jsonEncode(['backUrl' => $redirectUrl])
-            );
-            return;
+            /** @var \Magento\Framework\Controller\Result\Json $resultJson */
+            $resultJson = $this->resultFactory->create(ResultFactory::TYPE_JSON);
+            $resultJson->setData(['backUrl' => $redirectUrl]);
+            return $resultJson;
         }
-
-        return $this->getResponse()->setRedirect($redirectUrl);
+        
+        $resultRedirect->setUrl($redirectUrl);
+        return $resultRedirect;
     }
 }
diff --git a/app/code/Magento/Wishlist/Controller/Index/Configure.php b/app/code/Magento/Wishlist/Controller/Index/Configure.php
index 8172c895ed70e361cdeff01b31484bd69917a396..37522cd4cd0dac0bf1719106db853dbba4190744 100644
--- a/app/code/Magento/Wishlist/Controller/Index/Configure.php
+++ b/app/code/Magento/Wishlist/Controller/Index/Configure.php
@@ -1,6 +1,5 @@
 <?php
 /**
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
@@ -9,6 +8,7 @@ namespace Magento\Wishlist\Controller\Index;
 use Magento\Framework\App\Action;
 use Magento\Framework\Exception\NotFoundException;
 use Magento\Wishlist\Controller\IndexInterface;
+use Magento\Framework\Controller\ResultFactory;
 
 class Configure extends Action\Action implements IndexInterface
 {
@@ -50,12 +50,14 @@ class Configure extends Action\Action implements IndexInterface
     /**
      * Action to reconfigure wishlist item
      *
-     * @return void
+     * @return \Magento\Framework\Controller\ResultInterface
      * @throws NotFoundException
      */
     public function execute()
     {
         $id = (int)$this->getRequest()->getParam('id');
+        /** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */
+        $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
         try {
             /* @var $item \Magento\Wishlist\Model\Item */
             $item = $this->_objectManager->create('Magento\Wishlist\Model\Item');
@@ -83,7 +85,7 @@ class Configure extends Action\Action implements IndexInterface
             }
             $params->setBuyRequest($buyRequest);
             /** @var \Magento\Framework\View\Result\Page $resultPage */
-            $resultPage = $this->resultPageFactory->create();
+            $resultPage = $this->resultFactory->create(ResultFactory::TYPE_PAGE);
             $this->_objectManager->get(
                 'Magento\Catalog\Helper\Product\View'
             )->prepareAndRender(
@@ -96,13 +98,13 @@ class Configure extends Action\Action implements IndexInterface
             return $resultPage;
         } catch (\Magento\Framework\Exception\LocalizedException $e) {
             $this->messageManager->addError($e->getMessage());
-            $this->_redirect('*');
-            return;
+            $resultRedirect->setPath('*');
+            return $resultRedirect;
         } catch (\Exception $e) {
             $this->messageManager->addError(__('We can\'t configure the product.'));
             $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
-            $this->_redirect('*');
-            return;
+            $resultRedirect->setPath('*');
+            return $resultRedirect;
         }
     }
 }
diff --git a/app/code/Magento/Wishlist/Controller/Index/DownloadCustomOption.php b/app/code/Magento/Wishlist/Controller/Index/DownloadCustomOption.php
index 3c26bf8e64db6f7007b465927d10622f2e5a3816..1edd5e4426ee0343e25a9ab270674e72c74a4b79 100644
--- a/app/code/Magento/Wishlist/Controller/Index/DownloadCustomOption.php
+++ b/app/code/Magento/Wishlist/Controller/Index/DownloadCustomOption.php
@@ -1,6 +1,5 @@
 <?php
 /**
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
@@ -9,6 +8,7 @@ namespace Magento\Wishlist\Controller\Index;
 use Magento\Framework\App\Action;
 use Magento\Framework\App\Filesystem\DirectoryList;
 use Magento\Wishlist\Controller\IndexInterface;
+use Magento\Framework\Controller\ResultFactory;
 
 class DownloadCustomOption extends Action\Action implements IndexInterface
 {
@@ -32,7 +32,7 @@ class DownloadCustomOption extends Action\Action implements IndexInterface
     /**
      * Custom options download action
      *
-     * @return void
+     * @return \Magento\Framework\Controller\Result\Forward
      * @SuppressWarnings(PHPMD.CyclomaticComplexity)
      * @SuppressWarnings(PHPMD.ExitExpression)
      */
@@ -43,9 +43,11 @@ class DownloadCustomOption extends Action\Action implements IndexInterface
         )->load(
             $this->getRequest()->getParam('id')
         );
-
+        /** @var \Magento\Framework\Controller\Result\Forward $resultForward */
+        $resultForward = $this->resultFactory->create(ResultFactory::TYPE_FORWARD);
         if (!$option->getId()) {
-            return $this->_forward('noroute');
+            $resultForward->forward('noroute');
+            return $resultForward;
         }
 
         $optionId = null;
@@ -56,7 +58,8 @@ class DownloadCustomOption extends Action\Action implements IndexInterface
                 $option->getCode()
             );
             if ((int)$optionId != $optionId) {
-                return $this->_forward('noroute');
+                $resultForward->forward('noroute');
+                return $resultForward;
             }
         }
         $productOption = $this->_objectManager->create('Magento\Catalog\Model\Product\Option')->load($optionId);
@@ -66,7 +69,8 @@ class DownloadCustomOption extends Action\Action implements IndexInterface
             $productOption->getProductId() != $option->getProductId() ||
             $productOption->getType() != 'file'
         ) {
-            return $this->_forward('noroute');
+            $resultForward->forward('noroute');
+            return $resultForward;
         }
 
         try {
@@ -81,8 +85,8 @@ class DownloadCustomOption extends Action\Action implements IndexInterface
                 );
             }
         } catch (\Exception $e) {
-            $this->_forward('noroute');
+            $resultForward->forward('noroute');
+            return $resultForward;
         }
-        exit(0);
     }
 }
diff --git a/app/code/Magento/Wishlist/Controller/Index/Fromcart.php b/app/code/Magento/Wishlist/Controller/Index/Fromcart.php
index 085cf426a0a37cacae5decf0bfa6e020e229b6fb..03c1db81044f7b1be83ea1d319a4614538f9395f 100755
--- a/app/code/Magento/Wishlist/Controller/Index/Fromcart.php
+++ b/app/code/Magento/Wishlist/Controller/Index/Fromcart.php
@@ -1,6 +1,5 @@
 <?php
 /**
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
@@ -9,6 +8,7 @@ namespace Magento\Wishlist\Controller\Index;
 use Magento\Framework\App\Action;
 use Magento\Framework\Exception\NotFoundException;
 use Magento\Wishlist\Controller\IndexInterface;
+use Magento\Framework\Controller\ResultFactory;
 
 class Fromcart extends Action\Action implements IndexInterface
 {
@@ -82,7 +82,8 @@ class Fromcart extends Action\Action implements IndexInterface
      */
     public function getDefaultResult()
     {
-        $resultRedirect = $this->resultRedirectFactory->create();
+        /** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */
+        $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
         return $resultRedirect->setUrl($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
index 9cb4bbe9fcdb089edab3d242f6a648b128c55890..53566774d2400ee6dd73f7468bd4fb1de3d10c49 100644
--- a/app/code/Magento/Wishlist/Controller/Index/Index.php
+++ b/app/code/Magento/Wishlist/Controller/Index/Index.php
@@ -1,6 +1,5 @@
 <?php
 /**
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
@@ -9,6 +8,7 @@ namespace Magento\Wishlist\Controller\Index;
 use Magento\Framework\App\Action;
 use Magento\Framework\Exception\NotFoundException;
 use Magento\Wishlist\Controller\IndexInterface;
+use Magento\Framework\Controller\ResultFactory;
 
 class Index extends Action\Action implements IndexInterface
 {
@@ -32,7 +32,7 @@ class Index extends Action\Action implements IndexInterface
     /**
      * Display customer wishlist
      *
-     * @return void
+     * @return \Magento\Framework\View\Result\Page
      * @throws NotFoundException
      */
     public function execute()
@@ -40,8 +40,9 @@ class Index extends Action\Action implements IndexInterface
         if (!$this->wishlistProvider->getWishlist()) {
             throw new NotFoundException(__('Page not found.'));
         }
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->initMessages();
-        $this->_view->renderLayout();
+        /** @var \Magento\Framework\View\Result\Page resultPage */
+        $resultPage = $this->resultFactory->create(ResultFactory::TYPE_PAGE);
+        $resultPage->getLayout()->initMessages();
+        return $resultPage;
     }
 }
diff --git a/app/code/Magento/Wishlist/Controller/Index/Remove.php b/app/code/Magento/Wishlist/Controller/Index/Remove.php
index 674d1118a614689e2c25958bb205c3eb5be668ae..6a07bcbc9e03b6634f6c7d08fd7563e1650493ea 100644
--- a/app/code/Magento/Wishlist/Controller/Index/Remove.php
+++ b/app/code/Magento/Wishlist/Controller/Index/Remove.php
@@ -1,6 +1,5 @@
 <?php
 /**
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
@@ -9,6 +8,7 @@ namespace Magento\Wishlist\Controller\Index;
 use Magento\Framework\App\Action;
 use Magento\Framework\Exception\NotFoundException;
 use Magento\Wishlist\Controller\IndexInterface;
+use Magento\Framework\Controller\ResultFactory;
 
 class Remove extends Action\Action implements IndexInterface
 {
@@ -32,7 +32,7 @@ class Remove extends Action\Action implements IndexInterface
     /**
      * Remove item
      *
-     * @return void
+     * @return \Magento\Framework\Controller\Result\Redirect
      * @throws NotFoundException
      */
     public function execute()
@@ -69,6 +69,9 @@ class Remove extends Action\Action implements IndexInterface
         } else {
             $redirectUrl = $this->_redirect->getRedirectUrl($this->_url->getUrl('*/*'));
         }
-        $this->getResponse()->setRedirect($redirectUrl);
+        /** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */
+        $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
+        $resultRedirect->setUrl($redirectUrl);
+        return $resultRedirect;
     }
 }
diff --git a/app/code/Magento/Wishlist/Controller/Index/Send.php b/app/code/Magento/Wishlist/Controller/Index/Send.php
index 6a54e1b7bf9f0ba2da61da6f0976f40f0ab81b9a..591da81b0aab9f36ebcd3654bf5290fa91b11242 100644
--- a/app/code/Magento/Wishlist/Controller/Index/Send.php
+++ b/app/code/Magento/Wishlist/Controller/Index/Send.php
@@ -8,8 +8,9 @@ namespace Magento\Wishlist\Controller\Index;
 
 use Magento\Framework\App\Action;
 use Magento\Framework\Exception\NotFoundException;
-use Magento\Framework\App\ResponseInterface;
 use Magento\Wishlist\Controller\IndexInterface;
+use Magento\Framework\Controller\ResultFactory;
+use Magento\Framework\View\Result\Layout as ResultLayout;
 
 /**
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
@@ -84,7 +85,7 @@ class Send extends Action\Action implements IndexInterface
     /**
      * Share wishlist
      *
-     * @return ResponseInterface|void
+     * @return \Magento\Framework\Controller\Result\Redirect
      * @throws NotFoundException
      * @SuppressWarnings(PHPMD.CyclomaticComplexity)
      * @SuppressWarnings(PHPMD.NPathComplexity)
@@ -92,8 +93,11 @@ class Send extends Action\Action implements IndexInterface
      */
     public function execute()
     {
+        /** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */
+        $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
         if (!$this->_formKeyValidator->validate($this->getRequest())) {
-            return $this->_redirect('*/*/');
+            $resultRedirect->setPath('*/*/');
+            return $resultRedirect;
         }
 
         $wishlist = $this->wishlistProvider->getWishlist();
@@ -136,11 +140,12 @@ class Send extends Action\Action implements IndexInterface
             )->setSharingForm(
                 $this->getRequest()->getPostValue()
             );
-            $this->_redirect('*/*/share');
-            return;
+            $resultRedirect->setPath('*/*/share');
+            return $resultRedirect;
         }
-
-        $this->addLayoutHandles();
+        /** @var \Magento\Framework\View\Result\Layout $resultLayout */
+        $resultLayout = $this->resultFactory->create(ResultFactory::TYPE_LAYOUT);
+        $this->addLayoutHandles($resultLayout);
         $this->inlineTranslation->suspend();
 
         $sent = 0;
@@ -149,7 +154,7 @@ class Send extends Action\Action implements IndexInterface
             $customer = $this->_customerSession->getCustomerDataObject();
             $customerName = $this->_customerHelperView->getCustomerName($customer);
 
-            $message .= $this->getRssLink($wishlist->getId());
+            $message .= $this->getRssLink($wishlist->getId(), $resultLayout);
             $emails = array_unique($emails);
             $sharingCode = $wishlist->getSharingCode();
 
@@ -172,7 +177,7 @@ class Send extends Action\Action implements IndexInterface
                             'customer' => $customer,
                             'customerName' => $customerName,
                             'salable' => $wishlist->isSalable() ? 'yes' : '',
-                            'items' => $this->getWishlistItems(),
+                            'items' => $this->getWishlistItems($resultLayout),
                             'addAllLink' => $this->_url->getUrl('*/shared/allcart', ['code' => $sharingCode]),
                             'viewOnSiteLink' => $this->_url->getUrl('*/shared/index', ['code' => $sharingCode]),
                             'message' => $message,
@@ -203,7 +208,8 @@ class Send extends Action\Action implements IndexInterface
 
             $this->_eventManager->dispatch('wishlist_share', ['wishlist' => $wishlist]);
             $this->messageManager->addSuccess(__('Your wish list has been shared.'));
-            $this->_redirect('*/*', ['wishlist_id' => $wishlist->getId()]);
+            $resultRedirect->setPath('*/*', ['wishlist_id' => $wishlist->getId()]);
+            return $resultRedirect;
         } catch (\Exception $e) {
             $this->inlineTranslation->resume();
             $this->messageManager->addError($e->getMessage());
@@ -212,7 +218,8 @@ class Send extends Action\Action implements IndexInterface
             )->setSharingForm(
                 $this->getRequest()->getPostValue()
             );
-            $this->_redirect('*/*/share');
+            $resultRedirect->setPath('*/*/share');
+            return $resultRedirect;
         }
     }
 
@@ -222,27 +229,28 @@ class Send extends Action\Action implements IndexInterface
      * Add 'wishlist_email_rss' layout handle.
      * Add 'wishlist_email_items' layout handle.
      *
+     * @param \Magento\Framework\View\Result\Layout $resultLayout
      * @return void
      */
-    protected function addLayoutHandles()
+    protected function addLayoutHandles(ResultLayout $resultLayout)
     {
         if ($this->getRequest()->getParam('rss_url')) {
-            $this->_view->getLayout()->getUpdate()->addHandle('wishlist_email_rss');
+            $resultLayout->addHandle('wishlist_email_rss');
         }
-        $this->_view->getLayout()->getUpdate()->addHandle('wishlist_email_items');
-        $this->_view->loadLayoutUpdates();
+        $resultLayout->addHandle('wishlist_email_items');
     }
 
     /**
      * Retrieve RSS link content (html)
      *
      * @param int $wishlistId
+     * @param \Magento\Framework\View\Result\Layout $resultLayout
      * @return mixed
      */
-    protected function getRssLink($wishlistId)
+    protected function getRssLink($wishlistId, ResultLayout $resultLayout)
     {
         if ($this->getRequest()->getParam('rss_url')) {
-            return $this->_view->getLayout()
+            return $resultLayout->getLayout()
                 ->getBlock('wishlist.email.rss')
                 ->setWishlistId($wishlistId)
                 ->toHtml();
@@ -252,11 +260,12 @@ class Send extends Action\Action implements IndexInterface
     /**
      * Retrieve wishlist items content (html)
      *
+     * @param \Magento\Framework\View\Result\Layout $resultLayout
      * @return string
      */
-    protected function getWishlistItems()
+    protected function getWishlistItems(ResultLayout $resultLayout)
     {
-        return $this->_view->getLayout()
+        return $resultLayout->getLayout()
             ->getBlock('wishlist.email.items')
             ->toHtml();
     }
diff --git a/app/code/Magento/Wishlist/Controller/Index/Share.php b/app/code/Magento/Wishlist/Controller/Index/Share.php
index b47a0027f7bdd793ebef983e69aaae1f8861c651..cfc8f8a7f8b2a51cfc3a2e8f120735c4c449ac5f 100644
--- a/app/code/Magento/Wishlist/Controller/Index/Share.php
+++ b/app/code/Magento/Wishlist/Controller/Index/Share.php
@@ -1,6 +1,5 @@
 <?php
 /**
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
@@ -8,18 +7,20 @@ namespace Magento\Wishlist\Controller\Index;
 
 use Magento\Framework\App\Action;
 use Magento\Wishlist\Controller\IndexInterface;
+use Magento\Framework\Controller\ResultFactory;
 
 class Share extends Action\Action implements IndexInterface
 {
     /**
      * Prepare wishlist for share
      *
-     * @return void
+     * @return \Magento\Framework\View\Result\Page
      */
     public function execute()
     {
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->initMessages();
-        $this->_view->renderLayout();
+        /** @var \Magento\Framework\View\Result\Page $resultPage */
+        $resultPage = $this->resultFactory->create(ResultFactory::TYPE_PAGE);
+        $resultPage->getLayout()->initMessages();
+        return $resultPage;
     }
 }
diff --git a/app/code/Magento/Wishlist/Controller/Index/Update.php b/app/code/Magento/Wishlist/Controller/Index/Update.php
index 731a80cd743570abb624ee89bee2fb5a2e5179eb..ab7c5efd3d88aaf958418273106c46d66cf1b0e6 100644
--- a/app/code/Magento/Wishlist/Controller/Index/Update.php
+++ b/app/code/Magento/Wishlist/Controller/Index/Update.php
@@ -1,6 +1,5 @@
 <?php
 /**
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
@@ -8,8 +7,8 @@ namespace Magento\Wishlist\Controller\Index;
 
 use Magento\Framework\App\Action;
 use Magento\Framework\Exception\NotFoundException;
-use Magento\Framework\App\ResponseInterface;
 use Magento\Wishlist\Controller\IndexInterface;
+use Magento\Framework\Controller\ResultFactory;
 
 class Update extends Action\Action implements IndexInterface
 {
@@ -49,15 +48,18 @@ class Update extends Action\Action implements IndexInterface
     /**
      * Update wishlist item comments
      *
-     * @return ResponseInterface|void
+     * @return \Magento\Framework\Controller\Result\Redirect
      * @throws NotFoundException
      * @SuppressWarnings(PHPMD.CyclomaticComplexity)
      * @SuppressWarnings(PHPMD.NPathComplexity)
      */
     public function execute()
     {
+        /** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */
+        $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
         if (!$this->_formKeyValidator->validate($this->getRequest())) {
-            return $this->_redirect('*/*/');
+            $resultRedirect->setPath('*/*/');
+            return $resultRedirect;
         }
         $wishlist = $this->wishlistProvider->getWishlist();
         if (!$wishlist) {
@@ -130,10 +132,11 @@ class Update extends Action\Action implements IndexInterface
             }
 
             if (isset($post['save_and_share'])) {
-                $this->_redirect('*/*/share', ['wishlist_id' => $wishlist->getId()]);
-                return;
+                $resultRedirect->setPath('*/*/share', ['wishlist_id' => $wishlist->getId()]);
+                return $resultRedirect;
             }
         }
-        $this->_redirect('*', ['wishlist_id' => $wishlist->getId()]);
+        $resultRedirect->setPath('*', ['wishlist_id' => $wishlist->getId()]);
+        return $resultRedirect;
     }
 }
diff --git a/app/code/Magento/Wishlist/Controller/Index/UpdateItemOptions.php b/app/code/Magento/Wishlist/Controller/Index/UpdateItemOptions.php
index 483d3793eddc7fb3b0b107a8978e3143a3ca2897..b9dee182873329586d901c6fd32ca9e18116fd95 100644
--- a/app/code/Magento/Wishlist/Controller/Index/UpdateItemOptions.php
+++ b/app/code/Magento/Wishlist/Controller/Index/UpdateItemOptions.php
@@ -1,6 +1,5 @@
 <?php
 /**
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
@@ -10,6 +9,7 @@ use Magento\Catalog\Api\ProductRepositoryInterface;
 use Magento\Framework\App\Action;
 use Magento\Framework\Exception\NoSuchEntityException;
 use Magento\Wishlist\Controller\IndexInterface;
+use Magento\Framework\Controller\ResultFactory;
 
 class UpdateItemOptions extends Action\Action implements IndexInterface
 {
@@ -49,14 +49,16 @@ class UpdateItemOptions extends Action\Action implements IndexInterface
     /**
      * Action to accept new configuration for a wishlist item
      *
-     * @return void
+     * @return \Magento\Framework\Controller\Result\Redirect
      */
     public function execute()
     {
         $productId = (int)$this->getRequest()->getParam('product');
+        /** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */
+        $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
         if (!$productId) {
-            $this->_redirect('*/');
-            return;
+            $resultRedirect->setPath('*/');
+            return $resultRedirect;
         }
 
         try {
@@ -67,8 +69,8 @@ class UpdateItemOptions extends Action\Action implements IndexInterface
 
         if (!$product || !$product->isVisibleInCatalog()) {
             $this->messageManager->addError(__('We can\'t specify a product.'));
-            $this->_redirect('*/');
-            return;
+            $resultRedirect->setPath('*/');
+            return $resultRedirect;
         }
 
         try {
@@ -78,8 +80,8 @@ class UpdateItemOptions extends Action\Action implements IndexInterface
             $item->load($id);
             $wishlist = $this->wishlistProvider->getWishlist($item->getWishlistId());
             if (!$wishlist) {
-                $this->_redirect('*/');
-                return;
+                $resultRedirect->setPath('*/');
+                return $resultRedirect;
             }
 
             $buyRequest = new \Magento\Framework\Object($this->getRequest()->getParams());
@@ -102,6 +104,7 @@ class UpdateItemOptions extends Action\Action implements IndexInterface
             $this->messageManager->addError(__('An error occurred while updating wish list.'));
             $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
-        $this->_redirect('*/*', ['wishlist_id' => $wishlist->getId()]);
+        $resultRedirect->setPath('*/*', ['wishlist_id' => $wishlist->getId()]);
+        return $resultRedirect;
     }
 }
diff --git a/app/code/Magento/Wishlist/Controller/Shared/Allcart.php b/app/code/Magento/Wishlist/Controller/Shared/Allcart.php
index 27dc5d8fd5d94bb56e9060035a136c6d30a6c368..ffb6e34ea96390aedd403549f7294126bcd1b93c 100644
--- a/app/code/Magento/Wishlist/Controller/Shared/Allcart.php
+++ b/app/code/Magento/Wishlist/Controller/Shared/Allcart.php
@@ -1,6 +1,5 @@
 <?php
 /**
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
@@ -8,6 +7,7 @@ namespace Magento\Wishlist\Controller\Shared;
 
 use Magento\Framework\App\Action\Context;
 use Magento\Wishlist\Model\ItemCarrier;
+use Magento\Framework\Controller\ResultFactory;
 
 class Allcart extends \Magento\Framework\App\Action\Action
 {
@@ -39,16 +39,21 @@ class Allcart extends \Magento\Framework\App\Action\Action
     /**
      * Add all items from wishlist to shopping cart
      *
-     * @return void
+     * @return \Magento\Framework\Controller\ResultInterface
      */
     public function execute()
     {
         $wishlist = $this->wishlistProvider->getWishlist();
         if (!$wishlist) {
-            $this->_forward('noroute');
-            return;
+            /** @var \Magento\Framework\Controller\Result\Forward $resultForward */
+            $resultForward = $this->resultFactory->create(ResultFactory::TYPE_FORWARD);
+            $resultForward->forward('noroute');
+            return $resultForward;
         }
         $redirectUrl = $this->itemCarrier->moveAllToCart($wishlist, $this->getRequest()->getParam('qty'));
-        $this->getResponse()->setRedirect($redirectUrl);
+        /** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */
+        $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
+        $resultRedirect->setUrl($redirectUrl);
+        return $resultRedirect;
     }
 }
diff --git a/app/code/Magento/Wishlist/Controller/Shared/Cart.php b/app/code/Magento/Wishlist/Controller/Shared/Cart.php
index b14e996706ec4892296df08cad1b777c1166a41b..5c1efa80aec9ed522b32785b837805a0c05ab120 100644
--- a/app/code/Magento/Wishlist/Controller/Shared/Cart.php
+++ b/app/code/Magento/Wishlist/Controller/Shared/Cart.php
@@ -1,11 +1,12 @@
 <?php
 /**
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
 namespace Magento\Wishlist\Controller\Shared;
 
+use Magento\Framework\Controller\ResultFactory;
+
 class Cart extends \Magento\Framework\App\Action\Action
 {
     /**
@@ -14,7 +15,7 @@ class Cart extends \Magento\Framework\App\Action\Action
      * If Product has required options - redirect
      * to product view page with message about needed defined required options
      *
-     * @return \Magento\Framework\App\Response\Http
+     * @return \Magento\Framework\Controller\Result\Redirect
      */
     public function execute()
     {
@@ -51,7 +52,9 @@ class Cart extends \Magento\Framework\App\Action\Action
         } catch (\Exception $e) {
             $this->messageManager->addException($e, __('Cannot add item to shopping cart'));
         }
-
-        return $this->getResponse()->setRedirect($redirectUrl);
+        /** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */
+        $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
+        $resultRedirect->setUrl($redirectUrl);
+        return $resultRedirect;
     }
 }
diff --git a/app/code/Magento/Wishlist/Controller/Shared/Index.php b/app/code/Magento/Wishlist/Controller/Shared/Index.php
index 39c564d62004792cff56a7c3a6f81e510cb4e3ba..20ccbf1b45bcf38e17a0df3b09849da725a3ec5e 100644
--- a/app/code/Magento/Wishlist/Controller/Shared/Index.php
+++ b/app/code/Magento/Wishlist/Controller/Shared/Index.php
@@ -1,6 +1,5 @@
 <?php
 /**
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
@@ -8,8 +7,9 @@ namespace Magento\Wishlist\Controller\Shared;
 
 use Magento\Framework\App\Action\Action;
 use Magento\Framework\App\Action\Context;
+use Magento\Framework\Controller\ResultFactory;
 
-class Index extends \Magento\Framework\App\Action\Action
+class Index extends Action
 {
     /**
      * Core registry
@@ -49,7 +49,7 @@ class Index extends \Magento\Framework\App\Action\Action
     /**
      * Shared wishlist view page
      *
-     * @return void
+     * @return \Magento\Framework\Controller\ResultInterface
      */
     public function execute()
     {
@@ -57,16 +57,18 @@ class Index extends \Magento\Framework\App\Action\Action
         $customerId = $this->customerSession->getCustomerId();
 
         if ($wishlist && $wishlist->getCustomerId() && $wishlist->getCustomerId() == $customerId) {
-            $this->getResponse()->setRedirect(
+            /** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */
+            $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
+            $resultRedirect->setUrl(
                 $this->_objectManager->get('Magento\Wishlist\Helper\Data')->getListUrl($wishlist->getId())
             );
-            return;
+            return $resultRedirect;
         }
 
         $this->registry->register('shared_wishlist', $wishlist);
-
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->initMessages();
-        $this->_view->renderLayout();
+        /** @var \Magento\Framework\View\Result\Page $resultPage */
+        $resultPage = $this->resultFactory->create(ResultFactory::TYPE_PAGE);
+        $resultPage->getLayout()->initMessages();
+        return $resultPage;
     }
 }
diff --git a/app/code/Magento/Wishlist/Test/Unit/Controller/Index/AddTest.php b/app/code/Magento/Wishlist/Test/Unit/Controller/Index/AddTest.php
index 98fbbc933f8a1da2f837a85079624e6ce180a314..54e91fb5f079aad57ac236a3ee64c9c87f675b4b 100755
--- a/app/code/Magento/Wishlist/Test/Unit/Controller/Index/AddTest.php
+++ b/app/code/Magento/Wishlist/Test/Unit/Controller/Index/AddTest.php
@@ -3,9 +3,10 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-
 namespace Magento\Wishlist\Test\Unit\Controller\Index;
 
+use Magento\Framework\Controller\ResultFactory;
+
 class AddTest extends \PHPUnit_Framework_TestCase
 {
     /**
@@ -33,21 +34,21 @@ class AddTest extends \PHPUnit_Framework_TestCase
      */
     protected $controller;
 
+    /**
+     * @var \Magento\Framework\Controller\ResultFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $resultFactoryMock;
+
+    /**
+     * @var \Magento\Framework\Controller\Result\Redirect|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $resultRedirectMock;
+
     public function setUp()
     {
         $this->context = $this->getMock(
             'Magento\Framework\App\Action\Context',
-            [
-                'getRequest',
-                'getResponse',
-                'getObjectManager',
-                'getEventManager',
-                'getUrl',
-                'getActionFlag',
-                'getRedirect',
-                'getView',
-                'getMessageManager'
-            ],
+            [],
             [],
             '',
             false
@@ -79,6 +80,17 @@ class AddTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
+        $this->resultFactoryMock = $this->getMockBuilder('Magento\Framework\Controller\ResultFactory')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->resultRedirectMock = $this->getMockBuilder('Magento\Framework\Controller\Result\Redirect')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->resultFactoryMock->expects($this->any())
+            ->method('create')
+            ->with(ResultFactory::TYPE_REDIRECT, [])
+            ->willReturn($this->resultRedirectMock);
     }
 
     /**
@@ -128,13 +140,6 @@ class AddTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
-        $redirect = $this->getMock(
-            '\Magento\Store\App\Response\Redirect',
-            null,
-            [],
-            '',
-            false
-        );
         $view = $this->getMock(
             'Magento\Framework\App\View',
             null,
@@ -174,10 +179,6 @@ class AddTest extends \PHPUnit_Framework_TestCase
             ->expects($this->any())
             ->method('getActionFlag')
             ->will($this->returnValue($actionFlag));
-        $this->context
-            ->expects($this->any())
-            ->method('getRedirect')
-            ->will($this->returnValue($redirect));
         $this->context
             ->expects($this->any())
             ->method('getView')
@@ -186,6 +187,9 @@ class AddTest extends \PHPUnit_Framework_TestCase
             ->expects($this->any())
             ->method('getMessageManager')
             ->will($this->returnValue($messageManager));
+        $this->context->expects($this->any())
+            ->method('getResultFactory')
+            ->willReturn($this->resultFactoryMock);
     }
 
     public function configureCustomerSession()
@@ -261,12 +265,10 @@ class AddTest extends \PHPUnit_Framework_TestCase
         $eventManager = $this->getMock('Magento\Framework\Event\Manager', null, [], '', false);
         $url = $this->getMock('Magento\Framework\Url', null, [], '', false);
         $actionFlag = $this->getMock('Magento\Framework\App\ActionFlag', null, [], '', false);
-        $redirect = $this->getMock('\Magento\Store\App\Response\Redirect', ['redirect'], [], '', false);
-        $redirect
-            ->expects($this->once())
-            ->method('redirect')
-            ->with($response, '*/', [])
-            ->will($this->returnValue(null));
+        $this->resultRedirectMock->expects($this->once())
+            ->method('setPath')
+            ->with('*/', [])
+            ->willReturnSelf();
         $view = $this->getMock('Magento\Framework\App\View', null, [], '', false);
         $messageManager = $this->getMock('Magento\Framework\Message\Manager', null, [], '', false);
 
@@ -294,10 +296,6 @@ class AddTest extends \PHPUnit_Framework_TestCase
             ->expects($this->any())
             ->method('getActionFlag')
             ->will($this->returnValue($actionFlag));
-        $this->context
-            ->expects($this->any())
-            ->method('getRedirect')
-            ->will($this->returnValue($redirect));
         $this->context
             ->expects($this->any())
             ->method('getView')
@@ -327,10 +325,13 @@ class AddTest extends \PHPUnit_Framework_TestCase
             ->expects($this->never())
             ->method('setBeforeWishlistUrl')
             ->will($this->returnValue(null));
+        $this->context->expects($this->any())
+            ->method('getResultFactory')
+            ->willReturn($this->resultFactoryMock);
 
         $this->createController();
 
-        $this->controller->execute();
+        $this->assertSame($this->resultRedirectMock, $this->controller->execute());
     }
 
     /**
@@ -344,7 +345,6 @@ class AddTest extends \PHPUnit_Framework_TestCase
             ->method('getWishlist')
             ->will($this->returnValue($wishlist));
 
-
         $request = $this->getMock('Magento\Framework\App\Request\Http', ['getParams'], [], '', false);
         $request
             ->expects($this->once())
@@ -356,12 +356,10 @@ class AddTest extends \PHPUnit_Framework_TestCase
         $eventManager = $this->getMock('Magento\Framework\Event\Manager', null, [], '', false);
         $url = $this->getMock('Magento\Framework\Url', null, [], '', false);
         $actionFlag = $this->getMock('Magento\Framework\App\ActionFlag', null, [], '', false);
-        $redirect = $this->getMock('\Magento\Store\App\Response\Redirect', ['redirect'], [], '', false);
-        $redirect
-            ->expects($this->once())
-            ->method('redirect')
-            ->with($response, '*/', [])
-            ->will($this->returnValue(null));
+        $this->resultRedirectMock->expects($this->once())
+            ->method('setPath')
+            ->with('*/', [])
+            ->willReturnSelf();
         $view = $this->getMock('Magento\Framework\App\View', null, [], '', false);
         $messageManager = $this->getMock('Magento\Framework\Message\Manager', ['addError'], [], '', false);
         $messageManager
@@ -394,10 +392,6 @@ class AddTest extends \PHPUnit_Framework_TestCase
             ->expects($this->any())
             ->method('getActionFlag')
             ->will($this->returnValue($actionFlag));
-        $this->context
-            ->expects($this->any())
-            ->method('getRedirect')
-            ->will($this->returnValue($redirect));
         $this->context
             ->expects($this->any())
             ->method('getView')
@@ -406,6 +400,9 @@ class AddTest extends \PHPUnit_Framework_TestCase
             ->expects($this->any())
             ->method('getMessageManager')
             ->will($this->returnValue($messageManager));
+        $this->context->expects($this->any())
+            ->method('getResultFactory')
+            ->willReturn($this->resultFactoryMock);
 
         $this->customerSession
             ->expects($this->exactly(1))
@@ -430,7 +427,7 @@ class AddTest extends \PHPUnit_Framework_TestCase
 
         $this->createController();
 
-        $this->controller->execute();
+        $this->assertSame($this->resultRedirectMock, $this->controller->execute());
     }
 
     /**
@@ -466,12 +463,10 @@ class AddTest extends \PHPUnit_Framework_TestCase
         $eventManager = $this->getMock('Magento\Framework\Event\Manager', null, [], '', false);
         $url = $this->getMock('Magento\Framework\Url', null, [], '', false);
         $actionFlag = $this->getMock('Magento\Framework\App\ActionFlag', null, [], '', false);
-        $redirect = $this->getMock('\Magento\Store\App\Response\Redirect', ['redirect'], [], '', false);
-        $redirect
-            ->expects($this->once())
-            ->method('redirect')
-            ->with($response, '*', ['wishlist_id' => 2])
-            ->will($this->returnValue(null));
+        $this->resultRedirectMock->expects($this->once())
+            ->method('setPath')
+            ->with('*', ['wishlist_id' => 2])
+            ->willReturnSelf();
 
         $view = $this->getMock('Magento\Framework\App\View', null, [], '', false);
         $messageManager = $this->getMock('Magento\Framework\Message\Manager', ['addError'], [], '', false);
@@ -505,10 +500,6 @@ class AddTest extends \PHPUnit_Framework_TestCase
             ->expects($this->any())
             ->method('getActionFlag')
             ->will($this->returnValue($actionFlag));
-        $this->context
-            ->expects($this->any())
-            ->method('getRedirect')
-            ->will($this->returnValue($redirect));
         $this->context
             ->expects($this->any())
             ->method('getView')
@@ -517,6 +508,9 @@ class AddTest extends \PHPUnit_Framework_TestCase
             ->expects($this->any())
             ->method('getMessageManager')
             ->will($this->returnValue($messageManager));
+        $this->context->expects($this->any())
+            ->method('getResultFactory')
+            ->willReturn($this->resultFactoryMock);
 
         $this->customerSession
             ->expects($this->exactly(1))
@@ -559,7 +553,7 @@ class AddTest extends \PHPUnit_Framework_TestCase
 
         $this->createController();
 
-        $this->controller->execute();
+        $this->assertSame($this->resultRedirectMock, $this->controller->execute());
     }
 
     /**
@@ -683,12 +677,10 @@ class AddTest extends \PHPUnit_Framework_TestCase
 
         $url = $this->getMock('Magento\Framework\Url', null, [], '', false);
         $actionFlag = $this->getMock('Magento\Framework\App\ActionFlag', null, [], '', false);
-        $redirect = $this->getMock('\Magento\Store\App\Response\Redirect', ['redirect'], [], '', false);
-        $redirect
-            ->expects($this->once())
-            ->method('redirect')
-            ->with($response, '*', ['wishlist_id' => 2])
-            ->will($this->returnValue(null));
+        $this->resultRedirectMock->expects($this->once())
+            ->method('setPath')
+            ->with('*', ['wishlist_id' => 2])
+            ->willReturnSelf();
 
         $view = $this->getMock('Magento\Framework\App\View', null, [], '', false);
 
@@ -733,10 +725,6 @@ class AddTest extends \PHPUnit_Framework_TestCase
             ->expects($this->any())
             ->method('getActionFlag')
             ->will($this->returnValue($actionFlag));
-        $this->context
-            ->expects($this->any())
-            ->method('getRedirect')
-            ->will($this->returnValue($redirect));
         $this->context
             ->expects($this->any())
             ->method('getView')
@@ -745,6 +733,9 @@ class AddTest extends \PHPUnit_Framework_TestCase
             ->expects($this->any())
             ->method('getMessageManager')
             ->will($this->returnValue($messageManager));
+        $this->context->expects($this->any())
+            ->method('getResultFactory')
+            ->willReturn($this->resultFactoryMock);
 
         $this->customerSession
             ->expects($this->exactly(1))
@@ -766,6 +757,6 @@ class AddTest extends \PHPUnit_Framework_TestCase
 
         $this->createController();
 
-        $this->controller->execute();
+        $this->assertSame($this->resultRedirectMock, $this->controller->execute());
     }
 }
diff --git a/app/code/Magento/Wishlist/Test/Unit/Controller/Index/AllcartTest.php b/app/code/Magento/Wishlist/Test/Unit/Controller/Index/AllcartTest.php
index b99b18f4b87eaa6f95bc93601e434b2ce8bbc417..8d58bf0be7592847c0f13f568d923ff6aeeceba7 100644
--- a/app/code/Magento/Wishlist/Test/Unit/Controller/Index/AllcartTest.php
+++ b/app/code/Magento/Wishlist/Test/Unit/Controller/Index/AllcartTest.php
@@ -3,9 +3,10 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-
 namespace Magento\Wishlist\Test\Unit\Controller\Index;
 
+use Magento\Framework\Controller\ResultFactory;
+
 class AllcartTest extends \PHPUnit_Framework_TestCase
 {
     /**
@@ -38,6 +39,21 @@ class AllcartTest extends \PHPUnit_Framework_TestCase
      */
     protected $response;
 
+    /**
+     * @var \Magento\Framework\Controller\ResultFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $resultFactoryMock;
+
+    /**
+     * @var \Magento\Framework\Controller\Result\Redirect|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $resultRedirectMock;
+
+    /**
+     * @var \Magento\Framework\Controller\Result\Forward|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $resultForwardMock;
+
     protected function setUp()
     {
         $this->context = $this->getMock('Magento\Framework\App\Action\Context', [], [], '', false);
@@ -46,6 +62,24 @@ class AllcartTest extends \PHPUnit_Framework_TestCase
         $this->formKeyValidator = $this->getMock('Magento\Framework\Data\Form\FormKey\Validator', [], [], '', false);
         $this->request = $this->getMock('Magento\Framework\App\Request\Http', [], [], '', false);
         $this->response = $this->getMock('Magento\Framework\App\Response\Http', [], [], '', false);
+        $this->resultFactoryMock = $this->getMockBuilder('Magento\Framework\Controller\ResultFactory')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->resultRedirectMock = $this->getMockBuilder('Magento\Framework\Controller\Result\Redirect')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->resultForwardMock = $this->getMockBuilder('Magento\Framework\Controller\Result\Forward')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->resultFactoryMock->expects($this->any())
+            ->method('create')
+            ->willReturnMap(
+                [
+                    [ResultFactory::TYPE_REDIRECT, [], $this->resultRedirectMock],
+                    [ResultFactory::TYPE_FORWARD, [], $this->resultForwardMock]
+                ]
+            );
     }
 
     protected function prepareContext()
@@ -94,6 +128,9 @@ class AllcartTest extends \PHPUnit_Framework_TestCase
             ->expects($this->any())
             ->method('getMessageManager')
             ->will($this->returnValue($messageManager));
+        $this->context->expects($this->any())
+            ->method('getResultFactory')
+            ->willReturn($this->resultFactoryMock);
     }
 
     public function getController()
@@ -114,24 +151,13 @@ class AllcartTest extends \PHPUnit_Framework_TestCase
             ->method('validate')
             ->with($this->request)
             ->will($this->returnValue(false));
-
-        $this->request
-            ->expects($this->once())
-            ->method('initForward')
-            ->will($this->returnValue(true));
-        $this->request
-            ->expects($this->once())
-            ->method('setActionName')
+        $this->resultForwardMock->expects($this->once())
+            ->method('forward')
             ->with('noroute')
-            ->will($this->returnValue(true));
-        $this->request
-            ->expects($this->once())
-            ->method('setDispatched')
-            ->with(false)
-            ->will($this->returnValue(true));
+            ->willReturnSelf();
 
         $controller = $this->getController();
-        $controller->execute();
+        $this->assertSame($this->resultForwardMock, $controller->execute());
     }
 
     public function testExecuteWithoutWishlist()
@@ -141,63 +167,43 @@ class AllcartTest extends \PHPUnit_Framework_TestCase
             ->method('validate')
             ->with($this->request)
             ->will($this->returnValue(true));
-
-        $this->request
-            ->expects($this->once())
-            ->method('initForward')
-            ->will($this->returnValue(true));
-        $this->request
-            ->expects($this->once())
-            ->method('setActionName')
-            ->with('noroute')
-            ->will($this->returnValue(true));
-        $this->request
-            ->expects($this->once())
-            ->method('setDispatched')
-            ->with(false)
-            ->will($this->returnValue(true));
-
         $this->wishlistProvider
             ->expects($this->once())
             ->method('getWishlist')
             ->will($this->returnValue(null));
+        $this->resultForwardMock->expects($this->once())
+            ->method('forward')
+            ->with('noroute')
+            ->willReturnSelf();
 
-
-        $this->getController()->execute();
+        $this->assertSame($this->resultForwardMock, $this->getController()->execute());
     }
 
     public function testExecutePassed()
     {
+        $url = 'http://redirect-url.com';
         $wishlist = $this->getMock('Magento\Wishlist\Model\Wishlist', [], [], '', false);
         
-        $this->formKeyValidator
-            ->expects($this->once())
+        $this->formKeyValidator->expects($this->once())
             ->method('validate')
             ->with($this->request)
             ->will($this->returnValue(true));
-
-        $this->request
-            ->expects($this->once())
+        $this->request->expects($this->once())
             ->method('getParam')
             ->with('qty')
             ->will($this->returnValue(2));
-
-        $this->response
-            ->expects($this->once())
-            ->method('setRedirect')
-            ->will($this->returnValue('http://redirect-url.com'));
-
-        $this->wishlistProvider
-            ->expects($this->once())
+        $this->wishlistProvider->expects($this->once())
             ->method('getWishlist')
             ->will($this->returnValue($wishlist));
-        
-        $this->itemCarrier
-            ->expects($this->once())
+        $this->itemCarrier->expects($this->once())
             ->method('moveAllToCart')
             ->with($wishlist, 2)
-            ->will($this->returnValue('http://redirect-url.com'));
+            ->willReturn($url);
+        $this->resultRedirectMock->expects($this->once())
+            ->method('setUrl')
+            ->with($url)
+            ->willReturnSelf();
 
-        $this->getController()->execute();
+        $this->assertSame($this->resultRedirectMock, $this->getController()->execute());
     }
 }
diff --git a/app/code/Magento/Wishlist/Test/Unit/Controller/Index/CartTest.php b/app/code/Magento/Wishlist/Test/Unit/Controller/Index/CartTest.php
index fcfec1f1071a82b28b866e753669733d031422de..c2074246b31fa3f197fe5ed5150551f76954526d 100644
--- a/app/code/Magento/Wishlist/Test/Unit/Controller/Index/CartTest.php
+++ b/app/code/Magento/Wishlist/Test/Unit/Controller/Index/CartTest.php
@@ -3,12 +3,11 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-
 namespace Magento\Wishlist\Test\Unit\Controller\Index;
 
-use \Magento\Wishlist\Controller\Index\Cart;
-
+use Magento\Wishlist\Controller\Index\Cart;
 use Magento\Catalog\Model\Product\Exception as ProductException;
+use Magento\Framework\Controller\ResultFactory;
 
 /**
  * @SuppressWarnings(PHPMD.TooManyFields)
@@ -71,11 +70,6 @@ class CartTest extends \PHPUnit_Framework_TestCase
      */
     protected $requestMock;
 
-    /**
-     * @var \Magento\Framework\App\ResponseInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $responseMock;
-
     /**
      * @var \Magento\Framework\App\Response\RedirectInterface|\PHPUnit_Framework_MockObject_MockObject
      */
@@ -102,9 +96,19 @@ class CartTest extends \PHPUnit_Framework_TestCase
     protected $cartHelperMock;
 
     /**
-     * @var \Magento\Framework\Json\Helper\Data|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\Framework\Controller\ResultFactory|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $jsonHelperMock;
+    protected $resultFactoryMock;
+
+    /**
+     * @var \Magento\Framework\Controller\Result\Redirect|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $resultRedirectMock;
+
+    /**
+     * @var \Magento\Framework\Controller\Result\Json|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $resultJsonMock;
 
     /**
      * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
@@ -152,11 +156,6 @@ class CartTest extends \PHPUnit_Framework_TestCase
             ->setMethods(['getParams', 'getParam', 'isAjax'])
             ->getMockForAbstractClass();
 
-        $this->responseMock = $this->getMockBuilder('Magento\Framework\App\ResponseInterface')
-            ->disableOriginalConstructor()
-            ->setMethods(['setRedirect', 'representJson'])
-            ->getMockForAbstractClass();
-
         $this->redirectMock = $this->getMockBuilder('Magento\Framework\App\Response\RedirectInterface')
             ->disableOriginalConstructor()
             ->getMockForAbstractClass();
@@ -174,6 +173,18 @@ class CartTest extends \PHPUnit_Framework_TestCase
             ->disableOriginalConstructor()
             ->setMethods(['getUrl'])
             ->getMockForAbstractClass();
+        $this->cartHelperMock = $this->getMockBuilder('Magento\Checkout\Helper\Cart')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->resultFactoryMock = $this->getMockBuilder('Magento\Framework\Controller\ResultFactory')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->resultRedirectMock = $this->getMockBuilder('Magento\Framework\Controller\Result\Redirect')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->resultJsonMock = $this->getMockBuilder('Magento\Framework\Controller\Result\Json')
+            ->disableOriginalConstructor()
+            ->getMock();
 
         $this->contextMock = $this->getMockBuilder('Magento\Framework\App\Action\Context')
             ->disableOriginalConstructor()
@@ -181,9 +192,6 @@ class CartTest extends \PHPUnit_Framework_TestCase
         $this->contextMock->expects($this->any())
             ->method('getRequest')
             ->will($this->returnValue($this->requestMock));
-        $this->contextMock->expects($this->any())
-            ->method('getResponse')
-            ->will($this->returnValue($this->responseMock));
         $this->contextMock->expects($this->any())
             ->method('getRedirect')
             ->will($this->returnValue($this->redirectMock));
@@ -195,15 +203,19 @@ class CartTest extends \PHPUnit_Framework_TestCase
             ->will($this->returnValue($this->messageManagerMock));
         $this->contextMock->expects($this->any())
             ->method('getUrl')
-            ->will($this->returnValue($this->urlMock));
-
-        $this->cartHelperMock = $this->getMockBuilder('Magento\Checkout\Helper\Cart')
-            ->disableOriginalConstructor()
-            ->getMock();
+            ->willReturn($this->urlMock);
+        $this->contextMock->expects($this->any())
+            ->method('getResultFactory')
+            ->willReturn($this->resultFactoryMock);
+        $this->resultFactoryMock->expects($this->any())
+            ->method('create')
+            ->willReturnMap(
+                [
+                    [ResultFactory::TYPE_REDIRECT, [], $this->resultRedirectMock],
+                    [ResultFactory::TYPE_JSON, [], $this->resultJsonMock]
+                ]
+            );
 
-        $this->jsonHelperMock = $this->getMockBuilder('Magento\Framework\Json\Helper\Data')
-            ->disableOriginalConstructor()
-            ->getMock();
 
         $this->model = new Cart(
             $this->contextMock,
@@ -215,8 +227,7 @@ class CartTest extends \PHPUnit_Framework_TestCase
             $this->productHelperMock,
             $this->escaperMock,
             $this->helperMock,
-            $this->cartHelperMock,
-            $this->jsonHelperMock
+            $this->cartHelperMock
         );
     }
 
@@ -243,13 +254,12 @@ class CartTest extends \PHPUnit_Framework_TestCase
         $itemMock->expects($this->once())
             ->method('getId')
             ->willReturn(null);
+        $this->resultRedirectMock->expects($this->once())
+            ->method('setPath')
+            ->with('*/*', [])
+            ->willReturnSelf();
 
-        $this->redirectMock->expects($this->once())
-            ->method('redirect')
-            ->with($this->responseMock, '*/*', [])
-            ->willReturn($this->responseMock);
-
-        $this->assertEquals($this->responseMock, $this->model->execute());
+        $this->assertSame($this->resultRedirectMock, $this->model->execute());
     }
 
     public function testExecuteWithNoWishlist()
@@ -285,23 +295,44 @@ class CartTest extends \PHPUnit_Framework_TestCase
             ->method('getWishlist')
             ->with($wishlistId)
             ->willReturn(null);
+        $this->resultRedirectMock->expects($this->once())
+            ->method('setPath')
+            ->with('*/*', [])
+            ->willReturnSelf();
 
-        $this->redirectMock->expects($this->once())
-            ->method('redirect')
-            ->with($this->responseMock, '*/*', [])
-            ->willReturn($this->responseMock);
+        $this->assertSame($this->resultRedirectMock, $this->model->execute());
+    }
 
-        $this->assertEquals($this->responseMock, $this->model->execute());
+    public function testExecuteWithQuantityArray()
+    {
+        $refererUrl = $this->prepareExecuteWithQuantityArray();
+        
+        $this->resultRedirectMock->expects($this->once())
+            ->method('setUrl')
+            ->with($refererUrl)
+            ->willReturnSelf();
+
+        $this->assertSame($this->resultRedirectMock, $this->model->execute());
+    }
+
+    public function testExecuteWithQuantityArrayAjax()
+    {
+        $refererUrl = $this->prepareExecuteWithQuantityArray(true);
+
+        $this->resultJsonMock->expects($this->once())
+            ->method('setData')
+            ->with(['backUrl' => $refererUrl])
+            ->willReturnSelf();
+
+        $this->assertSame($this->resultJsonMock, $this->model->execute());
     }
 
     /**
      * @param bool $isAjax
-     *
-     * @dataProvider dataProviderExecuteWithQuantityArray
-     *
+     * @return array
      * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
      */
-    public function testExecuteWithQuantityArray($isAjax)
+    protected function prepareExecuteWithQuantityArray($isAjax = false)
     {
         $itemId = 2;
         $wishlistId = 1;
@@ -505,34 +536,8 @@ class CartTest extends \PHPUnit_Framework_TestCase
         $this->helperMock->expects($this->once())
             ->method('calculate')
             ->willReturnSelf();
-
-        $this->jsonHelperMock->expects($this->any())
-            ->method('jsonEncode')
-            ->with(['backUrl' => $refererUrl])
-            ->willReturn('{"backUrl":"' . $refererUrl . '"}');
-
-        $this->responseMock->expects($this->any())
-            ->method('setRedirect')
-            ->with($refererUrl)
-            ->willReturn($this->responseMock);
-        $this->responseMock->expects($this->any())
-            ->method('representJson')
-            ->with('{"backUrl":"' . $refererUrl . '"}')
-            ->willReturnSelf();
-
-        $expectedResult = ($isAjax ? null : $this->responseMock);
-        $this->assertEquals($expectedResult, $this->model->execute());
-    }
-
-    /**
-     * @return array
-     */
-    public function dataProviderExecuteWithQuantityArray()
-    {
-        return [
-            ['isAjax' => false],
-            ['isAjax' => true],
-        ];
+        
+        return $refererUrl;
     }
 
     /**
@@ -688,12 +693,12 @@ class CartTest extends \PHPUnit_Framework_TestCase
             ->method('calculate')
             ->willReturnSelf();
 
-        $this->responseMock->expects($this->once())
-            ->method('setRedirect')
+        $this->resultRedirectMock->expects($this->once())
+            ->method('setUrl')
             ->with($indexUrl)
-            ->willReturn($this->responseMock);
+            ->willReturnSelf();
 
-        $this->assertEquals($this->responseMock, $this->model->execute());
+        $this->assertSame($this->resultRedirectMock, $this->model->execute());
     }
 
     /**
@@ -849,11 +854,11 @@ class CartTest extends \PHPUnit_Framework_TestCase
             ->method('calculate')
             ->willReturnSelf();
 
-        $this->responseMock->expects($this->once())
-            ->method('setRedirect')
+        $this->resultRedirectMock->expects($this->once())
+            ->method('setUrl')
             ->with($configureUrl)
-            ->willReturn($this->responseMock);
+            ->willReturnSelf();
 
-        $this->assertEquals($this->responseMock, $this->model->execute());
+        $this->assertSame($this->resultRedirectMock, $this->model->execute());
     }
 }
diff --git a/app/code/Magento/Wishlist/Test/Unit/Controller/Index/IndexTest.php b/app/code/Magento/Wishlist/Test/Unit/Controller/Index/IndexTest.php
index 94888effcc121310c5f861654cf5638180e11860..12f3de81f386ccdb5d1fbbf041b254f40bb3d2ba 100644
--- a/app/code/Magento/Wishlist/Test/Unit/Controller/Index/IndexTest.php
+++ b/app/code/Magento/Wishlist/Test/Unit/Controller/Index/IndexTest.php
@@ -3,9 +3,10 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-
 namespace Magento\Wishlist\Test\Unit\Controller\Index;
 
+use Magento\Framework\Controller\ResultFactory;
+
 class IndexTest extends \PHPUnit_Framework_TestCase
 {
     /**
@@ -29,14 +30,24 @@ class IndexTest extends \PHPUnit_Framework_TestCase
     protected $wishlistProvider;
 
     /**
-     * @var \Magento\Framework\App\View|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\Store\App\Response\Redirect|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $view;
+    protected $redirect;
 
     /**
-     * @var \Magento\Store\App\Response\Redirect|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\Framework\Controller\ResultFactory|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $redirect;
+    protected $resultFactoryMock;
+
+    /**
+     * @var \Magento\Framework\View\Result\Page|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $resultPageMock;
+
+    /**
+     * @var \Magento\Framework\View\Layout|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $layoutMock;
 
     protected function setUp()
     {
@@ -44,8 +55,24 @@ class IndexTest extends \PHPUnit_Framework_TestCase
         $this->request = $this->getMock('Magento\Framework\App\Request\Http', [], [], '', false);
         $this->response = $this->getMock('Magento\Framework\App\Response\Http', [], [], '', false);
         $this->wishlistProvider = $this->getMock('Magento\Wishlist\Controller\WishlistProvider', [], [], '', false);
-        $this->view = $this->getMock('Magento\Framework\App\View', [], [], '', false);
         $this->redirect = $this->getMock('\Magento\Store\App\Response\Redirect', [], [], '', false);
+        $this->resultFactoryMock = $this->getMockBuilder('Magento\Framework\Controller\ResultFactory')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->resultPageMock = $this->getMockBuilder('Magento\Framework\View\Result\Page')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->layoutMock = $this->getMockBuilder('Magento\Framework\View\Layout')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->resultFactoryMock->expects($this->any())
+            ->method('create')
+            ->with(ResultFactory::TYPE_PAGE, [])
+            ->willReturn($this->resultPageMock);
+        $this->resultPageMock->expects($this->any())
+            ->method('getLayout')
+            ->willReturn($this->layoutMock);
     }
 
     protected function prepareContext()
@@ -84,14 +111,13 @@ class IndexTest extends \PHPUnit_Framework_TestCase
             ->expects($this->any())
             ->method('getRedirect')
             ->willReturn($this->redirect);
-        $this->context
-            ->expects($this->any())
-            ->method('getView')
-            ->willReturn($this->view);
         $this->context
             ->expects($this->any())
             ->method('getMessageManager')
             ->willReturn($messageManager);
+        $this->context->expects($this->any())
+            ->method('getResultFactory')
+            ->willReturn($this->resultFactoryMock);
     }
 
     public function getController()
@@ -120,30 +146,10 @@ class IndexTest extends \PHPUnit_Framework_TestCase
     {
         $wishlist = $this->getMock('Magento\Wishlist\Model\Wishlist', [], [], '', false);
 
-        $layout = $this->getMock('Magento\Framework\View\Layout', [], [], '', false);
-        $layout
-            ->expects($this->once())
-            ->method('initMessages')
-            ->willReturn(true);
-
-        $this->wishlistProvider
-            ->expects($this->once())
+        $this->wishlistProvider->expects($this->once())
             ->method('getWishlist')
             ->willReturn($wishlist);
 
-        $this->view
-            ->expects($this->once())
-            ->method('loadLayout')
-            ->willReturn(true);
-        $this->view
-            ->expects($this->once())
-            ->method('getLayout')
-            ->willReturn($layout);
-        $this->view
-            ->expects($this->once())
-            ->method('renderLayout')
-            ->willReturn(true);
-
-        $this->getController()->execute();
+        $this->assertSame($this->resultPageMock, $this->getController()->execute());
     }
 }
diff --git a/app/code/Magento/Wishlist/Test/Unit/Controller/Index/RemoveTest.php b/app/code/Magento/Wishlist/Test/Unit/Controller/Index/RemoveTest.php
index f2c2954f59d739e122c5e7b2b174136a1731cb9a..96381ac144f7ead0d860646c889ccb1bb30acb20 100644
--- a/app/code/Magento/Wishlist/Test/Unit/Controller/Index/RemoveTest.php
+++ b/app/code/Magento/Wishlist/Test/Unit/Controller/Index/RemoveTest.php
@@ -3,9 +3,10 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-
 namespace Magento\Wishlist\Test\Unit\Controller\Index;
 
+use Magento\Framework\Controller\ResultFactory;
+
 class RemoveTest extends \PHPUnit_Framework_TestCase
 {
     /**
@@ -23,16 +24,6 @@ class RemoveTest extends \PHPUnit_Framework_TestCase
      */
     protected $request;
 
-    /**
-     * @var \Magento\Framework\App\Response\Http|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $response;
-
-    /**
-     * @var \Magento\Framework\App\View|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $view;
-
     /**
      * @var \Magento\Store\App\Response\Redirect|\PHPUnit_Framework_MockObject_MockObject
      */
@@ -53,17 +44,36 @@ class RemoveTest extends \PHPUnit_Framework_TestCase
      */
     protected $url;
 
+    /**
+     * @var \Magento\Framework\Controller\ResultFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $resultFactoryMock;
+
+    /**
+     * @var \Magento\Framework\Controller\Result\Redirect|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $resultRedirectMock;
+
     protected function setUp()
     {
         $this->context = $this->getMock('Magento\Framework\App\Action\Context', [], [], '', false);
         $this->request = $this->getMock('Magento\Framework\App\Request\Http', [], [], '', false);
-        $this->response = $this->getMock('Magento\Framework\App\Response\Http', [], [], '', false);
         $this->wishlistProvider = $this->getMock('Magento\Wishlist\Controller\WishlistProvider', [], [], '', false);
-        $this->view = $this->getMock('Magento\Framework\App\View', [], [], '', false);
         $this->redirect = $this->getMock('\Magento\Store\App\Response\Redirect', [], [], '', false);
         $this->om = $this->getMock('Magento\Framework\App\ObjectManager', [], [], '', false);
         $this->messageManager = $this->getMock('Magento\Framework\Message\Manager', [], [], '', false);
         $this->url = $this->getMock('Magento\Framework\Url', [], [], '', false);
+        $this->resultFactoryMock = $this->getMockBuilder('Magento\Framework\Controller\ResultFactory')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->resultRedirectMock = $this->getMockBuilder('Magento\Framework\Controller\Result\Redirect')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->resultFactoryMock->expects($this->any())
+            ->method('create')
+            ->with(ResultFactory::TYPE_REDIRECT, [])
+            ->willReturn($this->resultRedirectMock);
     }
 
     public function tearDown()
@@ -71,9 +81,7 @@ class RemoveTest extends \PHPUnit_Framework_TestCase
         unset(
             $this->context,
             $this->request,
-            $this->response,
             $this->wishlistProvider,
-            $this->view,
             $this->redirect,
             $this->om,
             $this->messageManager,
@@ -94,10 +102,6 @@ class RemoveTest extends \PHPUnit_Framework_TestCase
             ->expects($this->any())
             ->method('getRequest')
             ->willReturn($this->request);
-        $this->context
-            ->expects($this->any())
-            ->method('getResponse')
-            ->willReturn($this->response);
         $this->context
             ->expects($this->any())
             ->method('getEventManager')
@@ -114,14 +118,13 @@ class RemoveTest extends \PHPUnit_Framework_TestCase
             ->expects($this->any())
             ->method('getRedirect')
             ->willReturn($this->redirect);
-        $this->context
-            ->expects($this->any())
-            ->method('getView')
-            ->willReturn($this->view);
         $this->context
             ->expects($this->any())
             ->method('getMessageManager')
             ->willReturn($this->messageManager);
+        $this->context->expects($this->any())
+            ->method('getResultFactory')
+            ->willReturn($this->resultFactoryMock);
     }
 
     public function getController()
@@ -283,13 +286,12 @@ class RemoveTest extends \PHPUnit_Framework_TestCase
                 ]
             );
 
-        $this->response
-            ->expects($this->once())
-            ->method('setRedirect')
+        $this->resultRedirectMock->expects($this->once())
+            ->method('setUrl')
             ->with($referer)
-            ->willReturn(true);
+            ->willReturnSelf();
 
-        $this->getController()->execute();
+        $this->assertSame($this->resultRedirectMock, $this->getController()->execute());
     }
 
     public function testExecuteCanNotSaveWishlistAndWithRedirect()
@@ -373,19 +375,18 @@ class RemoveTest extends \PHPUnit_Framework_TestCase
             ->expects($this->once())
             ->method('getUrl')
             ->with('*/*')
-            ->willReturn('http:/test.com/frontname/module/controller/action');
+            ->willReturn('http://test.com/frontname/module/controller/action');
 
         $this->redirect
             ->expects($this->once())
             ->method('getRedirectUrl')
-            ->willReturn('http:/test.com/frontname/module/controller/action');
+            ->willReturn('http://test.com/frontname/module/controller/action');
 
-        $this->response
-            ->expects($this->once())
-            ->method('setRedirect')
-            ->with('http:/test.com/frontname/module/controller/action')
-            ->willReturn(true);
+        $this->resultRedirectMock->expects($this->once())
+            ->method('setUrl')
+            ->with('http://test.com/frontname/module/controller/action')
+            ->willReturnSelf();
 
-        $this->getController()->execute();
+        $this->assertSame($this->resultRedirectMock, $this->getController()->execute());
     }
 }
diff --git a/app/code/Magento/Wishlist/Test/Unit/Controller/Index/UpdateItemOptionsTest.php b/app/code/Magento/Wishlist/Test/Unit/Controller/Index/UpdateItemOptionsTest.php
index 9fddb7383a3034e51fcf973eb797f4638189083a..cb1b05a9328a9203c38aa36d6c9034bfa04b1144 100755
--- a/app/code/Magento/Wishlist/Test/Unit/Controller/Index/UpdateItemOptionsTest.php
+++ b/app/code/Magento/Wishlist/Test/Unit/Controller/Index/UpdateItemOptionsTest.php
@@ -3,9 +3,10 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-
 namespace Magento\Wishlist\Test\Unit\Controller\Index;
 
+use Magento\Framework\Controller\ResultFactory;
+
 /**
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
@@ -31,21 +32,6 @@ class UpdateItemOptionsTest extends \PHPUnit_Framework_TestCase
      */
     protected $request;
 
-    /**
-     * @var \Magento\Framework\App\Response\Http|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $response;
-
-    /**
-     * @var \Magento\Framework\App\View|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $view;
-
-    /**
-     * @var \Magento\Store\App\Response\Redirect|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $redirect;
-
     /**
      * @var \Magento\Framework\App\ObjectManager|\PHPUnit_Framework_MockObject_MockObject
      */
@@ -71,6 +57,16 @@ class UpdateItemOptionsTest extends \PHPUnit_Framework_TestCase
      */
     protected $eventManager;
 
+    /**
+     * @var \Magento\Framework\Controller\ResultFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $resultFactoryMock;
+
+    /**
+     * @var \Magento\Framework\Controller\Result\Redirect|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $resultRedirectMock;
+
     /**
      * SetUp method
      *
@@ -81,15 +77,23 @@ class UpdateItemOptionsTest extends \PHPUnit_Framework_TestCase
         $this->productRepository = $this->getMock('Magento\Catalog\Model\ProductRepository', [], [], '', false);
         $this->context = $this->getMock('Magento\Framework\App\Action\Context', [], [], '', false);
         $this->request = $this->getMock('Magento\Framework\App\Request\Http', [], [], '', false);
-        $this->response = $this->getMock('Magento\Framework\App\Response\Http', [], [], '', false);
         $this->wishlistProvider = $this->getMock('Magento\Wishlist\Controller\WishlistProvider', [], [], '', false);
-        $this->view = $this->getMock('Magento\Framework\App\View', [], [], '', false);
-        $this->redirect = $this->getMock('\Magento\Store\App\Response\Redirect', [], [], '', false);
         $this->om = $this->getMock('Magento\Framework\App\ObjectManager', [], [], '', false);
         $this->messageManager = $this->getMock('Magento\Framework\Message\Manager', [], [], '', false);
         $this->url = $this->getMock('Magento\Framework\Url', [], [], '', false);
         $this->customerSession = $this->getMock('Magento\Customer\Model\Session', [], [], '', false);
         $this->eventManager = $this->getMock('Magento\Framework\Event\Manager', [], [], '', false);
+        $this->resultFactoryMock = $this->getMockBuilder('Magento\Framework\Controller\ResultFactory')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->resultRedirectMock = $this->getMockBuilder('Magento\Framework\Controller\Result\Redirect')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->resultFactoryMock->expects($this->any())
+            ->method('create')
+            ->with(ResultFactory::TYPE_REDIRECT, [])
+            ->willReturn($this->resultRedirectMock);
     }
 
     /**
@@ -103,10 +107,7 @@ class UpdateItemOptionsTest extends \PHPUnit_Framework_TestCase
             $this->productRepository,
             $this->context,
             $this->request,
-            $this->response,
             $this->wishlistProvider,
-            $this->view,
-            $this->redirect,
             $this->om,
             $this->messageManager,
             $this->url,
@@ -131,10 +132,6 @@ class UpdateItemOptionsTest extends \PHPUnit_Framework_TestCase
             ->expects($this->any())
             ->method('getRequest')
             ->willReturn($this->request);
-        $this->context
-            ->expects($this->any())
-            ->method('getResponse')
-            ->willReturn($this->response);
         $this->context
             ->expects($this->any())
             ->method('getEventManager')
@@ -147,18 +144,13 @@ class UpdateItemOptionsTest extends \PHPUnit_Framework_TestCase
             ->expects($this->any())
             ->method('getActionFlag')
             ->willReturn($actionFlag);
-        $this->context
-            ->expects($this->any())
-            ->method('getRedirect')
-            ->willReturn($this->redirect);
-        $this->context
-            ->expects($this->any())
-            ->method('getView')
-            ->willReturn($this->view);
         $this->context
             ->expects($this->any())
             ->method('getMessageManager')
             ->willReturn($this->messageManager);
+        $this->context->expects($this->any())
+            ->method('getResultFactory')
+            ->willReturn($this->resultFactoryMock);
     }
 
     /**
@@ -189,14 +181,12 @@ class UpdateItemOptionsTest extends \PHPUnit_Framework_TestCase
             ->method('getParam')
             ->with('product')
             ->willReturn(null);
+        $this->resultRedirectMock->expects($this->once())
+            ->method('setPath')
+            ->with('*/', [])
+            ->willReturnSelf();
 
-        $this->redirect
-            ->expects($this->once())
-            ->method('redirect')
-            ->with($this->response, '*/', [])
-            ->willReturn(true);
-
-        $this->getController()->execute();
+        $this->assertSame($this->resultRedirectMock, $this->getController()->execute());
     }
 
     /**
@@ -223,14 +213,12 @@ class UpdateItemOptionsTest extends \PHPUnit_Framework_TestCase
             ->method('addError')
             ->with('We can\'t specify a product.')
             ->willReturn(true);
+        $this->resultRedirectMock->expects($this->once())
+            ->method('setPath')
+            ->with('*/', [])
+            ->willReturnSelf();
 
-        $this->redirect
-            ->expects($this->once())
-            ->method('redirect')
-            ->with($this->response, '*/', [])
-            ->willReturn(true);
-
-        $this->getController()->execute();
+        $this->assertSame($this->resultRedirectMock, $this->getController()->execute());
     }
 
     /**
@@ -293,14 +281,12 @@ class UpdateItemOptionsTest extends \PHPUnit_Framework_TestCase
             ->method('create')
             ->with('Magento\Wishlist\Model\Item')
             ->willReturn($item);
+        $this->resultRedirectMock->expects($this->once())
+            ->method('setPath')
+            ->with('*/', [])
+            ->willReturnSelf();
 
-        $this->redirect
-            ->expects($this->once())
-            ->method('redirect')
-            ->with($this->response, '*/', [])
-            ->willReturn(true);
-
-        $this->getController()->execute();
+        $this->assertSame($this->resultRedirectMock, $this->getController()->execute());
     }
 
     /**
@@ -416,14 +402,12 @@ class UpdateItemOptionsTest extends \PHPUnit_Framework_TestCase
             ->method('addError')
             ->with('error-message', null)
             ->willReturn(true);
+        $this->resultRedirectMock->expects($this->once())
+            ->method('setPath')
+            ->with('*/*', ['wishlist_id' => 56])
+            ->willReturnSelf();
 
-        $this->redirect
-            ->expects($this->once())
-            ->method('redirect')
-            ->with($this->response, '*/*', ['wishlist_id' => 56])
-            ->willReturn(true);
-
-        $this->getController()->execute();
+        $this->assertSame($this->resultRedirectMock, $this->getController()->execute());
     }
     /**
      * Test execute add success critical exception
@@ -556,13 +540,11 @@ class UpdateItemOptionsTest extends \PHPUnit_Framework_TestCase
             ->method('addError')
             ->with('An error occurred while updating wish list.', null)
             ->willReturn(true);
+        $this->resultRedirectMock->expects($this->once())
+            ->method('setPath')
+            ->with('*/*', ['wishlist_id' => 56])
+            ->willReturnSelf();
 
-        $this->redirect
-            ->expects($this->once())
-            ->method('redirect')
-            ->with($this->response, '*/*', ['wishlist_id' => 56])
-            ->willReturn(true);
-
-        $this->getController()->execute();
+        $this->assertSame($this->resultRedirectMock, $this->getController()->execute());
     }
 }
diff --git a/app/code/Magento/Wishlist/Test/Unit/Controller/Shared/AllcartTest.php b/app/code/Magento/Wishlist/Test/Unit/Controller/Shared/AllcartTest.php
index fbd2ce5f641ac78949c061f63885d182daaad5c9..09ea2bb42c74aacbf7555c36fa41679d86822f43 100644
--- a/app/code/Magento/Wishlist/Test/Unit/Controller/Shared/AllcartTest.php
+++ b/app/code/Magento/Wishlist/Test/Unit/Controller/Shared/AllcartTest.php
@@ -3,161 +3,148 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-
 namespace Magento\Wishlist\Test\Unit\Controller\Shared;
 
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
+use Magento\Framework\Controller\ResultFactory;
+
 class AllcartTest extends \PHPUnit_Framework_TestCase
 {
+    /**
+     * @var \Magento\Wishlist\Controller\Shared\Allcart
+     */
+    protected $allcartController;
+
+    /**
+     * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager
+     */
+    protected $objectManagerHelper;
+
+    /**
+     * @var \Magento\Framework\App\Action\Context
+     */
+    protected $context;
+
     /**
      * @var \Magento\Wishlist\Controller\Shared\WishlistProvider|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $wishlistProvider;
+    protected $wishlistProviderMock;
+
+    /**
+     * @var \Magento\Wishlist\Model\ItemCarrier|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $itemCarrierMock;
+
+    /**
+     * @var \Magento\Wishlist\Model\Wishlist|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $wishlistMock;
 
     /**
      * @var \Magento\Framework\App\Request\Http|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $request;
+    protected $requestMock;
 
     /**
-     * @var \Magento\Wishlist\Model\ItemCarrier|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\Framework\Controller\ResultFactory|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $itemCarrier;
+    protected $resultFactoryMock;
 
     /**
-     * @var \Magento\Framework\App\Response\Http|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\Framework\Controller\Result\Redirect|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $response;
+    protected $resultRedirectMock;
 
     /**
-     * @var \Magento\Framework\App\Action\Context|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\Framework\Controller\Result\Forward|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $context;
+    protected $resultForwardMock;
 
     protected function setUp()
     {
-        $this->wishlistProvider = $this->getMock(
-            '\Magento\Wishlist\Controller\Shared\WishlistProvider',
-            [],
-            [],
-            '',
-            false
+        $this->wishlistProviderMock = $this->getMockBuilder('Magento\Wishlist\Controller\Shared\WishlistProvider')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->itemCarrierMock = $this->getMockBuilder('Magento\Wishlist\Model\ItemCarrier')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->wishlistMock = $this->getMockBuilder('Magento\Wishlist\Model\Wishlist')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->requestMock = $this->getMockBuilder('Magento\Framework\App\Request\Http')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->resultFactoryMock = $this->getMockBuilder('Magento\Framework\Controller\ResultFactory')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->resultRedirectMock = $this->getMockBuilder('Magento\Framework\Controller\Result\Redirect')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->resultForwardMock = $this->getMockBuilder('Magento\Framework\Controller\Result\Forward')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->resultFactoryMock->expects($this->any())
+            ->method('create')
+            ->willReturnMap(
+                [
+                    [ResultFactory::TYPE_REDIRECT, [], $this->resultRedirectMock],
+                    [ResultFactory::TYPE_FORWARD, [], $this->resultForwardMock]
+                ]
+            );
+
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+        $this->context = $this->objectManagerHelper->getObject(
+            'Magento\Framework\App\Action\Context',
+            [
+                'request' => $this->requestMock,
+                'resultFactory' => $this->resultFactoryMock
+            ]
+        );
+        $this->allcartController = $this->objectManagerHelper->getObject(
+            'Magento\Wishlist\Controller\Shared\Allcart',
+            [
+                'context' => $this->context,
+                'wishlistProvider' => $this->wishlistProviderMock,
+                'itemCarrier' => $this->itemCarrierMock
+            ]
         );
-        $this->request = $this->getMock('Magento\Framework\App\Request\Http', [], [], '', false);
-        $this->itemCarrier = $this->getMock('Magento\Wishlist\Model\ItemCarrier', [], [], '', false);
-        $this->context = $this->getMock('Magento\Framework\App\Action\Context', [], [], '', false);
-        $this->response = $this->getMock('Magento\Framework\App\Response\Http', [], [], '', false);
     }
 
-    protected function prepareContext()
+    public function testExecuteWithWishlist()
     {
-        $om = $this->getMock('Magento\Framework\App\ObjectManager', [], [], '', false);
-        $eventManager = $this->getMock('Magento\Framework\Event\Manager', null, [], '', false);
-        $url = $this->getMock('Magento\Framework\Url', [], [], '', false);
-        $actionFlag = $this->getMock('Magento\Framework\App\ActionFlag', [], [], '', false);
-        $redirect = $this->getMock('\Magento\Store\App\Response\Redirect', [], [], '', false);
-        $view = $this->getMock('Magento\Framework\App\View', [], [], '', false);
-        $messageManager = $this->getMock('Magento\Framework\Message\Manager', [], [], '', false);
-
-        $this->context
-            ->expects($this->any())
-            ->method('getObjectManager')
-            ->will($this->returnValue($om));
-        $this->context
-            ->expects($this->any())
-            ->method('getRequest')
-            ->will($this->returnValue($this->request));
-        $this->context
-            ->expects($this->any())
-            ->method('getResponse')
-            ->will($this->returnValue($this->response));
-        $this->context
-            ->expects($this->any())
-            ->method('getEventManager')
-            ->will($this->returnValue($eventManager));
-        $this->context
-            ->expects($this->any())
-            ->method('getUrl')
-            ->will($this->returnValue($url));
-        $this->context
-            ->expects($this->any())
-            ->method('getActionFlag')
-            ->will($this->returnValue($actionFlag));
-        $this->context
-            ->expects($this->any())
-            ->method('getRedirect')
-            ->will($this->returnValue($redirect));
-        $this->context
-            ->expects($this->any())
-            ->method('getView')
-            ->will($this->returnValue($view));
-        $this->context
-            ->expects($this->any())
-            ->method('getMessageManager')
-            ->will($this->returnValue($messageManager));
-    }
+        $url = 'http://redirect-url.com';
+        $quantity = 2;
 
-    public function getController()
-    {
-        $this->prepareContext();
-        return new \Magento\Wishlist\Controller\Shared\Allcart(
-            $this->context,
-            $this->wishlistProvider,
-            $this->itemCarrier
-        );
+        $this->wishlistProviderMock->expects($this->once())
+            ->method('getWishlist')
+            ->willReturn($this->wishlistMock);
+        $this->requestMock->expects($this->any())
+            ->method('getParam')
+            ->with('qty')
+            ->willReturn($quantity);
+        $this->itemCarrierMock->expects($this->once())
+            ->method('moveAllToCart')
+            ->with($this->wishlistMock, 2)
+            ->willReturn($url);
+        $this->resultRedirectMock->expects($this->once())
+            ->method('setUrl')
+            ->with($url)
+            ->willReturnSelf();
+
+        $this->assertSame($this->resultRedirectMock, $this->allcartController->execute());
     }
 
     public function testExecuteWithNoWishlist()
     {
-        $this->wishlistProvider->expects($this->once())
+        $this->wishlistProviderMock->expects($this->once())
             ->method('getWishlist')
             ->willReturn(false);
-
-        $this->request
-            ->expects($this->once())
-            ->method('initForward')
-            ->will($this->returnValue(true));
-        $this->request
-            ->expects($this->once())
-            ->method('setActionName')
+        $this->resultForwardMock->expects($this->once())
+            ->method('forward')
             ->with('noroute')
-            ->will($this->returnValue(true));
-        $this->request
-            ->expects($this->once())
-            ->method('setDispatched')
-            ->with(false)
-            ->will($this->returnValue(true));
-
-        $controller = $this->getController();
-        $controller->execute();
-    }
-
-    public function testExecuteWithWishlist()
-    {
-        $wishlist = $this->getMockBuilder('Magento\Wishlist\Model\Wishlist')
-            ->disableOriginalConstructor()
-            ->getMock();
-        $this->wishlistProvider->expects($this->once())
-            ->method('getWishlist')
-            ->willReturn($wishlist);
-
-        $this->request
-            ->expects($this->once())
-            ->method('getParam')
-            ->with('qty')
-            ->will($this->returnValue(2));
-
-        $this->itemCarrier
-            ->expects($this->once())
-            ->method('moveAllToCart')
-            ->with($wishlist, 2)
-            ->will($this->returnValue('http://redirect-url.com'));
-
-        $this->response
-            ->expects($this->once())
-            ->method('setRedirect')
-            ->will($this->returnValue('http://redirect-url.com'));
+            ->willReturnSelf();
 
-        $controller = $this->getController();
-        $controller->execute();
+        $this->assertSame($this->resultForwardMock, $this->allcartController->execute());
     }
 }
diff --git a/app/code/Magento/Wishlist/composer.json b/app/code/Magento/Wishlist/composer.json
index 59eee0b1b1feb0c7ab6eccbe0a4563a729e34340..b5400d7ffae45854dde81421038bcb58547818b7 100644
--- a/app/code/Magento/Wishlist/composer.json
+++ b/app/code/Magento/Wishlist/composer.json
@@ -3,28 +3,28 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta6",
-        "magento/module-customer": "0.74.0-beta6",
-        "magento/module-catalog": "0.74.0-beta6",
-        "magento/module-checkout": "0.74.0-beta6",
-        "magento/module-theme": "0.74.0-beta6",
-        "magento/module-catalog-inventory": "0.74.0-beta6",
-        "magento/module-rss": "0.74.0-beta6",
-        "magento/module-backend": "0.74.0-beta6",
-        "magento/module-sales": "0.74.0-beta6",
-        "magento/module-grouped-product": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
-        "magento/module-ui": "0.74.0-beta6",
+        "magento/module-store": "0.74.0-beta7",
+        "magento/module-customer": "0.74.0-beta7",
+        "magento/module-catalog": "0.74.0-beta7",
+        "magento/module-checkout": "0.74.0-beta7",
+        "magento/module-theme": "0.74.0-beta7",
+        "magento/module-catalog-inventory": "0.74.0-beta7",
+        "magento/module-rss": "0.74.0-beta7",
+        "magento/module-backend": "0.74.0-beta7",
+        "magento/module-sales": "0.74.0-beta7",
+        "magento/module-grouped-product": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
+        "magento/module-ui": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "suggest": {
-        "magento/module-configurable-product": "0.74.0-beta6",
-        "magento/module-downloadable": "0.74.0-beta6",
-        "magento/module-bundle": "0.74.0-beta6",
-        "magento/module-cookie": "0.74.0-beta6"
+        "magento/module-configurable-product": "0.74.0-beta7",
+        "magento/module-downloadable": "0.74.0-beta7",
+        "magento/module-bundle": "0.74.0-beta7",
+        "magento/module-cookie": "0.74.0-beta7"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Wishlist/view/adminhtml/layout/customer_form.xml b/app/code/Magento/Wishlist/view/adminhtml/layout/customer_index_edit.xml
similarity index 90%
rename from app/code/Magento/Wishlist/view/adminhtml/layout/customer_form.xml
rename to app/code/Magento/Wishlist/view/adminhtml/layout/customer_index_edit.xml
index 778b395ef14f8086c8c826715669fc6e6d6b03f4..c2caa32651b3797fb91742ea16f9dc1e57eda4dc 100644
--- a/app/code/Magento/Wishlist/view/adminhtml/layout/customer_form.xml
+++ b/app/code/Magento/Wishlist/view/adminhtml/layout/customer_index_edit.xml
@@ -7,7 +7,7 @@
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
     <body>
-        <referenceBlock name="form">
+        <referenceBlock name="customer_form">
             <block class="Magento\Wishlist\Block\Adminhtml\WishlistTab" name="wishlist" />
         </referenceBlock>
     </body>
diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/_footer.less b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/_footer.less
index c8333911914ef0b9074034bd5f189d17d516fe12..290056b3664b9ec988dec9870b94a528d4a54edc 100644
--- a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/_footer.less
+++ b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/_footer.less
@@ -38,6 +38,10 @@
             @_link-text-decoration-active: false
         );
     }
+    .admin__control-select {
+        max-width: 52rem;
+        width: 100%;
+    }
 }
 
 .magento-version {
diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/_menu.less b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/_menu.less
index 0101fe2439257f2c88766365f6bdf0b407fd8c46..2fe7569f06c995e426241930d01694c5fa15c438 100644
--- a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/_menu.less
+++ b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/_menu.less
@@ -73,16 +73,18 @@
         position: relative;
         text-align: center;
         z-index: @menu__z-index;
-        &:focus {
-            background-color: @menu-item__active__background-color;
-            box-shadow: none;
-            + .admin__menu {
-                .level-0 {
-                    &:first-child {
-                        > a {
-                            background-color: @menu__background-color;
-                            &:after {
-                                display: none;
+        ._keyfocus & {
+            &:focus {
+                background-color: @menu-item__active__background-color;
+                box-shadow: none;
+                + .admin__menu {
+                    .level-0 {
+                        &:first-child {
+                            > a {
+                                background-color: @menu__background-color;
+                                &:after {
+                                    display: none;
+                                }
                             }
                         }
                     }
@@ -275,25 +277,16 @@
         margin: -(@submenu-heading-group__indent-bottom) @submenu__padding-horizontal * 2 + @submenu-action-close__indent-right 3.8rem @submenu__padding-horizontal * 2;
     }
 
-    .submenu-close {
-        &:extend(.abs-action-reset all);
+    .action-close {
         padding: 2.4rem @submenu-action-close__indent-right;
         position: absolute;
         right: 0;
         top: 0;
-        &:active {
-            .scale();
-        }
         &:before {
-            &:extend(.abs-icon all);
             color: @submenu-section-label__color;
-            content: @icon-close-mage__content;
             font-size: 1.7rem;
-            .transition(color);
         }
         &:hover {
-            cursor: pointer;
-            text-decoration: none;
             &:before {
                 color: @color-white;
             }
diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/_actions-group.less b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/_actions-group.less
index c7c4a1d35bd596fe0f363e763fd50d2d006e5bcf..716248651a8add1391f46575e8323e20a1d7dbd9 100644
--- a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/_actions-group.less
+++ b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/_actions-group.less
@@ -19,53 +19,7 @@
 //  Variables
 //  ---------------------------------------------
 
-@page-header-action__height: 3.4rem;
-@page-header-action__color: @text__color;
-@page-header-action__hover__color: darken(@page-header-action__color, 20%);
-@page-header-action__background-color: @page-wrapper__background-color;
-@page-header-action__active__border-color: @color-blue-pure;
-@page-header-action__border-color: @color-light-gray;
-
-//
-//  Extends
-//  ---------------------------------------------
-
-.abs-page-header-action {
-    background-color: @page-header-action__background-color;
-    border: 1px solid transparent;
-    border-bottom: none;
-    color: @page-header-action__color;
-    display: inline-block;
-    height: @page-header-action__height;
-    position: relative;
-    transition: border-color @appering__transition-duration @apperaing__transition-timing-function;
-    &:hover {
-        color: @page-header-action__hover__color;
-        text-decoration: none;
-    }
-}
-
-.abs-page-header-action-menu {
-    background-color: @page-header-action__background-color;
-    border: 1px solid @page-header-action__active__border-color;
-    box-shadow: @component__box-shadow__base;
-    margin-top: -1px;
-    opacity: 0;
-    position: absolute;
-    right: 0;
-    top: 100%;
-    transition: all @appering__transition-duration @apperaing__transition-timing-function;
-    visibility: hidden;
-    &:before {
-        content: '';
-        position: absolute;
-    }
-    > li {
-        display: block;
-        > a {
-        }
-    }
-}
+@page-header-action__height: @action__height + .1rem;
 
 //
 
diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_notifications.less b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_notifications.less
index fd094d1ee44c7d1516e6f1989fb7086ad5b5034b..8d88b1044fc973c63d5f191a9073b77a862de7f6 100644
--- a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_notifications.less
+++ b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_notifications.less
@@ -18,14 +18,14 @@
 @notifications-action__padding-bottom: (@page-header-action__height - @notifications-action-icon__size) / 2 - .05rem;
 @notifications-action__padding-side: 2rem;
 @notifications-action__padding-top: (@page-header-action__height - @notifications-action-icon__size) / 2 + .05rem;
-@notifications-action__hover__color: darken(@page-header-action__color, 20%);
+@notifications-action__hover__color: darken(@action-dropdown__color, 20%);
 @notifications-action-icon__size: 1.9rem;
 @notifications-action-menu__z-index: @header__z-index;
 
 @notifications-close__color: @color-gray80;
 @notifications-counter__background-color: @color-tomato-brick;
 @notifications-entry__padding-top: .6rem;
-@notifications-entry__hover__background-color: @color-blue-clear-sky;
+@notifications-entry__hover__background-color: @action__hover__background-color;
 @notifications-list__width: 32rem;
 @notifications-title__color: @color-light-phoenix;
 @notifications-time__color: @color-very-dark-gray1;
@@ -39,33 +39,41 @@
     &.active {
         z-index: @notifications-action-menu__z-index; // Should be over global search when active
         .notifications-action {
-            border-color: @page-header-action__active__border-color;
+            border-color: @action-dropdown__active__border-color;
             box-shadow: @component__box-shadow__base;
             &:after {
-                background-color: @page-header-action__background-color;
+                border: none;
+                background-color: @action-dropdown__background-color;
                 content: '';
+                display: block;
                 height: @component__shadow-size__base + 1;
                 left: -(@component__shadow-size__base + 1);
+                margin-top: 0;
                 position: absolute;
                 right: 0;
                 top: 100%;
+                width: auto;
             }
         }
-        .notifications-list {
-            opacity: 1;
-            visibility: visible;
-        }
+    }
+    //  Notifications dropdown
+    .admin__action-dropdown-menu {
+        padding: 1rem 0 0;
+        width: @notifications-list__width;
     }
 }
 
 .notifications-action {
-    &:extend(.abs-page-header-action all);
+    height: @page-header-action__height;
     padding: @notifications-action__padding-top @notifications-action__padding-side @notifications-action__padding-bottom;
-    z-index: 2;
+    &:after {
+        display: none;
+    }
     &:before {
         &:extend(.abs-icon all);
         content: @icon-notification-02__content;
         font-size: @notifications-action-icon__size;
+        margin-right: 0;
     }
     &:active {
         &:before {
@@ -89,21 +97,11 @@
     }
 }
 
-.notifications-list {
-    &:extend(.abs-page-header-action-menu all);
-    padding-top: 1rem;
-    width: @notifications-list__width;
-    z-index: 1;
-    &:before {
-        z-index: 2;
-    }
-}
-
 .notifications-entry {
     line-height: @line-height__base;
     padding: @notifications-entry__padding-top @notifications-action__padding-side .8rem;
     position: relative;
-    transition: background-color .2s linear;
+    transition: @smooth__background-color;
     &:hover {
         background-color: @notifications-entry__hover__background-color;
     }
diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_search.less b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_search.less
index 8b733d549c46afbd5e8f133acc3ec51ee86b5515..27524d7d4d0854693596871cd21c5d8f05dd84b8 100644
--- a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_search.less
+++ b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_search.less
@@ -43,8 +43,8 @@
     min-width: @search-global-field__width;
     &._active {
         .search-global-input {
-            background-color: @page-header-action__background-color;
-            border-color: @page-header-action__active__border-color;
+            background-color: @action-dropdown__background-color;
+            border-color: @action-dropdown__active__border-color;
             box-shadow: @component__box-shadow__base;
             padding-right: @search-global-input__active__padding-right;
             width: @search-global-input__active__width;
@@ -70,7 +70,7 @@
         width: @search-global-input__active__width;
     }
     .search-global-menu {
-        border: 1px solid @page-header-action__active__border-color;
+        border: 1px solid @action-dropdown__active__border-color;
         border-top-color: transparent;
         box-shadow: @component__box-shadow__base;
         left: 0;
@@ -81,7 +81,7 @@
         top: 100%;
         z-index: 2;
         &:after {
-            background-color: @page-header-action__background-color;
+            background-color: @action-dropdown__background-color;
             content: '';
             height: @component__shadow-size__base;
             left: 0;
@@ -90,8 +90,8 @@
             top: -@component__shadow-size__base;
         }
         > li {
-            background-color: @page-header-action__background-color;
-            border-top: 1px solid @page-header-action__border-color;
+            background-color: @action-dropdown__background-color;
+            border-top: 1px solid @action-dropdown__border-color;
             display: block;
             font-size: @font-size__s;
             padding: @search-global-input__padding-top @search-global-input__padding-side @search-global-input__padding-bottom;
@@ -120,7 +120,7 @@
     }
     &:hover {
         &:before {
-            color: @page-header-action__hover__color;
+            color: @action-dropdown__hover__color;
         }
     }
     &:before {
diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_user.less b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_user.less
index 678ed4b2342689e39c6a8bc2e1e8b21288409102..e43ef98b27b22da4156f8e2427c6eab0bbd2ae4c 100644
--- a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_user.less
+++ b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_user.less
@@ -11,8 +11,6 @@
 //  Variables
 //  ---------------------------------------------
 
-@user__font-size: round(@font-size__base - .1rem, 1);
-
 @user-account__padding-bottom: .4rem;
 @user-account__padding-left: 4rem;
 @user-account__padding-top: .7rem;
@@ -20,6 +18,8 @@
 
 @user-account-menu__min-width: 20rem;
 @user-account-menu__z-index: @notifications-action-menu__z-index - 10; // Should be lower than notifications
+@user-account-menu__hover__background-color: @action__hover__background-color;
+@user-account-menu__active__background-color: darken(@color-blue-clear-sky, 5%);
 
 //
 
@@ -27,102 +27,74 @@
     float: right;
     line-height: @line-height__base; // ToDo UI: Delete with admin scope
     margin-left: .3rem;
-    position: relative;
     z-index: @user-account-menu__z-index;
+    &._active,
     &.active {
-        .admin-user-account {
-            border-color: @page-header-action__active__border-color;
+        //  User account action
+        .admin__action-dropdown {
+            border-color: @action-dropdown__active__border-color;
             box-shadow: @component__box-shadow__base;
         }
-        .admin-user-account-text-wrapper {
-            &:after {
-                background-color: @page-header-action__background-color;
-                content: '';
-                height: @component__shadow-size__base + 1;
-                left: -(@component__shadow-size__base + 1);
-                position: absolute;
-                right: 0;
-                top: 100%;
+    }
+    //  User account action
+    .admin__action-dropdown {
+        .action-toggle-triangle(
+            @_dropdown__padding-right: @user-account__padding-right;
+            @_triangle__color: @action-dropdown__color;
+            @_triangle__hover__color: @action-dropdown__hover__color;
+            @_triangle__right: 1.3rem;
+        );
+        height: @page-header-action__height;
+        padding-bottom: @user-account__padding-bottom;
+        padding-left: @user-account__padding-left;
+        padding-top: @user-account__padding-top;
+        &:before {
+            @_icon-user__size: 2rem;
+
+            &:extend(.abs-icon all);
+            content: @icon-account__content;
+            font-size: @_icon-user__size;
+            left: 1.1rem;
+            margin-top: -(@_icon-user__size / 2) - .1rem;
+            position: absolute;
+            top: 50%;
+        }
+    }
+    //  User account menu
+    .admin__action-dropdown-menu {
+        @_user-menu__indent-side: 1rem;
+        min-width: @user-account-menu__min-width;
+        padding-left: @_user-menu__indent-side;
+        padding-right: @_user-menu__indent-side;
+        > li {
+            > a {
+                padding-right: (@user-account__padding-right - @_user-menu__indent-side);
+                padding-left: .5em;
+                white-space: nowrap;
+                transition: @smooth__background-color;
+                &:hover {
+                    background-color: @user-account-menu__hover__background-color;
+                    color: @action-dropdown__color;
+                }
+                &:active {
+                    background-color: @user-account-menu__active__background-color;
+                    bottom: -1px;
+                    position: relative;
+                }
             }
         }
-        .admin-user-menu {
-            opacity: 1;
-            visibility: visible;
+        .admin-user-name {
+            .text-overflow-ellipsis();
+            display: inline-block;
+            max-width: @user-account-menu__min-width;
+            overflow: hidden;
+            vertical-align: top;
         }
     }
 }
 
-.admin-user-account {
-    &:extend(.abs-page-header-action all);
-    .dropdown-triangle(
-        @_dropdown__padding-right: @user-account__padding-right;
-        @_triangle__color: @page-header-action__color;
-        @_triangle__hover__color: @page-header-action__hover__color;
-        @_triangle__right: 1.3rem;
-    );
-    font-size: @user__font-size;
-    letter-spacing: .05em;
-    padding-bottom: @user-account__padding-bottom;
-    padding-left: @user-account__padding-left;
-    padding-top: @user-account__padding-top;
-    z-index: 2;
-    &:before {
-        @_icon-user__size: 2rem;
-        
-        &:extend(.abs-icon all);
-        content: @icon-account__content;
-        font-size: @_icon-user__size;
-        left: 1.1rem;
-        margin-top: -(@_icon-user__size / 2) - .1rem;
-        position: absolute;
-        top: 50%;
-    }
-}
-
 .admin-user-account-text {
+    .text-overflow-ellipsis();
     display: inline-block;
     max-width: @user-account-menu__min-width - @user-account__padding-left - @user-account__padding-right - 2rem;
-    overflow: hidden;
-    text-overflow: ellipsis;
-    white-space: nowrap;
-}
-
-.admin-user-menu {
-    @_user-menu__inden-side: 1rem;
-    
-    &:extend(.abs-page-header-action-menu all);
-    line-height: @line-height__base;
-    min-width: @user-account-menu__min-width;
-    padding: .5em @_user-menu__inden-side;
-    z-index: 1;
-    &:before {
-        z-index: 1;
-    }
-    > li {
-        > a {
-            color: @page-header-action__color;
-            display: block;
-            padding: .6rem (@user-account__padding-right - @_user-menu__inden-side) .6rem .5em;
-            text-decoration: none;
-            transition: background-color .1s linear;
-            white-space: nowrap;
-            &:hover {
-                background-color: @dropdown-menu__hover__background-color;
-                color: @page-header-action__color;
-            }
-            &:active {
-                background-color: @dropdown-menu__active__background-color;
-                bottom: -1px;
-                position: relative;
-            }
-        }
-    }
-    .admin-user-name {
-        display: inline-block;
-        max-width: @user-account-menu__min-width;
-        overflow: hidden;
-        text-overflow: ellipsis;
-        vertical-align: text-top;
-        white-space: nowrap;
-    }
 }
diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/_actions-bar.less b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/_actions-bar.less
index 8fc37b9a87900f1e8bfb4187f9c6573cb30fd66b..1e410484253ff275204b387310b92fe406181c64 100644
--- a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/_actions-bar.less
+++ b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/_actions-bar.less
@@ -12,7 +12,7 @@
 //  Components
 //  ---------------------------------------------
 
-@import 'actions_bar/_store-switcher.less';
+@import 'actions-bar/_store-switcher.less';
 
 //
 //  Variables
@@ -34,7 +34,7 @@
 }
 
 .page-main-actions {
-    margin: 0 0 2rem;
+    margin: 0 0 @indent__l;
 }
 
 //
@@ -52,15 +52,13 @@
         z-index: @page-actions__fixed__z-index;
         .page-actions-inner {
             &:before {
+                .text-overflow-ellipsis();
                 color: @page-title__color;
                 content: attr(data-title);
                 float: left;
                 font-size: @page-title__font-size;
                 margin-top: .3rem;
                 max-width: 50%;
-                overflow: hidden;
-                text-overflow: ellipsis;
-                white-space: nowrap;
             }
         }
     }
@@ -105,6 +103,7 @@
         }
     }
     .actions-split {
+        &:extend(.abs-actions-split-xl all);
         float: right;
         margin-left: @_page-action__indent;
         .vendor-prefix-order(2);
diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/_page-nav.less b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/_page-nav.less
index 09319136bec92e3efe47253d810c21eba1eacd4b..0071951108a8b8bd2be488be74e487b25762675d 100644
--- a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/_page-nav.less
+++ b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/_page-nav.less
@@ -23,7 +23,7 @@
 @admin__page-nav-item__hover__background-color: darken(@admin__page-nav__background-color, 5%);
 
 @admin__page-nav-link__color: @color-very-dark-gray-black;
-@admin__page-nav-link__padding: @indent__base 4rem @indent__base 1rem;
+@admin__page-nav-link__padding: @indent__base 4rem @indent__base @indent__s;
 @admin__page-nav-link__hover__color: @color-very-dark-gray-black;
 @admin__page-nav-link__changed__color: @color-very-dark-gray;
 
@@ -133,7 +133,7 @@
 .admin__page-nav-items {
     list-style-type: none;
     margin: 0;
-    padding: 0;
+    padding: @indent__s 0 @admin__page-nav-item__margin-vertical 0;
 }
 
 .admin__page-nav-item {
@@ -180,10 +180,6 @@
             display: inline-block;
         }
     }
-
-    &:last-child {
-        margin-bottom: @admin__page-nav-item__margin-vertical;
-    }
 }
 
 
@@ -276,7 +272,7 @@
         box-shadow: @admin__page-nav-tooltip__box-shadow;
         display: none;
         font-weight: @font-weight__regular;
-        left: -1rem;
+        left: -@indent__s;
         line-height: @line-height__base;
         padding: 2rem;
         position: absolute;
diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/actions_bar/_store-switcher.less b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/actions-bar/_store-switcher.less
similarity index 98%
rename from app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/actions_bar/_store-switcher.less
rename to app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/actions-bar/_store-switcher.less
index 3e699e2172984de88021448463571bcd9f5f87e1..99527ea22ca0b8ea743dc380f30360a5e6f02dd3 100644
--- a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/actions_bar/_store-switcher.less
+++ b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/actions-bar/_store-switcher.less
@@ -13,9 +13,10 @@
     color: @text__color; // ToDo UI: Delete with admin scope
     float: left;
     font-size: round(@font-size__base - .1rem, 1);
-    margin-top: 1.1rem;
+    margin-top: .7rem;
     .admin__action-dropdown {
         margin-left: .5em;
+        background-color: @page-main-actions__background-color;
     }
     .dropdown {
         .dropdown(
diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/pages/_dashboard.less b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/pages/_dashboard.less
index 8155f8e461eabf82cc8007f13c086edcbf402ebf..bb55d0e0722cdbb18b1b315f8ce82703ebeea40c 100644
--- a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/pages/_dashboard.less
+++ b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/pages/_dashboard.less
@@ -27,7 +27,7 @@
             padding-left: 0;
         }
     }
-    &.table-info {
+    &.admin__table-primary {
         th {
             border-top: 0;
         }
@@ -91,6 +91,9 @@
         background: @dashboard-tabs__background-color;
         font-size: @dashboard__font-size__base;
     }
+    .ui-tabs-panel {
+        border-top: 1px solid @color-gray68;
+    }
 }
 
 //
diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/pages/_login.less b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/pages/_login.less
index 7ba168e1ab2333553e3416ff40e09f404872faac..bf9bfec974326847996124b11b68fa4867defb75 100644
--- a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/pages/_login.less
+++ b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/pages/_login.less
@@ -18,12 +18,12 @@
 //  Admin user auth pages layout
 //  ---------------------------------------------
 
-// Header
+//  Header
 .login-header {
     margin: 0 0 3rem;
 }
 
-// Login box
+//  Login box
 .page-layout-admin-login {
     align-items: center;
     .vendor-prefix-display(flex);
@@ -38,6 +38,7 @@
         margin: auto;
         max-width: @login-box__max-width;
         min-height: @login-box__min-height;
+        min-width: 0;
         padding: 40px 80px 50px;
         position: relative;
         width: 100%;
diff --git a/app/design/adminhtml/Magento/backend/Magento_Downloadable/web/css/source/_module.less b/app/design/adminhtml/Magento/backend/Magento_Downloadable/web/css/source/_module.less
index af531ff02ac2067b0fc1d51bab40c460070df5a3..3411169b6c0028f8e28a2493f6d1ee1f07b13de0 100644
--- a/app/design/adminhtml/Magento/backend/Magento_Downloadable/web/css/source/_module.less
+++ b/app/design/adminhtml/Magento/backend/Magento_Downloadable/web/css/source/_module.less
@@ -59,19 +59,6 @@
         }
 
     }
-    .action-remove {
-        .button-reset();
-        .icon-font(
-            @icon-delete__content,
-            @icons-admin__font-name,
-            @_icon-font-size: 1.8rem,
-            @_icon-font-line-height: 16px,
-            @_icon-font-text-hide: true,
-            @_icon-font-position: after,
-            @_icon-font-color: @color-brown-darkie
-        );
-        margin-top: .5rem;
-    }
 }
 
 @-moz-document url-prefix() { // Firefox fieldset overflow bug fix
diff --git a/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/_module.less b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/_module.less
index 910cec4be04dfc70580ab6632d24ba2627acb519..b27606f18db19606eebfad18a29e4792deee9b15 100644
--- a/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/_module.less
+++ b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/_module.less
@@ -3,10 +3,5 @@
 //  * See COPYING.txt for license details.
 //  */
 
-//
-//  Pages
-//  _____________________________________________
-
-@import 'module/_order-create.less';
-@import 'module/_order-create-sidebar.less';
-@import 'module/_order-create-table.less';
+@import 'module/_order.less';
+@import 'module/_edit-order.less';
diff --git a/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/_edit-order.less b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/_edit-order.less
new file mode 100644
index 0000000000000000000000000000000000000000..860f0f37660ee8ba416d59dd615c7ed5489561dd
--- /dev/null
+++ b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/_edit-order.less
@@ -0,0 +1,91 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Variables
+//  ---------------------------------------------
+
+@edit-order-comment-notes__border-color: @color-gray65;
+@edit-order-comment-notes__font-size: @font-size__s;
+
+//
+//  Table secondary for edit order
+//  ---------------------------------------------
+
+.abs-admin__table-secondary-edit-order {
+    th {
+        font-weight: @font-weight__regular;
+        text-align: left;
+        vertical-align: top;
+    }
+    td {
+        text-align: right;
+    }
+    tr {
+        &:last-child {
+            td {
+                border: none;
+            }
+        }
+    }
+}
+
+//
+//  Order information
+//  ---------------------------------------------
+
+.order-information-table {
+    &:extend(.abs-admin__table-secondary-edit-order all);
+}
+
+//
+//  Order account information
+//  ---------------------------------------------
+
+.order-account-information-table {
+    &:extend(.abs-admin__table-secondary-edit-order all);
+}
+
+//
+//  Edit order tables
+//  ---------------------------------------------
+
+.edit-order-table {
+    &:extend(.abs-order-tables all);
+    &:extend(.abs-order-tbody-border all);
+    margin-bottom: 5rem;
+    tfoot {
+        &._hide {
+            display: none;
+        }
+        td {
+            padding-top: @order-create-sidebar__margin__m;
+        }
+        .col-total {
+            text-align: right;
+        }
+    }
+    .edit-total-price-block {
+        padding-left: 3rem;
+    }
+}
+
+.order-subtotal-table {
+    tr {
+        td {
+            &:last-child {
+                text-align: right;
+            }
+        }
+    }
+}
+
+.order-history-block {
+    margin: 0 0 5rem;
+}
+
+.order-history-comments-actions {
+    margin-top: @order-create-sidebar__margin__reqular;
+}
diff --git a/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/_order-create-table.less b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/_order-create-table.less
deleted file mode 100644
index a9594b130c1e82a0256b9a09f12e11ada61dfca9..0000000000000000000000000000000000000000
--- a/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/_order-create-table.less
+++ /dev/null
@@ -1,174 +0,0 @@
-// /**
-//  * Copyright © 2015 Magento. All rights reserved.
-//  * See COPYING.txt for license details.
-//  */
-
-//
-//  Variables
-//  ---------------------------------------------
-
-@order-create-table__border-color: @table-td__border-color;
-@order-create-sku__background: @admin__page-nav__background-color;
-@order-create-sku__padding: @indent__base;
-@order-create-sku-table__border-color: @color-white;
-
-//
-
-//
-//  Table
-//  ---------------------------------------------
-
-.order-tables {
-    margin: 0 0 @order-create-sidebar__margin-reqular;
-    width: 100%;
-    th {
-        border-top: 0;
-        font-size: 1.3rem;
-    }
-    td {
-        border-bottom: none;
-        padding-top: @order-create-sidebar__padding;
-    }
-    tbody {
-        tr {
-            &:last-child {
-                td {
-                    border-bottom: 1px solid @order-create-table__border-color;
-                }
-            }
-            &.border {
-                td {
-                    padding-top: 0;
-                }
-            }
-        }
-    }
-    .col-qty {
-        .admin__control-text {
-            &:extend(.abs-control-qty all);
-        }
-    }
-    .col-actions {
-        .admin__control-select {
-            width: 13rem;
-        }
-    }
-    .price {
-        display: inline-block;
-        margin: 0 0 @order-create-sidebar__margin-small;
-    }
-    .custom-price-block {
-        font-size: @order-create-sidebar__font-size-xs;
-        margin: 0 0 @order-create-sidebar__margin-small;
-        + .admin__control-text {
-            &:extend(.abs-control-price);
-        }
-    }
-    .discount-price-block {
-        font-size: @order-create-sidebar__font-size-xs;
-    }
-    .product-configure-block {
-        margin: 1rem 0 0;
-        .disabled {
-            display: none;
-        }
-    }
-}
-
-.order-search-items {
-    .grid {
-        .action-configure {
-            float: right;
-        }
-        .col-id,
-        .col-price,
-        .col-in_products {
-            width: 10rem;
-        }
-    }
-}
-
-//
-//  Add by SKU
-//  ---------------------------------------------
-
-.add-by-sku-wrapper {
-    .add-by-sku {
-        background: @order-create-sku__background;
-        clear: both;
-        margin: 0 0 @indent__base;
-        padding: @order-create-sku__padding;
-    }
-    .table-info {
-        color: @order-create-sidebar__color;
-    }
-    .admin__field-note {
-        margin: 1.4rem 0;
-    }
-    .table-info {
-        th {
-            border-top: none;
-        }
-        th,
-        td {
-            border-bottom-color: @order-create-sku-table__border-color;
-            &:first-child {
-                padding-left: 0;
-            }
-        }
-    }
-    .action-reset,
-    .action-delete {
-        &:extend(.abs-action-reset all);
-        &:extend(.abs-icon all);
-        display: inline-block;
-        font-size: @order-create-sidebar__font-size + 0.1rem;
-        margin-left: 1.2rem;
-        padding-top: @order-create-sidebar__margin-small + 0.2rem;
-        vertical-align: middle;
-        &:after {
-            color: @order-create-sidebar__color;
-            content: @order-create-icon-remove__content;
-        }
-        &:hover {
-            &:after {
-                color: @order-create-icon-plus__hover__color;
-            }
-        }
-        > span {
-            &:extend(.abs-visually-hidden all);
-        }
-    }
-    .action-reset {
-        margin-top: -.4rem;
-        opacity: .5;
-        padding-top: 0;
-        &:after {
-            content: @order-create-icon-reset__content;
-        }
-        &:hover {
-            opacity: 1;
-        }
-    }
-    .col-qty {
-        .admin__control-text {
-            &:extend(.abs-control-qty all);
-        }
-    }
-}
-
-//
-//  Product configure popup
-//  ---------------------------------------------
-
-.product-configure-popup {
-    .weee {
-        .price-wrapper {
-            display: block;
-            font-size: 1.3rem;
-            &:before {
-                content: attr(data-label) ": ";
-            }
-        }
-    }
-}
diff --git a/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/_order-create.less b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/_order-create.less
deleted file mode 100644
index 5ff4e9228ffd85bce65c88fbb894378729b318db..0000000000000000000000000000000000000000
--- a/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/_order-create.less
+++ /dev/null
@@ -1,416 +0,0 @@
-// /**
-//  * Copyright © 2015 Magento. All rights reserved.
-//  * See COPYING.txt for license details.
-//  */
-
-//
-//  Variables
-//  ---------------------------------------------
-
-@order-create-icon-refresh__font-size: 2rem;
-@order-create-icon-refresh__color: @color-gray83;
-@order-create-icon-refresh__hover__color: darken(@color-gray83, 10%);
-
-@order-create-icon-add__content: @icon-arrow-right__content;
-@order-create-icon-configure__content: @icon-systems__content;
-@order-create-icon-remove__content: @icon-delete__content;
-@order-create-icon-reset__content: @icon-remove-small__content;
-@order-create-icon-refresh__content: @icon-refresh__content;
-@order-create-icon-plus__content: @icon-plus__content;
-@order-create-icon-plus__hover__color: @color-very-dark-gray-black2;
-
-//
-
-//
-//  Layout
-//  ---------------------------------------------
-
-.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
-    .order-details {
-        float: right;
-        #mix-grid .width(9,12);
-        margin-left: 0;
-    }
-    .order-sidebar {
-        #mix-grid .column(3,12);
-        margin-left: 0;
-    }
-
-    .order-billing-address,
-    .order-billing-method,
-    .order-history {
-        float: left;
-        #mix-grid .width(6,12);
-    }
-
-    .order-shipping-address,
-    .order-shipping-method,
-    .order-totals {
-        float: right;
-        #mix-grid .width(6,12);
-    }
-}
-
-//
-//  Select Store Scope
-//  ---------------------------------------------
-
-.tree-store-scope {
-    max-width: 50rem;
-
-    .admin__field {
-        margin: 0 0 1rem;
-    }
-}
-
-//
-//  Order discounts
-//  ---------------------------------------------
-
-.order-discounts {
-    &:extend(.abs-clearfix all);
-    margin-top: @indent__base;
-    .action-secondary {
-        float: right;
-        margin-top: 2.1rem;
-    }
-    .order-coupons {
-        float: left;
-    }
-    .admin__field {
-        display: inline-block;
-        margin: 0 3.5rem 0 0;
-        vertical-align: top;
-
-        .admin__field-control {
-            padding-right: 32px;
-            position: relative;
-        }
-
-        .action-default {
-            &:extend(.abs-action-reset all);
-            top: 7px;
-            position: absolute;
-            right: 0;
-            > span {
-                .extend__visually-hidden();
-            }
-
-            &:before {
-                &:extend(.abs-icon all);
-                content: @order-create-icon-add__content;
-            }
-
-            &:hover {
-                color: @order-create-icon-plus__hover__color;
-            }
-        }
-        p {
-            margin: @indent__s 0 0;
-        }
-    }
-    .action-remove {
-        color: @color-brownie;
-        margin-left: @indent__xs;
-        &:hover {
-            color: @order-create-icon-plus__hover__color;
-            text-decoration: none;
-        }
-        > span {
-            .extend__visually-hidden();
-        }
-        &:before {
-            &:extend(.abs-icon all);
-            content: @order-create-icon-remove__content;
-        }
-    }
-}
-
-//
-//  Order Account Information
-//  ---------------------------------------------
-
-.order-account-information {
-    .admin__fieldset {
-        &:extend(.abs-clearfix all);
-    }
-    .admin__field {
-        margin-bottom: 0;
-    }
-    .field-group_id {
-        float: left;
-    }
-    .field-email {
-        margin-top: 0;
-        overflow: hidden;
-    }
-}
-
-//
-//  Order Address Information
-//  ---------------------------------------------
-
-.order-details {
-    .order-search-items {
-        .col-qty {
-            .admin__control-text {
-                &:extend(.abs-control-qty);
-            }
-        }
-    }
-
-    .admin__fieldset-wrapper:not(:last-child) {
-        margin-bottom: 5rem;
-    }
-
-    .admin__fieldset-wrapper-content {
-        &:extend(.abs-clearfix all);
-    }
-
-    .admin__fieldset-wrapper-title {
-        &:extend(.abs-clearfix all);
-        border-bottom: 1px solid @color-gray80;
-        margin-bottom: @order-create-sidebar__margin-reqular;
-        padding-bottom: @indent__xs;
-        .actions {
-            float: right;
-            margin-bottom: @order-create-sidebar__margin-reqular;
-            margin-top: -@indent__xs;
-        }
-        .action-secondary {
-            margin-left: @indent__base;
-        }
-        .title {
-            margin: 0;
-        }
-    }
-
-    .admin__legend {
-        &:extend(.abs-fieldset-legend all);
-    }
-
-    .admin__field {
-        &:extend(.abs-field-rows all);
-    }
-
-    .admin__field-option {
-        .admin__field-label {
-            display: block;
-            width: auto;
-        }
-    }
-}
-
-.field-vat-number {
-    .action-default {
-        &:extend(.action-tertiary all);
-        font-weight: @font-weight__regular;
-        margin-top: @indent__s;
-        padding: 0;
-    }
-}
-
-//
-//  Order Payment & Shipping Information
-//  ---------------------------------------------
-
-.order-methods {
-    .admin__field {
-        &:extend(.abs-field-rows all);
-    }
-    .admin__fieldset-wrapper-content {
-        .admin__fieldset-wrapper-title {
-            &:extend(.abs-fieldset-legend all);
-            border-bottom: 0;
-            margin-bottom: 1.5rem;
-            padding: 0;
-            strong {
-                font-weight: @font-weight__semibold;
-            }
-        }
-    }
-}
-
-.admin__payment-method-wapper {
-    margin: 0;
-    .admin__fieldset {
-        padding: 1.5rem 0 @indent__base @field-control-option-label__padding-left;
-    }
-    .admin__field {
-        &:last-child {
-            margin-bottom: 0;
-        }
-    }
-}
-
-.admin__order-shipment-methods-title {
-    font-weight: @font-weight__bold;
-    margin: 0 0 @indent__xs;
-}
-
-.admin__order-shipment-methods-options {
-    margin: 0 0 @indent__base;
-}
-
-.admin__order-shipment-methods-options-list {
-    list-style: none;
-    margin: 0;
-}
-
-.order-shipping-method-summary {
-    padding-top: @field-option__padding-top;
-}
-
-.order-shipping-method,
-.order-billing-method {
-    position: relative;
-}
-
-.order-shipping-method-summary,
-.order-shipping-method {
-    .action-default {
-        &:extend(.action-tertiary all);
-        font-weight: @font-weight__regular;
-        padding: 0;
-    }
-}
-
-.order-methods-overlay {
-    background: rgba(255, 255, 255, .5);
-    bottom: 0;
-    left: 0;
-    position: absolute;
-    right: 0;
-    top: 0;
-    span {
-        background: @color-white;
-        display: block;
-        font-weight: @font-weight__bold;
-        left: 0;
-        position: absolute;
-        top: 48px;
-    }
-    .order-shipping-address & {
-        span {
-            top: 27px;
-        }
-    }
-}
-
-//
-//  Order Errors
-//  ---------------------------------------------
-
-.order-errors {
-    .col-qty {
-        .admin__control-text {
-            &:extend(.abs-control-qty all);
-        }
-    }
-}
-
-//
-//  Gift options
-//  ---------------------------------------------
-
-.order-gift-options {
-    &:extend(.abs-clearfix all);
-    .card-price-box {
-        display: none;
-        &._active {
-            display: block;
-        }
-    }
-
-    .price-box {
-        .price {
-            font-weight: @font-weight__bold;
-        }
-    }
-
-    > .giftmessage-order-create {
-        float: left;
-        #mix-grid .width(6, 12);
-    }
-}
-
-.giftmessage-order-create {
-    .field-sender {
-        margin-top: 1.4rem;
-    }
-    .admin__field { // ToDo UI: remove when /app/code/Magento/Backend/view/adminhtml/templates/widget/form.phtml refactored (the wrapping div removed)
-        margin-bottom: 3rem;
-        position: relative;
-        + .admin__field {
-            margin-top: 1.5rem;
-        }
-    }
-}
-
-//
-//  Totals
-//  ---------------------------------------------
-
-.admin__table-secondary {
-    width: 100%;
-    td {
-        padding: .7rem @indent__s;
-    }
-    tr:nth-child(2n+1) td {
-        background-color: @color-white-fog2;
-    }
-    .admin__total-amount {
-        text-align: right;
-    }
-    tr:last-child td {
-        border-bottom: 1px solid @color-gray80;
-        padding-bottom: @indent__s;
-    }
-}
-
-.order-totals-actions {
-    margin-top: @indent__s;
-    .actions {
-        margin-top: @indent__l;
-        text-align: right;
-    }
-    .action-default {
-        &:extend(.abs-action-l all);
-    }
-}
-
-//  ToDo UI: review the collapsible block
-//.order-subtotal {
-//    .summary-collapse {
-//        cursor: pointer;
-//        display: inline-block;
-//        &:before {
-//            @iconsize: 16px;
-//
-//            background: #f2ebde;
-//            border: 1px solid #ada89e;
-//            border-radius: 2px;
-//            color: #816063;
-//            content: '+';
-//            display: inline-block;
-//            font-size: @iconsize;
-//            -webkit-font-smoothing: antialiased;
-//            font-style: normal;
-//            font-weight: normal;
-//            height: @iconsize;
-//            line-height: @iconsize;
-//            margin-right: 7px;
-//            overflow: hidden;
-//            speak: none;
-//            text-indent: 0;
-//            vertical-align: top;
-//            width: @iconsize;
-//        }
-//        &:hover:before {
-//            background: #cac3b4;
-//        }
-//    }
-//    &.show-details .summary-collapse:before {
-//        content: '\e03a';
-//    }
-//}
diff --git a/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/_order.less b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/_order.less
new file mode 100644
index 0000000000000000000000000000000000000000..2b4e2e6093170ca6345db320f4240256e67fa8ac
--- /dev/null
+++ b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/_order.less
@@ -0,0 +1,267 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Page components
+//  ---------------------------------------------
+
+@import 'order/_address.less';
+@import 'order/_discounts.less';
+@import 'order/_gift-options.less';
+@import 'order/_items.less';
+@import 'order/_order-account.less';
+@import 'order/_payment-shipping.less';
+@import 'order/_sidebar.less';
+@import 'order/_sku.less';
+@import 'order/_total.less';
+@import 'order/_order-comments.less';
+
+//
+//  Variables
+//  ---------------------------------------------
+
+@order-create-icon-refresh__font-size: 2rem;
+@order-create-icon-refresh__color: @color-gray83;
+@order-create-icon-refresh__hover__color: darken(@color-gray83, 10%);
+
+@order-create-icon-add__content: @icon-arrow-right__content;
+@order-create-icon-configure__content: @icon-systems__content;
+@order-create-icon-remove__content: @icon-delete__content;
+@order-create-icon-reset__content: @icon-remove-small__content;
+@order-create-icon-refresh__content: @icon-refresh__content;
+@order-create-icon-plus__content: @icon-plus__content;
+@order-create-icon-plus__hover__color: @color-very-dark-gray-black2;
+
+//
+//  Crosspage components
+//  _____________________________________________
+
+//
+//  Layout
+//  ---------------------------------------------
+
+.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
+    .order-details {
+        float: right;
+        #mix-grid .width(9,12);
+        margin-left: 0;
+    }
+    .order-sidebar {
+        #mix-grid .column(3,12);
+        margin-left: 0;
+    }
+
+    .order-billing-address,
+    .order-billing-method,
+    .order-history,
+    .order-information,
+    .order-payment-method,
+    .order-comments-history {
+        float: left;
+        #mix-grid .width(6,12);
+    }
+
+    .order-shipping-address,
+    .order-shipping-method,
+    .order-totals,
+    .order-view-account-information .order-account-information {
+        float: right;
+        #mix-grid .width(6,12);
+    }
+}
+
+.order-view {
+    > .ui-tabs-panel {
+        border: 0;
+        margin: 0;
+        padding: 0;
+    }
+}
+
+//
+//  Page sections
+//  ---------------------------------------------
+
+.admin__page-section {
+    margin-bottom: 5rem;
+
+    .admin__legend {
+        &:extend(.abs-fieldset-legend all);
+    }
+
+    .admin__field {
+        &:extend(.abs-field-rows all);
+    }
+
+    .admin__control-table-wrapper {
+        margin-top: @indent__base;
+    }
+
+    address {
+        font-style: normal;
+    }
+
+    .admin__table-secondary {
+        .admin__control-text {
+            width: 5.4rem;
+        }
+    }
+}
+
+.admin__page-section-title {
+    &:extend(.abs-clearfix all);
+    border-bottom: 1px solid @color-gray80;
+    margin-bottom: 1.7rem;
+    padding: 1.4rem 0 .5rem;
+    strong,
+    .title {
+        &:extend(h2);
+        float: left;
+        margin: 0;
+    }
+    .actions {
+        display: inline-block;
+        margin-left: @indent__xs;
+    }
+}
+
+.admin__page-section-content {
+    &:extend(.abs-clearfix all);
+}
+
+.admin__page-section-item-title,
+.admin__page-section-content .admin__page-section-title {
+    border-bottom: 0;
+    margin-bottom: 1.5rem;
+    padding: 0;
+    .title {
+        &:extend(.abs-fieldset-legend all);
+        margin: 0;
+    }
+    .actions {
+        display: inline-block;
+        margin-left: @indent__xs;
+    }
+}
+
+//
+//  Select Customer
+//  ---------------------------------------------
+
+.order-customer-selector {
+    .admin__page-section-title {
+        .title {
+            margin: 0 0 2rem;
+        }
+        .actions {
+            float: right;
+            margin-top: -.5rem;
+        }
+    }
+}
+
+//
+//  Select Store Scope
+//  ---------------------------------------------
+
+.tree-store-scope {
+    max-width: 50rem;
+    .admin__field {
+        margin: 0 0 1rem;
+    }
+}
+
+//
+//  Order Errors
+//  ---------------------------------------------
+
+.order-errors {
+    .col-qty {
+        .admin__control-text {
+            &:extend(.abs-control-qty all);
+        }
+    }
+}
+
+//
+//  Order Invoice
+//  ---------------------------------------------
+
+.order-invoice-tables {
+    &:extend(.abs-order-tables all);
+    &:extend(.abs-order-tbody-border all);
+}
+
+.abs-qty-table {
+    th,
+    td {
+        border: none;
+        font-weight: @font-weight__regular;
+        padding: 0 @order-create-sidebar__margin__s @order-create-sidebar__margin__s 0;
+    }
+}
+
+.abs-order-tbody-border {
+    tbody {
+        border-bottom: 1px solid @table-td__border-color;
+        &:last-of-type {
+            border-bottom: none;
+        }
+    }
+}
+
+
+//
+//  Product configure popup
+//  ---------------------------------------------
+
+.product-configure-popup {
+    .weee {
+        .price-excluding-tax,
+        .price-including-tax {
+            display: block;
+            font-size: 1.3rem;
+            &:before {
+                content: attr(data-label) ": ";
+            }
+        }
+    }
+}
+
+//  ToDo UI: review the collapsible block
+//.order-subtotal {
+//    .summary-collapse {
+//        cursor: pointer;
+//        display: inline-block;
+//        &:before {
+//            @iconsize: 16px;
+//
+//            background: #f2ebde;
+//            border: 1px solid #ada89e;
+//            border-radius: 2px;
+//            color: #816063;
+//            content: '+';
+//            display: inline-block;
+//            font-size: @iconsize;
+//            -webkit-font-smoothing: antialiased;
+//            font-style: normal;
+//            font-weight: normal;
+//            height: @iconsize;
+//            line-height: @iconsize;
+//            margin-right: 7px;
+//            overflow: hidden;
+//            speak: none;
+//            text-indent: 0;
+//            vertical-align: top;
+//            width: @iconsize;
+//        }
+//        &:hover:before {
+//            background: #cac3b4;
+//        }
+//    }
+//    &.show-details .summary-collapse:before {
+//        content: '\e03a';
+//    }
+//}
diff --git a/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_address.less b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_address.less
new file mode 100644
index 0000000000000000000000000000000000000000..0fdcfc2df388f9ca7c25a9d9ee78f1715a5dba1d
--- /dev/null
+++ b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_address.less
@@ -0,0 +1,49 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Order Address Information
+//  ---------------------------------------------
+
+.order-details {
+    .order-search-items {
+        .col-qty {
+            .admin__control-text {
+                &:extend(.abs-control-qty);
+            }
+        }
+    }
+
+    .order-items,
+    .order-search-items,
+    .order-additional-area {
+        .admin__page-section-title {
+            .actions {
+                float: right;
+                margin-bottom: @order-create-sidebar__margin__reqular;
+                margin-top: -.3rem;
+            }
+            .action-secondary {
+                margin-left: @indent__base;
+            }
+        }
+    }
+
+    .admin__field-option {
+        .admin__field-label {
+            display: block;
+            width: auto;
+        }
+    }
+}
+
+.field-vat-number {
+    .action-default {
+        &:extend(.action-tertiary all);
+        font-weight: @font-weight__regular;
+        margin-top: @indent__s;
+        padding: 0;
+    }
+}
diff --git a/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_discounts.less b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_discounts.less
new file mode 100644
index 0000000000000000000000000000000000000000..64b80e77823dc8ce8ea8931cc8a587b4d88e5266
--- /dev/null
+++ b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_discounts.less
@@ -0,0 +1,67 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Order discounts
+//  ---------------------------------------------
+
+.order-discounts {
+    &:extend(.abs-clearfix all);
+    margin-top: @indent__base;
+    .action-secondary {
+        float: right;
+        margin-top: 2.1rem;
+    }
+    .order-coupons {
+        float: left;
+    }
+    .admin__field {
+        display: inline-block;
+        margin: 0 3.5rem 0 0;
+        vertical-align: top;
+
+        .admin__field-control {
+            padding-right: 32px;
+            position: relative;
+        }
+
+        .action-default {
+            &:extend(.abs-action-reset all);
+            position: absolute;
+            right: 0;
+            top: 7px;
+            > span {
+                .extend__visually-hidden();
+            }
+
+            &:before {
+                &:extend(.abs-icon all);
+                content: @order-create-icon-add__content;
+            }
+
+            &:hover {
+                color: @order-create-icon-plus__hover__color;
+            }
+        }
+        p {
+            margin: @indent__s 0 0;
+        }
+    }
+    .action-remove {
+        color: @color-brownie;
+        margin-left: @indent__xs;
+        &:hover {
+            color: @order-create-icon-plus__hover__color;
+            text-decoration: none;
+        }
+        > span {
+            .extend__visually-hidden();
+        }
+        &:before {
+            &:extend(.abs-icon all);
+            content: @order-create-icon-remove__content;
+        }
+    }
+}
diff --git a/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_gift-options.less b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_gift-options.less
new file mode 100644
index 0000000000000000000000000000000000000000..4b88d1f0e57e1074965c264f8a80e69aa6c1ce23
--- /dev/null
+++ b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_gift-options.less
@@ -0,0 +1,58 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Gift options
+//  ---------------------------------------------
+
+.order-gift-options {
+    &:extend(.abs-clearfix all);
+    .card-price-box {
+        display: none;
+        &._active {
+            display: block;
+        }
+    }
+
+    .price-box {
+        .price {
+            font-weight: @font-weight__bold;
+        }
+    }
+
+    > .giftmessage-order-create {
+        float: left;
+        #mix-grid .width(6, 12);
+    }
+
+    .admin__field {
+        &._required[class] {
+            &:not(.admin__field-option) {
+                > .admin__field-label span {
+                    &:after {
+                        margin-left: 0;
+                    }
+                }
+            }
+        }
+    }
+}
+
+.giftmessage-order-create {
+    .field-sender {
+        margin-top: 1.4rem;
+    }
+    .admin__field { // ToDo UI: remove when /app/code/Magento/Backend/view/adminhtml/templates/widget/form.phtml refactored (the wrapping div removed)
+        margin-bottom: 3rem;
+        position: relative;
+        + .admin__field {
+            margin-top: 1.5rem;
+        }
+    }
+}
+
+.gift-options-tooltip {
+    &:extend(.abs-admin__field-tooltip-content all);
+}
diff --git a/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_items.less b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_items.less
new file mode 100644
index 0000000000000000000000000000000000000000..0f621df99f43c72b37991106eaab7880ac6868a7
--- /dev/null
+++ b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_items.less
@@ -0,0 +1,124 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Variables
+//  ---------------------------------------------
+
+@order-create-table__border-color: @table-td__border-color;
+@order-create-sku__background: @admin__page-nav__background-color;
+@order-create-sku__padding: @indent__base;
+@order-create-sku-table__border-color: @color-white;
+
+//
+//  Table
+//  ---------------------------------------------
+
+.order-tables {
+    &:extend(.abs-order-tables all);
+    &:extend(.abs-order-tbody-border all);
+}
+
+.order-items {
+    > .admin__page-section-title {
+        margin: 0;
+    }
+    .actions-update {
+        margin: @indent__base 0;
+        text-align: right;
+    }
+}
+
+.order-search-items {
+    .grid {
+        .action-configure {
+            float: right;
+        }
+        .col-id,
+        .col-price,
+        .col-in_products {
+            width: 10rem;
+        }
+    }
+}
+
+.abs-order-tables {
+    margin: 0 0 @order-create-sidebar__margin__reqular;
+    width: 100%;
+    th {
+        border-top: 0;
+        font-size: 1.3rem;
+    }
+    td {
+        border-bottom: none;
+    }
+    tbody {
+        tr {
+            &.row-messages-error,
+            &.row-gift-options {
+                td {
+                    padding-top: 0;
+                }
+            }
+        }
+    }
+    tfoot {
+        td {
+            border-bottom: 1px solid @order-create-table__border-color;
+            border-top: none;
+        }
+    }
+    .col-qty,
+    .col-qty-invoice {
+        .admin__control-text {
+            &:extend(.abs-control-qty all);
+        }
+    }
+    .qty-table {
+        &:extend(.abs-qty-table all);
+    }
+    .col-actions {
+        .admin__control-select {
+            width: 13rem;
+        }
+    }
+    .price {
+        display: inline-block;
+        margin: 0 0 @order-create-sidebar__margin__s;
+    }
+    .item-options {
+        &:extend(.abs-clearfix all);
+        margin: @order-create-sidebar__margin__m 0 0;
+        dt {
+            clear: left;
+            float: left;
+            margin: 0 @order-create-sidebar__margin__s @order-create-sidebar__margin__s 0;
+        }
+        dd {
+            display: inline-block;
+            float: left;
+            margin: 0 0 @order-create-sidebar__margin__s;
+        }
+    }
+    .custom-price-block {
+        font-size: @order-create-sidebar__font-size__xs;
+        margin: 0 0 @order-create-sidebar__margin__s;
+        + .admin__control-text {
+            &:extend(.abs-control-price);
+        }
+    }
+    .discount-price-block {
+        font-size: @order-create-sidebar__font-size__xs;
+    }
+    .product-configure-block {
+        margin: @indent__s 0 0;
+        .disabled {
+            display: none;
+        }
+    }
+    .product-sku-block {
+        margin: @indent__s 0 0;
+    }
+}
diff --git a/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_order-account.less b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_order-account.less
new file mode 100644
index 0000000000000000000000000000000000000000..a0cf2a04230c41c2028b05acffb070e3f6f3dd1e
--- /dev/null
+++ b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_order-account.less
@@ -0,0 +1,24 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Order Account Information
+//  ---------------------------------------------
+
+.order-account-information {
+    .admin__fieldset {
+        &:extend(.abs-clearfix all);
+    }
+    .admin__field {
+        margin-bottom: 0;
+    }
+    .field-group_id {
+        float: left;
+    }
+    .field-email {
+        margin-top: 0;
+        overflow: hidden;
+    }
+}
diff --git a/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_order-comments.less b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_order-comments.less
new file mode 100644
index 0000000000000000000000000000000000000000..675a02272c8cf1199ab008e1e454ce58cfa3e144
--- /dev/null
+++ b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_order-comments.less
@@ -0,0 +1,58 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Edit Order comments
+//  ---------------------------------------------
+
+.edit-order-comments {
+    .note-list {
+        font-size: @edit-order-comment-notes__font-size;
+        list-style: none;
+        margin: 0 0 @order-create-sidebar__margin;
+    }
+    .note-list-item {
+        margin: 0 0 @order-create-sidebar__margin__s;
+    }
+    .note-list-date,
+    .note-list-time {
+        padding: 0 @order-create-sidebar__margin__m 0 0;
+    }
+    .note-list-status,
+    .note-list-customer {
+        border-left: 1px solid @edit-order-comment-notes__border-color;
+        padding: 0 @order-create-sidebar__margin__m;
+    }
+    .note-list-customer-notapplicable,
+    .note-list-customer-not-notified,
+    .note-list-customer-notified {
+        font-weight: @font-weight__bold;
+        padding: 0 @order-create-sidebar__margin__m 0 0;
+    }
+    .note-list-comment {
+        margin: 0 0 @order-create-sidebar__margin__reqular;
+    }
+    .comments-block-item {
+        margin: 0 0 @order-create-sidebar__margin;
+    }
+    .comments-block-item-comment {
+        margin: 0 0 @order-create-sidebar__margin__s;
+    }
+    .comments-block-item-date-time {
+        font-size: @font-size__tiny;
+    }
+}
+
+.edit-order-comments-block-title {
+    margin: 0 0 @order-create-sidebar__margin;
+    .typography(
+    @_font-size: 1.9rem,
+    @_color: @color-brown-darkie,
+    @_font-weight: @font-weight__semibold,
+    @_line-height: @line-height__s,
+    @_font-family: false,
+    @_font-style: false
+    );
+}
diff --git a/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_payment-shipping.less b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_payment-shipping.less
new file mode 100644
index 0000000000000000000000000000000000000000..fe3ebac483461cb7bd0f7899d679e2808a5dfb5b
--- /dev/null
+++ b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_payment-shipping.less
@@ -0,0 +1,91 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Order Payment & Shipping Information
+//  ---------------------------------------------
+
+.admin__payment-method-wapper {
+    margin: 0;
+    .admin__field {
+        margin-left: -4rem;
+        &:first-child {
+            margin-top: 1.5rem;
+        }
+    }
+    .admin__payment-methods {
+        margin: 0;
+    }
+}
+
+.admin__order-shipment-methods-title {
+    font-weight: @font-weight__bold;
+    margin: 0 0 @indent__xs;
+}
+
+.admin__order-shipment-methods-options {
+    margin: 0 0 @indent__base;
+}
+
+.admin__order-shipment-methods-options-list {
+    list-style: none;
+    margin: 0;
+}
+
+.order-shipping-method-summary {
+    padding-top: @field-option__padding-top;
+}
+
+.order-shipping-method,
+.order-billing-method {
+    position: relative;
+}
+
+.order-shipping-method-summary,
+.order-shipping-method-info {
+    .action-default {
+        &:extend(.action-tertiary all);
+        font-weight: @font-weight__regular;
+        padding: 0;
+    }
+}
+
+.order-methods-overlay {
+    background-color: rgba(255, 255, 255, .5);
+    bottom: 0;
+    left: 0;
+    position: absolute;
+    right: 0;
+    top: 0;
+    span {
+        background-color: @color-white;
+        display: block;
+        font-weight: @font-weight__bold;
+        left: 0;
+        padding: @indent__xs 0;
+        position: absolute;
+        top: 43px;
+    }
+    .order-shipping-address & {
+        span {
+            top: 22px;
+        }
+    }
+}
+
+.shipping-description-wrapper {
+    .price {
+        font-weight: @font-weight__bold;
+    }
+}
+
+.order-payment-method-title,
+.shipping-description-title {
+    font-weight: @font-weight__bold;
+}
+
+.action-create-label {
+    margin: @indent__s 0;
+}
diff --git a/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/_order-create-sidebar.less b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_sidebar.less
similarity index 88%
rename from app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/_order-create-sidebar.less
rename to app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_sidebar.less
index 6bdd17f7f4d18eae84eba64d3fe9e1b5cdbcfb20..8ef7ff03c7c529c3e4ad388073672207a1917107 100644
--- a/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/_order-create-sidebar.less
+++ b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_sidebar.less
@@ -8,19 +8,17 @@
 //  ---------------------------------------------
 
 @order-create-sidebar__font-size: 1.5rem;
-@order-create-sidebar__font-size-xs: 1.1rem;
+@order-create-sidebar__font-size__xs: 1.1rem;
 @order-create-sidebar__color: @color-very-dark-gray;
 @order-create-sidebar__margin: 2.4rem;
 @order-create-sidebar__padding: @indent__base;
-@order-create-sidebar__margin-small: .5rem;
-@order-create-sidebar__margin-m: 1rem;
-@order-create-sidebar__margin-reqular: 1.7rem;
+@order-create-sidebar__margin__s: .5rem;
+@order-create-sidebar__margin__m: 1rem;
+@order-create-sidebar__margin__reqular: 1.7rem;
 @order-create-sidebar__border-color: @border__color;
 
 @order-create-sidebar-scroll__height: 24rem;
 
-//
-
 //
 //  Order Sidebar
 //  ---------------------------------------------
@@ -47,7 +45,7 @@
         padding: 0 0 @order-create-sidebar__margin;
     }
     .admin__control-select {
-        margin: 0 0 @order-create-sidebar__margin-small;
+        margin: 0 0 @order-create-sidebar__margin__s;
         width: 100%;
     }
     .order-sidebar-block {
@@ -55,7 +53,7 @@
         margin: 0 0 @order-create-sidebar__margin;
         padding: 0 0 @order-create-sidebar__margin;
     }
-    .table-info {
+    .admin__table-primary {
         color: @order-create-sidebar__color;
         width: 100%;
         th,
@@ -102,7 +100,7 @@
             text-align: right;
             .icon-configure,
             .icon-add {
-                margin-right: @order-create-sidebar__margin-m;
+                margin-right: @order-create-sidebar__margin__m;
             }
         }
     }
@@ -110,7 +108,7 @@
         &:extend(.abs-icon all);
         display: table-cell;
         font-size: @order-create-icon-refresh__font-size;
-        padding-right: @order-create-sidebar__margin-m;
+        padding-right: @order-create-sidebar__margin__m;
         vertical-align: middle;
         &:after {
             color: @order-create-icon-refresh__color;
@@ -127,16 +125,16 @@
         }
     }
     .create-order-sidebar-block {
-        .head {
+        .sidebar-title-block {
             margin: 0 0 @order-create-sidebar__margin;
         }
         .auto-scroll {
-            margin: 0 -@order-create-sidebar__padding @order-create-sidebar__margin-small;
+            margin: 0 -@order-create-sidebar__padding @order-create-sidebar__margin__s;
             max-height: @order-create-sidebar-scroll__height;
             overflow: auto;
             position: relative;
             + .action-default {
-                margin-top: @order-create-sidebar__margin-reqular;
+                margin-top: @order-create-sidebar__margin__reqular;
             }
             .no-items {
                 padding-left: @order-create-sidebar__padding;
@@ -153,7 +151,7 @@
         margin: 0;
         vertical-align: middle;
         + .admin__control-select {
-            margin-top: @order-create-sidebar__margin-reqular;
+            margin-top: @order-create-sidebar__margin__reqular;
         }
     }
     .actions {
diff --git a/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_sku.less b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_sku.less
new file mode 100644
index 0000000000000000000000000000000000000000..68b25e5aa12ae0ad94526499174c2418ed3a5413
--- /dev/null
+++ b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_sku.less
@@ -0,0 +1,45 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Add by SKU
+//  ---------------------------------------------
+
+.add-by-sku-wrapper {
+    .add-by-sku {
+        margin: 0 0 @indent__base;
+    }
+    .admin__field-note {
+        margin: 1.4rem 0;
+    }
+    .action-reset {
+        &:extend(.abs-action-reset all);
+        &:extend(.abs-icon all);
+        display: inline-block;
+        font-size: 1.6rem;
+        margin: -.4rem 0 0;
+        opacity: .5;
+        vertical-align: middle;
+        &:after {
+            color: @order-create-icon-reset__content;
+            content: @order-create-icon-reset__content;
+        }
+        &:hover {
+            opacity: 1;
+            &:after {
+                color: @order-create-icon-plus__hover__color;
+            }
+        }
+        > span {
+            &:extend(.abs-visually-hidden all);
+        }
+    }
+    .col-qty {
+        width: 8rem;
+        .admin__control-text {
+            &:extend(.abs-control-qty all);
+        }
+    }
+}
diff --git a/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_total.less b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_total.less
new file mode 100644
index 0000000000000000000000000000000000000000..699576bde84c70e2645fbe07475fbe915afca647
--- /dev/null
+++ b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_total.less
@@ -0,0 +1,19 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Totals
+//  ---------------------------------------------
+
+.order-totals-actions {
+    margin-top: @indent__s;
+    .actions {
+        margin-top: @indent__l;
+        text-align: right;
+    }
+    .action-default {
+        &:extend(.abs-action-l all);
+    }
+}
diff --git a/app/design/adminhtml/Magento/backend/Magento_Shipping/web/css/source/_module.less b/app/design/adminhtml/Magento/backend/Magento_Shipping/web/css/source/_module.less
new file mode 100644
index 0000000000000000000000000000000000000000..c1ff50783ee7816d1751695366462a40901c383a
--- /dev/null
+++ b/app/design/adminhtml/Magento/backend/Magento_Shipping/web/css/source/_module.less
@@ -0,0 +1,114 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Order Shipment
+//  ---------------------------------------------
+
+.order-shipment-table {
+    &:extend(.abs-order-tables all);
+    &:extend(.abs-order-tbody-border all);
+}
+
+//
+//  Packaging for Shipping Popup
+// --------------------------------------
+
+//  ToDo UI: refactor the popup to jQuery UI, edit the styles
+.packaging-window {
+    background: @color-white;
+    box-shadow: 0 3px 6px rgba(0, 0, 0, .4);
+    left: 50%;
+    margin: -20rem 0 0 -47rem;
+    position: fixed;
+    top: 50%;
+    width: 100rem;
+    z-index: 1000;
+    .message-warning {
+        margin: 0 0 @indent__s;
+    }
+    .admin__control-select {
+        width: 13rem;
+        &.measures {
+            width: 9rem;
+        }
+    }
+    .packaging-content {
+        height: auto !important;
+        max-height: 40rem;
+        overflow-x: hidden;
+        overflow: auto;
+        padding: @indent__base @indent__base 0;
+        position: relative;
+        .options-weight {
+            vertical-align: top;
+        }
+    }
+    .popup-window-title {
+        &:extend(.abs-clearfix all);
+        padding: @indent__base;
+        .title {
+            font-size: 1.9rem;
+            display: block;
+        }
+        .actions {
+            float: right;
+        }
+    }
+    .popup-fieldset-title {
+        &:extend(.abs-clearfix all);
+        .title {
+            display: block;
+            font-weight: 700;
+            padding-top: @indent__s;
+        }
+        .actions {
+            float: right;
+        }
+        margin: 0 0 @indent__base;
+    }
+    .popup-window-buttons-set {
+        padding: @indent__base;
+        text-align: right;
+    }
+    .package-add-products {
+        margin: @indent__base 0 0;
+        .grid {
+            padding: 0;
+            button {
+                vertical-align: middle;
+            }
+        }
+    }
+    .col-total-weight {
+        .admin__control-text {
+            margin: 0 0 .5rem;
+        }
+    }
+    .col-qty-edit {
+        .admin__control-text {
+            &:extend(.abs-control-qty all);
+        }
+    }
+    .col-actions {
+        width: 13rem;
+        .action-delete {
+            padding-top: 0;
+        }
+    }
+    .admin__table-primary {
+        .action-delete {
+            margin-top: -.7rem;
+            padding: 0;
+            &:extend(.abs-action-delete all);
+        }
+    }
+    .action-secondary {
+        float: right;
+    }
+    .action-close {
+        &:extend(.abs-action-tertiary all);
+    }
+}
diff --git a/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/_module.less b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/_module.less
new file mode 100644
index 0000000000000000000000000000000000000000..6ab7104603ae2c6e9a7f1bfbbe30ef029520c508
--- /dev/null
+++ b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/_module.less
@@ -0,0 +1,6 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+@import 'module/_data-grid.less';
diff --git a/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module.less b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module.less
index 6d1cdd4c54a3d3db423a4740e016c242f7fd7e84..3e1c86ab7f8b8dbd8cd4cbcecc88cf50ae9d5af0 100644
--- a/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module.less
+++ b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module.less
@@ -3,13 +3,15 @@
 //  * See COPYING.txt for license details.
 //  */
 
-//colors
+//
+//  Variables
+//  ---------------------------------------------
+
 @admin__color1: #adadad;
 @admin__color2: #d3d3d3;
 @admin__color3: #e0e0e0;
 @admin__color4: #666;
 
-//Spacing
 @spacing__base: 10px;
 @spacing-xs: @spacing__base;
 @spacing-s: @spacing__base;
@@ -17,7 +19,6 @@
 @spacing-l: @spacing__base;
 @spacing-xl: @spacing__base;
 
-//Fonts
 @size__base: 1rem;
 @size-xs: @size__base;
 @size-s: @size__base;
@@ -27,6 +28,8 @@
 
 @field-date-icon--color: #514943;
 
+//
+
 [class*="tab-nav-item"]:not(ul):active,
 [class*="tab-nav-item"]:not(ul):focus {
     box-shadow: none;
@@ -125,53 +128,51 @@
 }
 
 .listing-tiles {
-  overflow: hidden;
-  margin-top: -10px;
-  margin-left: -10px;
-
-  .listing-tile {
-    background-color: #f2ebde;
-    display: block;
-    width: 238px;
-    height: 200px;
-    float: left;
-    border: 1px solid #676056;
-    margin-top: 10px;
-    margin-left: 10px;
-    border-radius: 4px;
-    text-align: center;
-
-    &.disabled {
-      border-color: red;
-    }
+    overflow: hidden;
+    margin-top: -10px;
+    margin-left: -10px;
+
+    .listing-tile {
+        background-color: #f2ebde;
+        display: block;
+        width: 238px;
+        height: 200px;
+        float: left;
+        border: 1px solid #676056;
+        margin-top: 10px;
+        margin-left: 10px;
+        border-radius: 4px;
+        text-align: center;
+
+        &.disabled {
+            border-color: red;
+        }
 
-    &.enabled {
-      border-color: green;
+        &.enabled {
+            border-color: green;
+        }
     }
-  }
 }
 
 .listing {
-  .disabled {
-    color: red;
-  }
-  .enabled {
-    color: green;
-  }
+    .disabled {
+        color: red;
+    }
+    .enabled {
+        color: green;
+    }
 }
 
 .pager {
     text-align: left;
     padding-bottom: 10px;
     .clearfix();
-
     [data-part=left] {
         display: inline-block;
         width: 45%;
         float: left;
         text-align: left;
     }
-
     [data-part=right] {
         display: inline-block;
         width: 45%;
@@ -182,44 +183,30 @@
         -ms-user-select: none; // use in 11 IE
         user-select: none;
     }
-
-    .action-next{
+    .action-next {
         cursor: pointer;
     }
-
-    .action-previous{
+    .action-previous {
         cursor: pointer;
     }
 }
 
-.pager {
-  text-align: left;
-}
-.pager [data-part=left] {
-  display: inline-block;
-  width: 45%;
-  text-align: left;
-}
-.pager [data-part=right] {
-  display: inline-block;
-  width: 45%;
-  text-align: right;
-  float: right;
-}
-.grid .col-title {
-  min-width: 90px;
-  text-align: center;
-}
-.grid-actions [data-part=search] {
-  display: inline-block;
-  margin: 0 30px;
-}
-.grid-actions [data-part=search] input[type=text] {
-  vertical-align: bottom;
-  width: 460px;
+.grid-actions {
+    [data-part=search] {
+        display: inline-block;
+        margin: 0 30px;
+        input[type=text] {
+            vertical-align: bottom;
+            width: 460px;
+        }
+    }
 }
 
 .grid {
+    .col-title {
+        min-width: 90px;
+        text-align: center;
+    }
     .actions-split {
         .clearfix();
         display: inline-block;
@@ -292,274 +279,6 @@
     }
 }
 
-.filters {
-    &-toggle {
-        .button(
-            @_button-margin: 3px,
-            @_button-icon-use: true,
-            @_button-font-content: @icon-pointer-down,
-            @_button-icon-font-size: 30px,
-            @_button-icon-font-line-height: 15px,
-            @_button-icon-font-text-hide: false,
-            @_button-icon-font-position: after
-        );
-        .button-reset();
-        &:after {
-            margin-top: 2px;
-            margin-left: -3px;
-        }
-        &.active {
-            &:after {
-                content: @icon-pointer-up;
-            }
-        }
-    }
-    &-current {
-        padding: 10px 0;
-        display: none;
-        &.active{
-            display: block;
-        }
-    }
-    &-items {
-        .list-reset-styles();
-        display: inline;
-    }
-    &-item {
-        display: inline-block;
-        margin:0 5px 5px 0;
-        padding: 2px 2px 2px 4px;
-        border-radius: 3px;
-        background: #f7f3eb;
-        .item-label {
-            font-weight: 600;
-            &:after {
-                content: ": "
-            }
-        }
-        .action-remove {
-            .button(
-                @_button-margin: 3px,
-                @_button-icon-use: true,
-                @_button-font-content: @icon-remove,
-                @_button-icon-font-size: 16px,
-                @_button-icon-font-line-height: 16px,
-                @_button-icon-font-text-hide: true
-            );
-            padding: 0;
-            //.button-reset();
-        }
-    }
-    &-form {
-        position: relative;
-        z-index: 1;
-        margin: 14px 0;
-        background: #fff;
-        border: 1px solid #bbb;
-        box-shadow: 0 3px 3px rgba(0, 0, 0, .15);
-        .action-close {
-            position: absolute;
-            top: 3px;
-            right: 7px;
-            .button(
-                @_button-margin: 3px,
-                @_button-icon-use: true,
-                @_button-font-content: @icon-remove,
-                @_button-icon-font-size: 42px,
-                @_button-icon-font-line-height: 42px,
-                @_button-icon-font-text-hide: true
-            );
-            .button-reset();
-        }
-    }
-    &-actions {
-        margin: 18px;
-        text-align: right;
-    }
-    &-fieldset {
-        padding-bottom: 0;
-        .field {
-            border: 0;
-            .form-field(
-                    @_type: inline,
-                    @_column: true,
-                    @_column-number: 3,
-                    @_type-inline-label-width: 35%,
-                    @_type-inline-control-width: 65%
-                );
-            .label {
-                .style2();
-                margin: 0;
-            }
-        }
-    }
-    .field-date .group {
-        .hasDatepicker {
-          width: 100%;
-          padding-right: 30px;
-
-          & + .ui-datepicker-trigger {
-              img {
-                  display: none;
-              }
-              .button-reset();
-              .icon-font(
-                  @icon-calendar,
-                  @_icon-font-size: 35px,
-                  @_icon-font-line-height: 30px,
-                  @_icon-font-text-hide: true,
-                  @_icon-font-position: after,
-                  @_icon-font-color: @field-date-icon--color
-              );
-              margin-left: -33px;
-              display: inline-block;
-              width: 30px;
-          }
-        }
-    }
-    .field-range .group{
-        .field {
-            margin-bottom: 0;
-        }
-        .label {
-            &:extend(.visually-hidden all);
-        }
-        .control {
-            width: 100%;
-            box-sizing: border-box;
-            padding-right: 0;
-            position: relative;
-            z-index: 1;
-        }
-    }
-
-}
-
-/* [data-part=filter-form] {
-  width: 650px;
-  left: 150px;
-
-  background: #fff;
-  border: 1px solid #bbb;
-  position: absolute;
-  z-index: 100;
-  box-shadow: 0 3px 3px rgba(0, 0, 0, .15);
-  margin-top: 4px;
-
-  .title {
-    position: relative;
-    padding: 5px 18px;
-
-    .close {
-      position: absolute;
-      font-size: .8em;
-      right: 10px;
-      top: 12px;
-      cursor: pointer;
-
-      &:hover,
-      &:active {
-        text-decoration: underline;
-      }
-    }
-  }
-
-  > .actions {
-    padding: 5px 18px 36px;
-  }
-} */
-
-.mass-select {
-    position: relative;
-    margin: -6px -10px;
-    padding: 6px 2px 6px 10px;
-    z-index: 1;
-    white-space: nowrap;
-    &.active {
-        background: rgba(0,0,0,.2);
-    }
-    &-toggle {
-        .button(
-            @_button-margin: 3px,
-            @_button-icon-use: true,
-            @_button-font-content: @icon-pointer-down,
-            @_button-icon-font-size: 30px,
-            @_button-icon-font-line-height: 15px,
-            @_button-icon-font-text-hide: true
-        );
-        .button-reset();
-        &:before {
-            margin-top: -2px;
-            text-indent: -5px;
-            color: #fff;
-        }
-        &:hover:before {
-            color: #fff;
-        }
-        &:active,
-        &.active {
-            &:before {
-                content: @icon-pointer-up;
-            }
-        }
-    }
-    &-field {
-        .label {
-            &:extend(.visually-hidden all);
-        }
-        display: inline;
-    }
-    &-menu {
-        display: none;
-        position: absolute; top: 100%; left: 0;
-        text-align: left;
-        .list-reset-styles();
-        background: #fff;
-        border: 1px solid #bbb;
-        min-width: 175px;
-        box-shadow: 0 3px 3px rgba(0, 0, 0, .15);
-        li {
-          margin: 0;
-          padding: 4px 15px;
-          border-bottom: 1px solid #e5e5e5;
-        }
-        li:hover {
-          background: #e8e8e8;
-          cursor: pointer;
-        }
-        span {
-            font-weight: normal;
-            font-size: 13px;
-            color: #645d53;
-        }
-        &.active {
-            display: block;
-        }
-    }
-}
-
-.grid-loading-mask{
-    position: absolute;
-    left: 0;
-    top: 0;
-    right: 0;
-    bottom: 0;
-    background: rgba(255, 255, 255, .5);
-    z-index: 100;
-
-    .grid-loader{
-        position: absolute;
-        margin: auto;
-        left: 0;
-        top: 0;
-        right: 0;
-        bottom: 0;
-        width: 218px;
-        height: 149px;
-        background: url('@{baseDir}images/loader-2.gif') 50% 50% no-repeat;
-    }
-}
-
 //
 // Form Component
 //
@@ -581,20 +300,20 @@
 }
 
 .field-price.addon {
-  direction: rtl;
+    direction: rtl;
 }
 
 .field-price.addon > * {
-  direction: ltr;
+    direction: ltr;
 }
 
 .field-price.addon .addafter {
-  border-width: 1px 0 1px 1px;
-  border-radius: 2px 0 0 2px;
+    border-width: 1px 0 1px 1px;
+    border-radius: 2px 0 0 2px;
 }
 
 .field-price.addon input:first-child {
-  border-radius: 0 2px 2px 0;
+    border-radius: 0 2px 2px 0;
 }
 
 .field-price input[type="text"] {
@@ -602,21 +321,21 @@
 }
 
 .field-price input ~ label.addafter strong {
-  margin-left: 2px;
-  margin-right: -2px;
+    margin-left: 2px;
+    margin-right: -2px;
 }
 
 .field-price.addon > input {
-  width: 99px;
-  float: left;
+    width: 99px;
+    float: left;
 }
 
 .field-price .control {
-  position: relative;
+    position: relative;
 }
 
 .field-price label.mage-error {
-  position: absolute;
-  left: 0;
-  top: 30px;
+    position: absolute;
+    left: 0;
+    top: 30px;
 }
diff --git a/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/_data-grid.less b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/_data-grid.less
new file mode 100644
index 0000000000000000000000000000000000000000..d01685e141655100c6a45d8a9115fcf4ae3d7abf
--- /dev/null
+++ b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/_data-grid.less
@@ -0,0 +1,313 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  UI -> Data Grid
+//  _____________________________________________
+
+//
+//  Components
+//  ---------------------------------------------
+
+@import 'data-grid/_data-grid-header.less';
+
+//
+//  Variables
+//  ---------------------------------------------
+
+@data-grid__font-size: 1.3rem;
+
+@data-grid-tr__active__background-color: @action__hover__background-color;
+@data-grid-tr__hover__background-color: lighten(@action__hover__background-color, 1%);
+
+@data-grid-cell__border-width: .1rem;
+@data-grid-cell__padding-horizontal: 1rem;
+@data-grid-cell__padding-vertical: 1rem;
+
+@data-grid-td__border-color: @color-gray84;
+@data-grid-td__border-inner-style: dashed;
+@data-grid-td__border-outer-style: solid;
+@data-grid-td__even__background-color: @color-white-smoke;
+@data-grid-td__odd__background-color: @page__background-color;
+
+@data-grid-th__border-color: @color-darkie-gray;
+@data-grid-th__border-style: solid;
+@data-grid-th__background-color: @color-brownie;
+@data-grid-th__color: @color-white;
+@data-grid-th__padding-horizontal: @data-grid-cell__padding-horizontal;
+@data-grid-th__padding-vertical: @data-grid-cell__padding-vertical;
+@data-grid-th__hover__background-color: lighten(@data-grid-th__background-color, 5%);
+
+@data-grid-th-marker__width: .7rem;
+
+@data-grid-checkbox-cell-inner__padding-top: 1.1rem;
+@data-grid-checkbox-cell-inner__padding-horizontal: 1.8rem;
+
+@data-grid-row-parent-marker__size: 1rem;
+
+//
+
+.admin__data-grid-wrap {
+    padding-top: 0;
+    position: relative;
+}
+
+.admin__data-grid-loading-mask {
+    background: rgba(255, 255, 255, .5);
+    bottom: 0;
+    left: 0;
+    right: 0;
+    top: 0;
+    position: absolute;
+    z-index: @overlay__z-index;
+
+    .grid-loader {
+        background: url('@{baseDir}images/loader-2.gif') 50% 50% no-repeat;
+        bottom: 0;
+        height: 149px;
+        left: 0;
+        margin: auto;
+        position: absolute;
+        right: 0;
+        top: 0;
+        width: 218px;
+    }
+}
+
+.data-grid {
+    border-bottom: @data-grid-cell__border-width @data-grid-td__border-outer-style @data-grid-td__border-color;
+    border-left: none;
+    border-right: none;
+    border-top: none;
+    font-size: @data-grid__font-size;
+    margin-bottom: 2rem;
+    max-width: 100%;
+    width: 100%;
+    thead {
+        background-color: transparent; // ToDo UI: Rewrite old styles. Should be deleted afterwards
+        color: @text__color; // ToDo UI: Rewrite old styles. Should be deleted afterwards
+    }
+    tr {
+        &:nth-child(even) {
+            td {
+                background-color: @data-grid-td__even__background-color;
+            }
+        }
+        &:active {
+            td {
+                background-color: @data-grid-tr__active__background-color;
+            }
+        }
+        &:hover {
+            td {
+                background-color: @data-grid-tr__hover__background-color;
+                cursor: pointer;
+            }
+        }
+        &.data-grid-tr-no-data {
+            &:hover {
+                td {
+                    cursor: default;
+                    background-color: @data-grid-td__odd__background-color;
+                }
+            }
+        }
+    }
+    th,
+    td {
+        font-size: @data-grid__font-size; // ToDo UI: Rewrite old styles. Should be deleted afterwards
+        line-height: @line-height__base;
+        transition: @smooth__background-color;
+        vertical-align: top;
+    }
+    td {
+        background-color: @data-grid-td__odd__background-color;
+        border-left: @data-grid-cell__border-width @data-grid-td__border-inner-style @data-grid-td__border-color;
+        border-right: @data-grid-cell__border-width @data-grid-td__border-inner-style @data-grid-td__border-color;
+        color: @table__color;
+        padding: @data-grid-cell__padding-vertical @data-grid-cell__padding-horizontal;
+        &:first-child {
+            border-left-style: @data-grid-td__border-outer-style;
+        }
+        &:last-child {
+            border-right-style: @data-grid-td__border-outer-style;
+        }
+        //  Action select data grid styles (can be action-select-secondary in future)
+        .action-select {
+            .link-pattern();
+            background-color: transparent;
+            border: none;
+            font-size: @data-grid__font-size;
+            padding: 0 3rem 0 0;
+            &:hover {
+                &:after {
+                    border-color: @link__hover__color transparent transparent transparent;
+                }
+            }
+            &:after {
+                border-color: @link__color transparent transparent transparent;
+            }
+            &:before {
+                display: none;
+            }
+        }
+        .action-menu {
+            left: auto;
+            z-index: 1;
+        }
+    }
+    th {
+        background-color: @data-grid-th__background-color;
+        border: @data-grid-cell__border-width @data-grid-th__border-style @data-grid-th__border-color;
+        border-left-color: transparent;
+        color: @data-grid-th__color;
+        font-weight: @font-weight__semibold;
+        padding: 0;
+        text-align: left;
+        &:first-child {
+            border-left-color: @data-grid-th__border-color;
+        }
+    }
+    .data-grid-th {
+        color: @data-grid-th__color;
+        padding: @data-grid-th__padding-vertical @data-grid-th__padding-horizontal;
+        &._sortable {
+            cursor: pointer;
+            padding-right: @data-grid-th__padding-horizontal * 2 + @data-grid-th-marker__width;
+            position: relative;
+            transition: @smooth__background-color;
+            &:focus,
+            &:hover {
+                background-color: @data-grid-th__hover__background-color;
+            }
+            &:active {
+                padding-bottom: @data-grid-th__padding-vertical - .1rem;
+                padding-top: @data-grid-th__padding-vertical + .1rem;
+            }
+        }
+    }
+    .data-grid-checkbox-cell {
+        padding: 0;
+        &:hover {
+            cursor: default;
+        }
+    }
+    .data-grid-multiselect-cell {
+        padding: @data-grid-th__padding-horizontal @data-grid-th__padding-vertical @data-grid-th__padding-horizontal - .1rem;
+        text-align: center;
+        width: @control-checkbox-radio__size + @data-grid-checkbox-cell-inner__padding-horizontal * 2;
+    }
+    .data-grid-actions-cell {
+        padding-left: @data-grid-cell__padding-horizontal * 2;
+        padding-right: @data-grid-cell__padding-horizontal * 2;
+        width: 1%;
+    }
+    //  Nested rows
+    .data-grid-row-parent {
+        &._active {
+            > td {
+                background-color: @color-lazy-sunny;
+                border-bottom: @data-grid-cell__border-width @data-grid-td__border-outer-style @data-grid-td__border-color;
+                border-left-color: transparent;
+                border-right-color: transparent;
+                border-top: @data-grid-cell__border-width @data-grid-td__border-outer-style @data-grid-td__border-color;
+                &:first-child {
+                    border-left-color: @data-grid-td__border-color;
+                }
+                &:last-child {
+                    border-right-color: @data-grid-td__border-color;
+                }
+            }
+        }
+    }
+    .data-grid-row-child {
+        display: none;
+        &._active {
+            display: table-row;
+            + tr {
+                &:not(.data-grid-row-child) {
+                    td {
+                        border-top: @data-grid-cell__border-width @data-grid-td__border-outer-style @data-grid-td__border-color;
+                    }
+                }
+            }
+        }
+    }
+    .data-grid-row-child,
+    .data-grid-row-parent ~ .data-grid-row-child {
+        td {
+            background-color: @color-lazy-sun-white;
+            border-color: transparent;
+            &:first-child {
+                border-left-color: @data-grid-td__border-color;
+            }
+            &:last-child {
+                border-right-color: @data-grid-td__border-color;
+            }
+        }
+    }
+}
+
+//  Ascend & Descend sort marker
+.data-grid-th {
+    &._sortable {
+        &._ascend,
+        &._descend {
+            &:before {
+                position: absolute;
+                right: @data-grid-th__padding-horizontal;
+                top: @data-grid-th__padding-vertical - .1rem;
+            }
+        }
+        &._ascend {
+            &:before {
+                content: '\2193';
+            }
+        }
+        &._descend {
+            &:before {
+                content: '\2191';
+            }
+        }
+    }
+}
+
+//  Checkbox actions column
+.data-grid-checkbox-cell-inner {
+    display: block;
+    padding: @data-grid-checkbox-cell-inner__padding-top @data-grid-checkbox-cell-inner__padding-horizontal .9rem;
+    text-align: right;
+    &:hover {
+        cursor: pointer;
+    }
+}
+
+//  Nested rows
+.data-grid-row-parent {
+    &._active {
+        > td {
+            .data-grid-checkbox-cell-inner {
+                &:before {
+                    content: @icon-caret-up__content;
+                }
+            }
+        }
+    }
+    > td {
+        .data-grid-checkbox-cell-inner {
+            padding-left: (@data-grid-checkbox-cell-inner__padding-horizontal * .75) * 2 + @data-grid-row-parent-marker__size;
+            position: relative;
+            &:before {
+                &:extend(.abs-icon all);
+                content: @icon-caret-down__content;
+                font-size: @data-grid-row-parent-marker__size;
+                font-weight: @font-weight__bold;
+                left: @data-grid-checkbox-cell-inner__padding-horizontal * .75;
+                position: absolute;
+                top: @data-grid-checkbox-cell-inner__padding-top + (@data-grid-row-parent-marker__size / 2);
+            }
+        }
+    }
+}
diff --git a/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/data-grid/_data-grid-header.less b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/data-grid/_data-grid-header.less
new file mode 100644
index 0000000000000000000000000000000000000000..6d5ecd492f8b61b3727d2aea729e31e3cce18dbb
--- /dev/null
+++ b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/data-grid/_data-grid-header.less
@@ -0,0 +1,96 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  UI -> Data Grid -> Header
+//  _____________________________________________
+
+//
+//  Components
+//  ---------------------------------------------
+
+@import 'data-grid-header/_data-grid-filters.less';
+@import 'data-grid-header/_data-grid-pager.less';
+//  Actions group
+@import 'data-grid-header/_data-grid-action-bookmarks.less';
+@import 'data-grid-header/_data-grid-action-columns.less';
+
+//
+//  Variables
+//  ---------------------------------------------
+
+@data-grid-header-add-indent__bottom: .9rem;
+@data-grid-header-add-indent__top: .5rem;
+
+@data-grid-header-row__margin-bottom: @indent__base;
+
+@data-grid-action__z-index: @data-grid-header__z-index - 10;
+
+//
+
+.admin__data-grid-header {
+    font-size: @font-size__base; // ToDo UI: should be deleted, added to prevent fz override with .grid
+    position: relative;
+    z-index: @data-grid-header__z-index - 1;
+}
+
+.admin__data-grid-header-row {
+    &:extend(.abs-clearfix all);
+    margin-bottom: @data-grid-header-row__margin-bottom;
+    &:first-child {
+        margin-bottom: @data-grid-header-row__margin-bottom - @data-grid-header-add-indent__bottom;
+    }
+    .action-select-wrap {
+        display: block;
+    }
+    .action-select {
+        width: 100%;
+    }
+}
+
+//
+//  Data grid Header Actions group
+//  ---------------------------------------------
+
+.admin__data-grid-actions-wrap {
+    float: right;
+    margin-left: 1.1rem;
+    margin-top: -@data-grid-header-add-indent__top;
+    text-align: right;
+    .admin__action-dropdown-wrap {
+        position: relative;
+        text-align: left;
+        &._active,
+        &._active + .admin__action-dropdown-wrap, // ToDo UI: remove after bookmarks ready
+        &._hide + .admin__action-dropdown-wrap,
+        &:first-child {
+            &:after {
+                display: none;
+            }
+        }
+        &._active {
+            .admin__action-dropdown,
+            .admin__action-dropdown-menu {
+                border-color: @action__border-color;
+            }
+        }
+        &:after {
+            border-left: 1px solid @color-gray80;
+            content: '';
+            height: @action__height;
+            left: 0;
+            position: absolute;
+            top: @data-grid-header-add-indent__top;
+            z-index: 3;
+        }
+    }
+    .admin__action-dropdown {
+        padding-bottom: @action-dropdown__padding-bottom + @data-grid-header-add-indent__bottom;
+        padding-top: @action-dropdown__padding-top + @data-grid-header-add-indent__top;
+        &:after {
+           margin-top: -.4rem;
+        }
+    }
+}
diff --git a/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/data-grid/data-grid-header/_data-grid-action-bookmarks.less b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/data-grid/data-grid-header/_data-grid-action-bookmarks.less
new file mode 100644
index 0000000000000000000000000000000000000000..6e3be82858c0933375b870d9c25d4ccbf986e401
--- /dev/null
+++ b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/data-grid/data-grid-header/_data-grid-action-bookmarks.less
@@ -0,0 +1,160 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  UI -> Data Grid -> Header -> Action Default View
+//  _____________________________________________
+
+//
+//  Variables
+//  ---------------------------------------------
+
+@action-dropdown-menu__font-size: 1.3rem;
+
+@action-dropdown-menu-item__background-color: @page-wrapper__background-color;
+@action-dropdown-menu-item__padding-vertical: 1rem;
+@action-dropdown-menu-item__padding-left: 2rem;
+@action-dropdown-menu-item__hover__background-color: @color-gray89;
+
+@action-dropdown-menu-item-actions__size: 1.7rem;
+@action-dropdown-menu-item-actions__width: 5rem;
+
+@action-dropdown-menu-item-action-icon__padding-horizontal: 1.4rem;
+@action-dropdown-menu-item-action-icon__padding-vertical: .6rem;
+
+//
+
+.admin__data-grid-action-bookmarks {
+    .admin__action-dropdown-menu__align(right);
+    opacity: @component-modal__opacity;
+    &._hide {
+        display: none;
+    }
+    &._active {
+        z-index: @data-grid-action__z-index;
+    }
+    .admin__action-dropdown {
+        &:before {
+            &:extend(.abs-icon all);
+            content: @icon-views__content;
+        }
+    }
+    .admin__action-dropdown-menu {
+        font-size: @action-dropdown-menu__font-size;
+        left: 0;
+        padding: 1rem 0 0;
+        right: auto;
+        > li {
+            padding: 0 @action-dropdown-menu-item-actions__width 0 0;
+            position: relative;
+            white-space: nowrap;
+            &:not(.action-dropdown-menu-item-last) {
+                transition: @smooth__background-color;
+                &:hover {
+                    background-color: @action-dropdown-menu-item__hover__background-color;
+                }
+            }
+        }
+        .action-dropdown-menu-item {
+            max-width: 23rem;
+            min-width: 18rem;
+            white-space: normal;
+            word-break: break-all;
+        }
+        .action-dropdown-menu-item-edit {
+            display: none;
+            padding-bottom: @action-dropdown-menu-item__padding-vertical;
+            padding-left: @action-dropdown-menu-item__padding-left / 2;
+            padding-top: @action-dropdown-menu-item__padding-vertical;
+            .action-dropdown-menu-item-actions {
+                padding-bottom: @action-dropdown-menu-item__padding-vertical;
+                padding-top: @action-dropdown-menu-item__padding-vertical;
+            }
+        }
+        //  Save action
+        .action-dropdown-menu-item-last {
+            padding-bottom: @action-dropdown-menu-item__padding-vertical;
+            padding-left: @action-dropdown-menu-item__padding-left / 2;
+            padding-top: @action-dropdown-menu-item__padding-vertical;
+            > a {
+                .link-pattern();
+                display: inline-block;
+                padding-left: 1.1rem;
+            }
+        }
+        //  Edit state
+        ._edit {
+            .action-dropdown-menu-item {
+                display: none;
+            }
+            .action-dropdown-menu-item-edit {
+                display: block;
+            }
+        }
+        //  Edit item
+        .admin__control-text {
+            font-size: @action-dropdown-menu__font-size;
+            min-width: 15rem;
+            width: ~'calc(100% - 4rem)';
+            .ie9 & {
+                width: 15rem;
+            }
+        }
+        .action-dropdown-menu-item-actions {
+            border-left: 1px solid @action-dropdown-menu-item__background-color;
+            bottom: 0;
+            position: absolute;
+            right: 0;
+            top: 0;
+            width: @action-dropdown-menu-item-actions__width;
+        }
+        .action-dropdown-menu-link {
+            .action-dropdown-menu-link-pattern();
+            padding: @action-dropdown-menu-item__padding-vertical 1rem @action-dropdown-menu-item__padding-vertical @action-dropdown-menu-item__padding-left + .1rem;
+        }
+    }
+    //  Icon actions
+    .action-submit,
+    .action-delete,
+    .action-edit {
+        .action-reset();
+        vertical-align: top;
+        &:before {
+            &:extend(.abs-icon all);
+            font-size: @action-dropdown-menu-item-actions__size;
+        }
+        > span {
+            .hidden();
+        }
+    }
+    .action-delete,
+    .action-edit {
+        padding: @action-dropdown-menu-item-action-icon__padding-vertical @action-dropdown-menu-item-action-icon__padding-horizontal;
+        &:active {
+            .scale();
+        }
+    }
+    .action-submit {
+        padding: @action-dropdown-menu-item-action-icon__padding-vertical 1rem @action-dropdown-menu-item-action-icon__padding-vertical .8rem;
+        &:active {
+            position: relative;
+            right: -1px;
+        }
+        &:before {
+            content: @icon-arrow-right__content;
+        }
+    }
+    .action-delete {
+        &:before {
+            content: @icon-delete__content;
+        }
+    }
+    .action-edit {
+        padding-top: @action-dropdown-menu-item-action-icon__padding-vertical + .2rem;
+        &:before {
+            content: @icon-edit__content;
+        }
+    }
+}
diff --git a/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/data-grid/data-grid-header/_data-grid-action-columns.less b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/data-grid/data-grid-header/_data-grid-action-columns.less
new file mode 100644
index 0000000000000000000000000000000000000000..e4148e87f4dbb11469b2e3ecb97513defca1e363
--- /dev/null
+++ b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/data-grid/data-grid-header/_data-grid-action-columns.less
@@ -0,0 +1,94 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  UI -> Data Grid -> Header -> Action Columns
+//  _____________________________________________
+
+//
+//  Variables
+//  ---------------------------------------------
+
+@data-grid-action-columns-menu__padding-horizontal: 3.5rem;
+
+@data-grid-action-columns-menu-item__column: 3;
+@data-grid-action-columns-menu-item__margin-bottom: 1.5rem;
+@data-grid-action-columns-menu-item__width: 15.8rem;
+@data-grid-action-columns-menu-item__height: round((@font-size__base * @line-height__base), 1);
+
+@data-grid-action-columns-menu-items-to-scroll: 18;
+@data-grid-action-columns-menu-scroll__width: 1.8rem;
+
+//
+
+.admin__data-grid-action-columns {
+    &._active {
+        opacity: @component-modal__opacity;
+        z-index: @data-grid-action__z-index;
+    }
+    .admin__action-dropdown {
+        &:before {
+            &:extend(.abs-icon all);
+            content: @icon-systems__content;
+            font-size: 1.8rem; // Static
+            left: .3rem;
+            margin-right: .7rem;
+            vertical-align: top;
+        }
+    }
+}
+
+.admin__data-grid-action-columns-menu {
+    color: @color-very-dark-gray-black;
+    font-size: 1.3rem;
+    overflow: hidden;
+    padding: 2.2rem @data-grid-action-columns-menu__padding-horizontal 1rem;
+    z-index: 1;
+    //  State with scroll when .admin__field-option > @data-grid-action-columns-menu-items-to-scroll
+    &._overflow {
+        .admin__action-dropdown-menu-header {
+            border-bottom: 1px solid @border-color__base;
+        }
+        .admin__action-dropdown-menu-content {
+            width: @data-grid-action-columns-menu-item__width * @data-grid-action-columns-menu-item__column + @data-grid-action-columns-menu-scroll__width;
+        }
+        .admin__action-dropdown-menu-footer {
+            border-top: 1px solid @border-color__base;
+            padding-top: 2.5rem;
+        }
+    }
+    .admin__action-dropdown-menu-content {
+        .extend__clearfix();
+        max-height: (@data-grid-action-columns-menu-items-to-scroll / @data-grid-action-columns-menu-item__column) * (@data-grid-action-columns-menu-item__height + @data-grid-action-columns-menu-item__margin-bottom) + (@data-grid-action-columns-menu-item__height / 2 + @data-grid-action-columns-menu-item__margin-bottom);
+        overflow-y: auto;
+        padding-top: 1.5rem;
+        width: @data-grid-action-columns-menu-item__width * @data-grid-action-columns-menu-item__column;
+    }
+    .admin__field-option {
+        height: @data-grid-action-columns-menu-item__height;
+        float: left;
+        margin-bottom: @data-grid-action-columns-menu-item__margin-bottom;
+        padding: 0 1rem 0 0;
+        width: @data-grid-action-columns-menu-item__width;
+    }
+    .admin__field-label {
+        .text-overflow-ellipsis();
+        display: block;
+    }
+    .admin__action-dropdown-menu-header {
+        padding-bottom: 1.5rem;
+    }
+    .admin__action-dropdown-menu-footer {
+        padding: 1rem 0 2rem;
+    }
+    .admin__action-dropdown-footer-main-actions {
+        margin-left: 25%;
+        text-align: right;
+    }
+    .admin__action-dropdown-footer-secondary-actions {
+        float: left;
+        margin-left: -@button__padding-horizontal;
+    }
+}
diff --git a/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/data-grid/data-grid-header/_data-grid-filters.less b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/data-grid/data-grid-header/_data-grid-filters.less
new file mode 100644
index 0000000000000000000000000000000000000000..66df9bda92aaebd8b110229fdbcb6adefc9b2e79
--- /dev/null
+++ b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/data-grid/data-grid-header/_data-grid-filters.less
@@ -0,0 +1,320 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  UI -> Data Grid -> Header -> Filters
+//  _____________________________________________
+
+//
+//  Variables
+//  ---------------------------------------------
+
+@data-grid-search-action__size: 2rem;
+
+@data-grid-filters__font-size: 1.3rem;
+@data-grid-filters__background-color: @page-wrapper__background-color;
+
+@data-grid-filters-fieldset__inner-side: 4rem;
+@data-grid-filters-fieldset__columns: 4;
+
+@data-grid-filters-label__width: 25%;
+
+@data-grid-filters-action__padding-right: 2.1rem;
+@data-grid-filters-action__padding-left: 1.7rem;
+@data-grid-filters-action__active__border-color: @color-gray80;
+@data-grid-filters-action__active__color: @color-phoenix;
+
+@data-grid-filters-current-action-remove__background-color: @color-gray68;
+@data-grid-filters-current-action-remove__hover__background-color: darken(@data-grid-filters-current-action-remove__background-color, 10%);
+@data-grid-filters-current-action-remove__size: 1.6rem;
+
+//
+//  Filter action & search
+//  ---------------------------------------------
+
+.data-grid-filters-actions-wrap {
+    float: right;
+}
+
+//  Data Grid Search
+.data-grid-search-control-wrap {
+    display: none;
+    float: left;
+    max-width: 45.5rem;
+    position: relative;
+    width: 50%;
+    :-ms-input-placeholder {
+        font-style: italic;
+    }
+    ::-webkit-input-placeholder {
+        font-style: italic;
+    }
+    ::-moz-placeholder {
+        font-style: italic;
+    }
+    //  Submit/search icon
+    .action-submit {
+        .action-reset();
+        padding: .6rem 2rem .2rem;
+        position: absolute;
+        right: 0;
+        top: 1px;
+        &:active {
+            .scale();
+        }
+        &:hover {
+            &:before {
+                color: darken(@text__color, 10%);
+            }
+        }
+        &:focus {
+            box-shadow: @focus__box-shadow;
+        }
+        &:before {
+            &:extend(.abs-icon all);
+            content: @icon-search__content;
+            font-size: @data-grid-search-action__size;
+            transition: @smooth__color;
+        }
+        > span {
+            .hidden();
+        }
+    }
+    .action-menu {
+        z-index: 1;
+    }
+}
+
+.data-grid-search-control {
+    padding-right: @data-grid-search-action__size + 2rem * 2;
+    width: 100%;
+}
+
+//  Action
+.data-grid-filters-action-wrap {
+    float: left;
+    padding-left: @indent__base;
+    .action-default {
+        font-size: @data-grid-filters__font-size;
+        padding-left: @data-grid-filters-action__padding-left;
+        padding-right: @data-grid-filters-action__padding-right;
+        padding-top: @action__padding-top + .1rem;
+        &._active {
+            background-color: @data-grid-filters__background-color;
+            border-bottom-color: @data-grid-filters__background-color;
+            border-right-color: @data-grid-filters-action__active__border-color;
+            font-weight: @font-weight__semibold;
+            margin-left: 0;
+            margin-right: 0;
+            margin-top: -.1rem;
+            padding-bottom: 1.9rem;
+            padding-top: @action__padding-top + .2rem;
+            position: relative;
+            z-index: 4;
+            &:after {
+                background-color: @data-grid-filters-action__active__color;
+                bottom: 100%;
+                content: '';
+                height: 3px;
+                left: -1px;
+                position: absolute;
+                right: -1px;
+            }
+        }
+        &:before {
+            &:extend(.abs-icon all);
+            content: @icon-filter__content;
+            font-size: 1.8rem;
+            margin-right: .4rem;
+            position: relative;
+            top: -1px;
+            vertical-align: top;
+        }
+    }
+}
+
+//
+//  Filters content
+//  ---------------------------------------------
+
+.admin__data-grid-filters-wrap {
+    .appearing__off();
+    clear: both;
+    font-size: @data-grid-filters__font-size;
+    max-height: 0;
+    transition: opacity .3s ease, padding .3s ease;
+    &._show {
+        .appearing__on();
+        border-bottom: 1px solid @data-grid-filters-action__active__border-color;
+        border-top: 1px solid @data-grid-filters-action__active__border-color;
+        margin-bottom: .7rem;
+        max-height: 50rem;
+        padding: 3.6rem 0 3rem;
+        position: relative;
+        top: -1px;
+        z-index: 3;
+        .admin__data-grid-filters-footer,
+        .admin__data-grid-filters {
+            display: block;
+        }
+    }
+    //  Field labels
+    .admin__form-field-legend,
+    .admin__form-field-label {
+        display: block;
+        font-weight: bold;
+        margin: 0 0 .3rem;
+        text-align: left;
+    }
+    //  First level field
+    .admin__form-field {
+        float: left;
+        margin-bottom: 2em;
+        margin-left: 0;
+        padding-left: @data-grid-filters-fieldset__inner-side / 2;
+        padding-right: @data-grid-filters-fieldset__inner-side / 2;
+        width: 100% / @data-grid-filters-fieldset__columns;
+        &:nth-child(5n + 1) {
+            clear: both;
+        }
+        //  Inner fields
+        .admin__form-field {
+            float: none;
+            margin-bottom: 1.5rem;
+            padding-left: 0;
+            padding-right: 0;
+            width: auto;
+            &:last-child {
+                margin-bottom: 0;
+            }
+            //  Inner field labels
+            .admin__form-field-label {
+                border: @field-control__border-width solid transparent;
+                float: left;
+                font-weight: normal;
+                line-height: @field-control__line-height;
+                margin-bottom: 0;
+                padding-bottom: @field-control__padding-bottom;
+                padding-right: 1em;
+                padding-top: @field-control__padding-top;
+                width: @data-grid-filters-label__width;
+            }
+            .admin__form-field-control {
+                margin-left: @data-grid-filters-label__width;
+            }
+        }
+    }
+    .admin__form-field-label,
+    .admin__control-text,
+    .admin__control-select {
+        font-size: @data-grid-filters__font-size;
+    }
+    .admin__control-select {
+        padding-top: @action__padding-top - .1rem;
+        height: @action__height - .1rem;
+    }
+    //  Date control
+    .admin__control-text.hasDatepicker,
+    .admin__control-select {
+        width: 100%;
+    }
+}
+
+//  Filters content wrap
+.admin__data-grid-filters {
+    &:extend(.abs-clearfix all);
+    display: none;
+    margin-left: -(@data-grid-filters-fieldset__inner-side / 2);
+    margin-right: -(@data-grid-filters-fieldset__inner-side / 2);
+}
+
+.admin__filters-legend {
+    .hidden();
+}
+
+//  Filters footer
+.admin__data-grid-filters-footer {
+    &:extend(.abs-clearfix all);
+    display: none;
+    font-size: @font-size__base;
+    .admin__footer-main-actions {
+        margin-left: 25%;
+        text-align: right;
+    }
+    .admin__footer-secondary-actions {
+        float: left;
+        width: 50%;
+    }
+}
+
+//
+//  Chips
+//  ---------------------------------------------
+
+//  Current chips
+.admin__data-grid-filters-current {
+    border-bottom: 1px solid @data-grid-filters-action__active__border-color;
+    border-top: 1px solid @data-grid-filters-action__active__border-color;
+    display: none;
+    font-size: @data-grid-filters__font-size;
+    margin-bottom: .9rem;
+    padding-bottom: .8rem;
+    padding-top: 1.1rem;
+    width: 100%;
+    &._show {
+        display: table;
+    }
+}
+
+.admin__current-filters-list-wrap,
+.admin__current-filters-title-wrap {
+    display: table-cell;
+    vertical-align: top;
+}
+
+.admin__current-filters-title {
+    margin-right: 1em;
+    white-space: nowrap;
+}
+
+.admin__current-filters-list-wrap {
+    width: 100%;
+}
+
+.admin__current-filters-list {
+    margin-bottom: 0;
+    > li {
+        display: inline-block;
+        font-weight: @font-weight__semibold;
+        margin: 0 1rem .5rem;
+        padding-right: @data-grid-filters-current-action-remove__size + 1rem;
+        position: relative;
+    }
+    .action-remove {
+        .action-reset();
+        line-height: 1;
+        position: absolute;
+        right: 0;
+        top: 1px;
+        &:hover {
+            &:before {
+                color: @data-grid-filters-current-action-remove__hover__background-color;
+            }
+        }
+        &:active {
+            .scale();
+        }
+        &:before {
+            &:extend(.abs-icon all);
+            color: @data-grid-filters-current-action-remove__background-color;
+            content: @icon-remove-small__content;
+            font-size: @data-grid-filters-current-action-remove__size;
+            transition: @smooth__color;
+        }
+        > span {
+            .hidden();
+        }
+    }
+}
diff --git a/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/data-grid/data-grid-header/_data-grid-pager.less b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/data-grid/data-grid-header/_data-grid-pager.less
new file mode 100644
index 0000000000000000000000000000000000000000..a30087cb5a6972ca99f7636d3a4fe26e9ee59219
--- /dev/null
+++ b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/data-grid/data-grid-header/_data-grid-pager.less
@@ -0,0 +1,63 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  UI -> Data Grid -> Header -> Pager
+//  _____________________________________________
+
+//
+//  Variables
+//  ---------------------------------------------
+
+@data-grid-pager-action__width: 4.4rem;
+
+//
+
+.admin__data-grid-pager-wrap {
+    text-align: right;
+}
+
+.admin__data-grid-pager {
+    display: inline-block;
+    margin-left: @content__indent;
+    .admin__control-text::-webkit-outer-spin-button,
+    .admin__control-text::-webkit-inner-spin-button {
+        -webkit-appearance: none;
+        margin: 0;
+    }
+    .admin__control-text {
+        -moz-appearance: textfield;
+        text-align: center;
+        width: @data-grid-pager-action__width;
+    }
+}
+
+.action-previous,
+.action-next {
+    width: @data-grid-pager-action__width;
+    &:before {
+        &:extend(.abs-icon all);
+        font-weight: @font-weight__bold;
+    }
+    > span {
+        .hidden();
+    }
+}
+
+.action-previous {
+    margin-right: 2.5rem;
+    text-indent: -.25em;
+    &:before {
+        content: @icon-caret-left__content;
+    }
+}
+
+.action-next {
+    margin-left: 1.5rem;
+    text-indent: .1em;
+    &:before {
+        content: @icon-caret-right__content;
+    }
+}
diff --git a/app/design/adminhtml/Magento/backend/composer.json b/app/design/adminhtml/Magento/backend/composer.json
index 8ae2687dac7e5d03b2248d8dff711c8d8fd8a1c9..a0fc76610568403a31ae8e6e3184977f90c6cce9 100644
--- a/app/design/adminhtml/Magento/backend/composer.json
+++ b/app/design/adminhtml/Magento/backend/composer.json
@@ -3,11 +3,11 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/framework": "0.74.0-beta6",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-theme",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/design/adminhtml/Magento/backend/web/css/source/_actions.less b/app/design/adminhtml/Magento/backend/web/css/source/_actions.less
index 7a3f017a0a5b58b1841e07680b58341e1e00a9f6..0353568d0e94abea48be8579cb2adcf6d3f1dcf9 100644
--- a/app/design/adminhtml/Magento/backend/web/css/source/_actions.less
+++ b/app/design/adminhtml/Magento/backend/web/css/source/_actions.less
@@ -7,7 +7,10 @@
 //  Imports
 //  _____________________________________________
 
+@import 'actions/_actions-dropdown.less';
 @import 'actions/_actions-split.less';
+@import 'actions/_actions-select.less';
+@import 'actions/_actions-multiselect.less';
 
 //
 //  Variables
@@ -15,12 +18,15 @@
 
 //  Base button
 @button__background-color: @color-gray89;
-@button__border-color: @color-gray68;
+@button__border-color: @action__border-color;
+@button__border-size: 1px;
+@button__border-style: solid;
 @button__color: @color-brownie;
 @button__font-family: @font-family__base;
-@button__font-size: @font-size__base;
-@button__padding-top: .5em;
-@button__padding-bottom: .57em;
+@button__font-size: @action__font-size;
+@button__line-height: @action__line-height;
+@button__padding-top: @action__padding-top;
+@button__padding-bottom: @action__padding-bottom;
 @button__padding-horizontal: 1em;
 @button__padding-vertical__l: .6875em;
 
@@ -46,11 +52,18 @@
 @button-secondary__active__background-color: @color-very-dark-gray-black2;
 @button-secondary__hover__background-color: @color-very-dark-gray-black2;
 
+//  Triangle marker
+@button-marker-triangle__height: .5rem;
+@button-marker-triangle__width: .8rem;
+
+@button-marker-triangle__height__xl: .9rem;
+@button-marker-triangle__width__xl: 1.2rem;
+
 //
 //  Utilities
 //  _____________________________________________
 
-.action-reset () {
+.action-reset() {
     background-color: transparent;
     border: none;
     border-radius: 0;
@@ -64,6 +77,47 @@
     }
 }
 
+//  Used in action dropdown, actions split & all other actions with triangle marker
+.action-toggle-triangle (
+    @_dropdown__padding-right: 3rem;
+    @_triangle__height: @button-marker-triangle__height;
+    @_triangle__width: @button-marker-triangle__width;
+    @_triangle__color: @color-black;
+    @_triangle__hover__color: darken(@_triangle__color, 10%);
+    @_triangle__right: (@_dropdown__padding-right / 2) - (@_triangle__width / 2);
+) {
+    padding-right: @_dropdown__padding-right;
+    &._active,
+    &.active {
+        &:after {
+            transform: rotate(180deg);
+        }
+    }
+    &:after {
+        border-color: @_triangle__color transparent transparent transparent;
+        border-style: solid;
+        border-width: @_triangle__height @_triangle__width / 2 0 @_triangle__width / 2;
+        content: '';
+        height: 0;
+        margin-top: -((@_triangle__width / 2) / 2);
+        position: absolute;
+        right: @_triangle__right;
+        top: 50%;
+        transition: all .2s linear;
+        width: 0;
+        ._active &,
+        .active & {
+            transform: rotate(180deg);
+        }
+    }
+    &:hover {
+        &:after {
+            border-color: @_triangle__hover__color transparent transparent transparent;
+        }
+    }
+}
+
+
 //
 //  Extends
 //  _____________________________________________
@@ -73,15 +127,16 @@
 }
 
 .abs-action-pattern {
-    border: 1px solid;
+    border: @button__border-size @button__border-style;
     border-radius: 0; // ToDo UI: Delete with admin scope
     display: inline-block;
     font-family: @button__font-family;
     font-size: @button__font-size;
     font-weight: @font-weight__semibold;
+    line-height: @button__line-height;
     padding: @button__padding-top @button__padding-horizontal @button__padding-bottom;
     text-align: center;
-    vertical-align: baseline; // ToDo UI: Delete with admin scope
+    vertical-align: baseline;
     &[disabled],
     &.disabled {
         cursor: default;
@@ -97,6 +152,29 @@
     padding-top: @button__padding-vertical__l;
 }
 
+.abs-action-delete {
+    &:extend(.abs-action-reset all);
+    &:extend(.abs-icon all);
+    display: inline-block;
+    font-size: 1.6rem;
+    margin-left: 1.2rem;
+    padding-top: .7rem;
+    text-decoration: none;
+    vertical-align: middle;
+    &:after {
+        color: @color-very-dark-gray;
+        content: @icon-delete__content;
+    }
+    &:hover {
+        &:after {
+            color: @color-very-dark-gray-black2;
+        }
+    }
+    > span {
+        &:extend(.abs-visually-hidden all);
+    }
+}
+
 .abs-action-default {
     .action-default();
 }
@@ -117,6 +195,10 @@
     .action-quaternary();
 }
 
+.abs-action-menu {
+    .action-menu();
+}
+
 //
 //  Default action
 //  ---------------------------------------------
@@ -222,6 +304,89 @@ button {
     }
 }
 
+//
+//  Specific actions
+//  ---------------------------------------------
+
+.action-close {
+    > span {
+        .hidden();
+    }
+    &:extend(.abs-action-reset all);
+    &:active {
+        .scale();
+    }
+    &:before {
+        &:extend(.abs-icon all);
+        content: @icon-close-mage__content;
+        .transition(color);
+    }
+    &:hover {
+        cursor: pointer;
+        text-decoration: none;
+    }
+}
+
+//
+//  Action menu
+//  ---------------------------------------------
+
+//  Used in actions split, action select and all other simple (one line) action menu list
+.action-menu {
+    .appearing__off();
+    background-color: @page-wrapper__background-color;
+    border: 1px solid @action__active__border-color;
+    border-radius: 1px;
+    box-shadow: @component__box-shadow__base;
+    color: @text__color;
+    display: block; // ToDo UI: Should be deleted with old styles
+    font-weight: @font-weight__regular;
+    left: 0;
+    list-style: none;
+    margin: 2px 0 0; // Action box-shadow + 1px indent
+    min-width: 0; // ToDo UI: Should be deleted with old styles
+    padding: 0;
+    position: absolute;
+    right: 0;
+    top: 100%;
+    transition: opacity @appearing__transition-duration @apperaing__transition-timing-function;
+    &._active {
+        .appearing__on();
+    }
+    > li {
+        display: block;
+        border: none; // ToDo UI: Should be deleted with old styles
+        padding: 0;
+        transition: background-color .1s linear;
+        > a {
+            &:hover {
+                text-decoration: none;
+            }
+        }
+        &:hover {
+            background-color: @action-menu__hover__background-color;
+        }
+        &:active {
+            background-color: darken(@action-menu__hover__background-color, 10%);
+        }
+    }
+    .item,
+    .action-menu-item {
+        display: block;
+        padding: .6875em 1em;
+        cursor: pointer;
+    }
+    a {
+        &.action-menu-item {
+            color: @text__color;
+            &:focus {
+                background-color: @action-menu__hover__background-color;
+                box-shadow: none;
+            }
+        }
+    }
+}
+
 //
 //  ToDo UI: Button migration
 //  _____________________________________________
diff --git a/app/design/adminhtml/Magento/backend/web/css/source/_classes.less b/app/design/adminhtml/Magento/backend/web/css/source/_classes.less
new file mode 100644
index 0000000000000000000000000000000000000000..2b420d0e88ff98160f00b6af5ae2953665a61568
--- /dev/null
+++ b/app/design/adminhtml/Magento/backend/web/css/source/_classes.less
@@ -0,0 +1,16 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Helper cross js and styles classes
+//  _____________________________________________
+
+//  Can be used for disabled elements, equal disabled='disabled' attribute
+._disabled {
+    .disabled();
+    &:hover {
+        .disabled();
+    }
+}
diff --git a/app/design/adminhtml/Magento/backend/web/css/source/_forms.less b/app/design/adminhtml/Magento/backend/web/css/source/_forms.less
index 131ae92ae03dee1b4e619d4a5939357de56fa86b..624092c1068bb181bf7e9e60329e41e13c0f4f8a 100644
--- a/app/design/adminhtml/Magento/backend/web/css/source/_forms.less
+++ b/app/design/adminhtml/Magento/backend/web/css/source/_forms.less
@@ -7,4 +7,4 @@
 @import 'forms/_fields.less';
 @import 'forms/_tooltip.less';
 @import 'forms/_temp.less';
-@import 'forms/_dropdown.less';
+@import 'forms/_checkbox-radio.less';
diff --git a/app/design/adminhtml/Magento/backend/web/css/source/_grid.less b/app/design/adminhtml/Magento/backend/web/css/source/_grid.less
index f139356abfa2948d91e01fa63dffde477b7067de..4a7856af7947c918231a4d19f46be1f279336daa 100644
--- a/app/design/adminhtml/Magento/backend/web/css/source/_grid.less
+++ b/app/design/adminhtml/Magento/backend/web/css/source/_grid.less
@@ -65,9 +65,8 @@
 .row-gutter {
     margin-left: -(@content__indent / 2);
     margin-right: -(@content__indent / 2);
-    .col-gutter {
+    > [class*='col-'] {
         padding-left: @content__indent / 2;
         padding-right: @content__indent / 2;
     }
 }
-
diff --git a/app/design/adminhtml/Magento/backend/web/css/source/_sources.less b/app/design/adminhtml/Magento/backend/web/css/source/_sources.less
index 82de6e8fd0d1b023a6739df8b85ab07b820f1724..197d0d89a271cb453c4048d7a02099dbd23ba63b 100644
--- a/app/design/adminhtml/Magento/backend/web/css/source/_sources.less
+++ b/app/design/adminhtml/Magento/backend/web/css/source/_sources.less
@@ -11,8 +11,8 @@
 @import '_utilities.less';
 @import '_reset.less';
 @import '_typography.less';
-@import '_icons.less';
 @import '_lists.less';
+@import '_icons.less';
 @import '_forms.less';
 @import '_actions.less';
 @import '_tables.less';
diff --git a/app/design/adminhtml/Magento/backend/web/css/source/_structure.less b/app/design/adminhtml/Magento/backend/web/css/source/_structure.less
index f971e04756ee517f8ded56eaf5346c5cf1726c81..f7e0dbde07ca8958b2778f02d9811eb077738ae8 100644
--- a/app/design/adminhtml/Magento/backend/web/css/source/_structure.less
+++ b/app/design/adminhtml/Magento/backend/web/css/source/_structure.less
@@ -29,6 +29,7 @@ body {
 
 .page-wrapper {
     background-color: @page-wrapper__background-color;
+    min-width: 102.4rem;
     padding-left: @page-wrapper__indent-left;
 }
 
diff --git a/app/design/adminhtml/Magento/backend/web/css/source/_tables.less b/app/design/adminhtml/Magento/backend/web/css/source/_tables.less
index bf591fe9921f70066c979e51f23d908baf851669..c72dda688951972b6e6b5b74851f0c8355c12727 100644
--- a/app/design/adminhtml/Magento/backend/web/css/source/_tables.less
+++ b/app/design/adminhtml/Magento/backend/web/css/source/_tables.less
@@ -16,29 +16,48 @@
 
 @table-tfoot__background-color: @color-white-fog;
 
-@table-info__font-size: 1.3rem;
-@table-info__padding-vertical: 1rem;
-@table-info__padding-horizontal: 1.5rem;
+@admin__table-primary__font-size: 1.3rem;
+@admin__table-primary__padding-vertical: 1rem;
+@admin__table-primary__padding-horizontal: 1.5rem;
+
+@admin__table-secondary__padding-vertical: @admin__table-primary__padding-vertical;
+@admin__table-secondary__padding-horizontal: 1rem;
+@admin__table-secondary-caption__font-size: 1.8rem;
+@admin__table-secondary-cell__odd__color: @color-white-fog2;
+@admin__table-secondary-th__color: @color-brownie-light;
 
 //
 //  Tables
 //  _____________________________________________
 
-//
-//  Utilities
-//  ---------------------------------------------
+table {
+    background-color: transparent;
+    color: @table__color;
+    > caption {
+        margin-bottom: .5em;
+    }
+}
+
+.admin__table-primary,
+.admin__table-secondary {
+    width: 100%;
+}
 
-.table-info {
-    font-size: @table-info__font-size;
+.admin__table-primary {
+    font-size: @admin__table-primary__font-size;
     th,
     td {
-        padding: @table-info__padding-vertical @table-info__padding-horizontal;
+        padding: @admin__table-primary__padding-vertical @admin__table-primary__padding-horizontal;
         text-align: left;
+        &:first-child {
+            padding-left: 0;
+        }
     }
     th {
         border-bottom: 1px solid @table-th__border-color;
         border-top: 1px solid @table-th__border-color;
         font-weight: @font-weight__bold;
+        vertical-align: bottom;
     }
     td {
         border-bottom: 1px solid @table-td__border-color;
@@ -55,15 +74,59 @@
     }
     tfoot {
         background: @table-tfoot__background-color;
+        font-weight: @font-weight__semibold;
+        th,
+        td {
+            &:first-child {
+                padding-left: @admin__table-primary__padding-horizontal;
+            }
+        }
     }
 }
 
-//
-
-table {
-    background-color: transparent;
-    color: @table__color;
-    > caption {
-        margin-bottom: .5em;
+.admin__table-secondary {
+    caption {
+        font-size: @admin__table-secondary-caption__font-size;
+        font-weight: @font-weight__bold;
+        margin-bottom: .75em;
+        text-align: left;
+    }
+    tbody {
+        th {
+            vertical-align: top;
+        }
+    }
+    tr {
+        &:nth-child(odd) {
+            th,
+            td {
+                background-color: @admin__table-secondary-cell__odd__color;
+            }
+        }
+    }
+    th,
+    td {
+        padding: @admin__table-secondary__padding-horizontal @admin__table-secondary__padding-vertical;
+        text-align: left;
+    }
+    th {
+        color: @admin__table-secondary-th__color;
+        font-weight: @font-weight__regular;
+    }
+    tfoot {
+        tr {
+            &:nth-child(odd) {
+                th,
+                td {
+                    background-color: @color-white;
+                }
+            }
+            &:first-child {
+                border-top: 1px solid @table-td__border-color;
+            }
+        }
+    }
+    .admin__total-amount {
+        text-align: right;
     }
 }
diff --git a/app/design/adminhtml/Magento/backend/web/css/source/_tabs.less b/app/design/adminhtml/Magento/backend/web/css/source/_tabs.less
index fa113a59c52acb0e46b2968e09eab6d0c9f33f49..1728f1f08b5e655e4f61a43b9efd443f266c5c5e 100644
--- a/app/design/adminhtml/Magento/backend/web/css/source/_tabs.less
+++ b/app/design/adminhtml/Magento/backend/web/css/source/_tabs.less
@@ -57,7 +57,6 @@
 
 //  Tabs content
 .ui-tabs-panel {
-    border-top: 1px solid @color-gray68;
     margin-top: -1px;
     padding: 2rem;
 }
diff --git a/app/design/adminhtml/Magento/backend/web/css/source/_typography.less b/app/design/adminhtml/Magento/backend/web/css/source/_typography.less
index 476415b15756aca49c23ba1c8218a3cc679666a6..ef2beb554b5a79d5a0512720366d68cc6787b81b 100644
--- a/app/design/adminhtml/Magento/backend/web/css/source/_typography.less
+++ b/app/design/adminhtml/Magento/backend/web/css/source/_typography.less
@@ -3,6 +3,19 @@
 //  * See COPYING.txt for license details.
 //  */
 
+//
+//  Utilities
+//  ---------------------------------------------
+
+.link-pattern() {
+    color: @link__color;
+    text-decoration: none;
+    &:hover {
+        color: @link__hover__color;
+        text-decoration: underline;
+    }
+}
+
 .font-face(
     @family-name: @font-family-name__base,
     @font-path: '@{baseDir}fonts/opensans/light/opensans-300',
@@ -31,6 +44,8 @@
     @font-style: normal
 );
 
+//
+
 html,
 body {
     height: 100%;
@@ -109,10 +124,5 @@ small {
 
 //  Links
 a {
-    color: @link__color;
-    text-decoration: none;
-    &:hover {
-        color: @link__hover__color;
-        text-decoration: underline;
-    }
+    .link-pattern();
 }
diff --git a/app/design/adminhtml/Magento/backend/web/css/source/_utilities.less b/app/design/adminhtml/Magento/backend/web/css/source/_utilities.less
index 5182c77ed22e5463c2e377a7d09b17f0a12f3820..84a014a902f9bdc18a9e1f99330fc50891985d80 100644
--- a/app/design/adminhtml/Magento/backend/web/css/source/_utilities.less
+++ b/app/design/adminhtml/Magento/backend/web/css/source/_utilities.less
@@ -7,3 +7,32 @@
 @import 'utilities/_grid.less';
 @import 'utilities/_animations.less';
 @import 'utilities/_spinner.less';
+
+.hidden() {
+    clip: rect(0, 0, 0, 0);
+    overflow: hidden;
+    position: absolute;
+}
+
+.disabled() {
+    box-shadow: none;
+    cursor: default;
+    opacity: .5;
+    outline: 0;
+}
+
+.text-overflow-ellipsis() {
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+}
+
+.appearing__off() {
+    opacity: 0;
+    visibility: hidden;
+}
+
+.appearing__on() {
+    opacity: 1;
+    visibility: visible;
+}
diff --git a/app/design/adminhtml/Magento/backend/web/css/source/_variables.less b/app/design/adminhtml/Magento/backend/web/css/source/_variables.less
index a18ebc40b4799ca255df30f31ef303b596f8665c..191918c389c231300ce085f212628874acc1bc6d 100644
--- a/app/design/adminhtml/Magento/backend/web/css/source/_variables.less
+++ b/app/design/adminhtml/Magento/backend/web/css/source/_variables.less
@@ -10,6 +10,7 @@
 @import 'variables/_colors.less';
 @import 'variables/_typography.less';
 @import 'variables/_icons.less';
+@import 'variables/_actions.less';
 @import 'variables/_forms.less';
 @import 'variables/_structure.less';
 @import 'variables/_animations.less';
\ No newline at end of file
diff --git a/app/design/adminhtml/Magento/backend/web/css/source/actions/_actions-dropdown.less b/app/design/adminhtml/Magento/backend/web/css/source/actions/_actions-dropdown.less
new file mode 100644
index 0000000000000000000000000000000000000000..6f89fefaf392a88cc9042ddb7d1070e5fb3dfc09
--- /dev/null
+++ b/app/design/adminhtml/Magento/backend/web/css/source/actions/_actions-dropdown.less
@@ -0,0 +1,164 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Forms -> Dropdown element
+//  _____________________________________________
+
+//
+//  Variables
+//  ---------------------------------------------
+
+@action-dropdown__color: @text__color;
+@action-dropdown__background-color: @page-wrapper__background-color;
+@action-dropdown__border-color: @color-light-gray;
+@action-dropdown__font-size: round(@font-size__base - .1rem, 1);
+@action-dropdown__height: @action__height;
+@action-dropdown__padding-top: .7rem;
+@action-dropdown__padding-bottom: .8rem;
+@action-dropdown__padding-horizontal: 1.5rem;
+@action-dropdown__padding-right: @action-dropdown__padding-horizontal + @action-dropdown-menu__padding-horizontal + @button-marker-triangle__width;
+@action-dropdown__active__border-color: @color-blue-pure;
+@action-dropdown__hover__color: darken(@action-dropdown__color, 20%);
+
+@action-dropdown-menu__padding-vertical: .5rem;
+@action-dropdown-menu__padding-horizontal: 1rem;
+
+@action-dropdown-menu-link__padding-vertical: .6rem;
+@action-dropdown-menu-link__padding-horizontal: @action-dropdown__padding-horizontal - @action-dropdown-menu__padding-horizontal;
+
+//
+//  Utilities
+//  ---------------------------------------------
+
+.admin__action-dropdown-menu__align(
+    @_align
+) when (@_align = left) {
+    .admin__action-dropdown-text {
+        &:after {
+            left: -(@component__shadow-size__base + 1);
+            right: 0;
+        }
+    }
+    .admin__action-dropdown-menu {
+        left: auto;
+        right: 0;
+    }
+}
+
+.admin__action-dropdown-menu__align(
+    @_align
+) when (@_align = right) {
+    .admin__action-dropdown-text {
+        &:after {
+            right: -(@component__shadow-size__base + 1);
+            left: 0;
+        }
+    }
+    .admin__action-dropdown-menu {
+        left: 0;
+        right: auto;
+    }
+}
+
+.action-dropdown-menu-link-pattern() {
+    color: @action-dropdown__color;
+    display: block;
+    text-decoration: none;
+}
+
+//
+
+.admin__action-dropdown-wrap {
+    .admin__action-dropdown-menu__align(left);
+    display: inline-block;
+    position: relative;
+    &.active,
+    &._active {
+        .admin__action-dropdown {
+            border-color: @action-dropdown__active__border-color;
+            box-shadow: @component__box-shadow__base;
+        }
+        //  Dropdown helper to prevent box shadow unnecessary appearing
+        .admin__action-dropdown-text {
+            &:after {
+                background-color: @action-dropdown__background-color;
+                content: '';
+                height: @component__shadow-size__base + 1;
+                position: absolute;
+                top: 100%;
+            }
+        }
+        .admin__action-dropdown-menu {
+            .appearing__on();
+        }
+    }
+    &._disabled {
+        .admin__action-dropdown {
+            cursor: default;
+        }
+        &:hover {
+            .admin__action-dropdown {
+                color: @action-dropdown__color;
+            }
+        }
+    }
+}
+
+.admin__action-dropdown {
+    .action-toggle-triangle(
+        @_dropdown__padding-right: @action-dropdown__padding-right;
+    );
+    box-shadow: none;
+    background-color: @action-dropdown__background-color;
+    border: 1px solid transparent;
+    border-bottom: none;
+    border-radius: 0;
+    color: @action-dropdown__color;
+    display: inline-block;
+    font-size: @action-dropdown__font-size;
+    font-weight: @font-weight__regular;
+    letter-spacing: -.025em;
+    padding: @action-dropdown__padding-top @action-dropdown__padding-right @action-dropdown__padding-bottom @action-dropdown__padding-horizontal;
+    position: relative;
+    transition: border-color @appearing__transition-duration @apperaing__transition-timing-function;
+    vertical-align: baseline;
+    z-index: 2;
+    &:hover {
+        color: @action-dropdown__hover__color;
+        background-color: @action-dropdown__background-color;
+        text-decoration: none;
+    }
+    //  Triangle
+    &:after {
+        right: @action-dropdown__padding-horizontal;
+    }
+    //  Icon
+    &:before {
+        margin-right: 1rem;
+    }
+}
+
+.admin__action-dropdown-menu {
+    .appearing__off();
+    background-color: @action-dropdown__background-color;
+    border: 1px solid @action-dropdown__active__border-color;
+    box-shadow: @component__box-shadow__base;
+    line-height: @line-height__base;
+    margin-top: -1px;
+    min-width: 120%;
+    padding: @action-dropdown-menu__padding-vertical @action-dropdown-menu__padding-horizontal;
+    position: absolute;
+    top: 100%;
+    transition: all @appearing__transition-duration @apperaing__transition-timing-function;
+    z-index: 1;
+    > li {
+        display: block;
+        > a {
+            .action-dropdown-menu-link-pattern();
+            padding: @action-dropdown-menu-link__padding-vertical @action-dropdown-menu-link__padding-horizontal;
+        }
+    }
+}
diff --git a/app/design/adminhtml/Magento/backend/web/css/source/actions/_actions-multiselect.less b/app/design/adminhtml/Magento/backend/web/css/source/actions/_actions-multiselect.less
new file mode 100644
index 0000000000000000000000000000000000000000..597a73358d82bb119a8329b8c2d5a435339f1e0d
--- /dev/null
+++ b/app/design/adminhtml/Magento/backend/web/css/source/actions/_actions-multiselect.less
@@ -0,0 +1,84 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Actions -> Actions multiselect
+//  _____________________________________________
+
+//  Action multiselect is a combining of checkbox and dropdown elements
+
+.action-multiselect-wrap {
+    &:extend(.abs-clearfix all);
+    display: inline-block;
+    padding-top: 1px;
+    position: relative;
+    height: @control-checkbox-radio__size;
+    z-index: @action-multiselect__z-index;
+    &:hover {
+        .admin__control-checkbox + label:before,
+        .action-multiselect-toggle {
+            border-color: @field-control__hover__border-color;
+        }
+    }
+    &._active {
+        .admin__control-checkbox + label:before,
+        .action-multiselect-toggle {
+            border-color: @action__active__border-color;
+        }
+        .action-menu {
+            .appearing__on();
+        }
+    }
+    &._disabled {
+        .admin__control-checkbox {
+            + label {
+                &:before {
+                    background-color: @control-checkbox-radio__background-color;
+                }
+            }
+        }
+        .admin__control-checkbox + label:before,
+        .action-multiselect-toggle {
+            border-color: @field-control__border-color;
+            opacity: 1;
+        }
+    }
+    .admin__control-checkbox,
+    .admin__control-checkbox + label,
+    .action-multiselect-toggle {
+        float: left;
+    }
+    .action-multiselect-toggle {
+        .action-toggle-triangle(
+            @_triangle__height: @button-marker-triangle__height;
+            @_triangle__width: @button-marker-triangle__width;
+        );
+        border-radius: 0 1px 1px 0;
+        height: @control-checkbox-radio__size;
+        margin-left: -1px;
+        padding: 0;
+        position: relative;
+        transition: @smooth__border-color;
+        width: @control-checkbox-radio__size;
+        &:focus {
+            border-color: @action__active__border-color;
+        }
+        &:after {
+            right: .3rem;
+        }
+        > span {
+            .visually-hidden();
+        }
+    }
+    .action-menu {
+        left: -(@data-grid-cell__padding-horizontal + @data-grid-cell__border-width + .1rem);
+        right: auto;
+        text-align: left;
+        margin-top: 1px;
+    }
+    .action-menu-item {
+        white-space: nowrap;
+    }
+}
diff --git a/app/design/adminhtml/Magento/backend/web/css/source/actions/_actions-select.less b/app/design/adminhtml/Magento/backend/web/css/source/actions/_actions-select.less
new file mode 100644
index 0000000000000000000000000000000000000000..496f6269e8b3ddff1ae01efaf405ea41e37aa979
--- /dev/null
+++ b/app/design/adminhtml/Magento/backend/web/css/source/actions/_actions-select.less
@@ -0,0 +1,64 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Actions -> Action select
+//  _____________________________________________
+
+//  Action select have the same visual styles and functionality as native <select>
+.action-select-wrap {
+    @_action-select__border-color: @button__border-color;
+    @_action-select__active__border-color: @action__active__border-color;
+    @_action-select-toggle__size: @action__height;
+
+    display: inline-block;
+    position: relative;
+    .action-select {
+        .action-toggle-triangle(
+            @_dropdown__padding-right: @_action-select-toggle__size;
+            @_triangle__height: @button-marker-triangle__height;
+            @_triangle__width: @button-marker-triangle__width;
+        );
+        .text-overflow-ellipsis();
+        background-color: @color-white;
+        font-weight: @font-weight__regular;
+        text-align: left;
+        &:hover {
+            border-color: @field-control__hover__border-color;
+            &:before {
+                border-color: @field-control__hover__border-color;
+            }
+        }
+        //  Toggle action
+        &:before {
+            background-color: @button__background-color;
+            border: @button__border-size @button__border-style @_action-select__border-color;
+            bottom: 0;
+            content: '';
+            position: absolute;
+            right: 0;
+            top: 0;
+            width: @_action-select-toggle__size;
+        }
+        &._active {
+            border-color: @_action-select__active__border-color;
+            &:before {
+                border-color: @_action-select__active__border-color;
+                border-left-color: @_action-select__border-color;
+            }
+        }
+    }
+    &._active {
+        .action-select {
+            border-color: @field-control__active__border-color;
+            &:before {
+                border-color: @field-control__active__border-color;
+            }
+            &:after {
+                transform: rotate(180deg);
+            }
+        }
+    }
+}
diff --git a/app/design/adminhtml/Magento/backend/web/css/source/actions/_actions-split.less b/app/design/adminhtml/Magento/backend/web/css/source/actions/_actions-split.less
index 050e9bf71fbfc21c19218280971f16cf0169695f..402bd4b223727a8e437a3ce7dd66a6f09c898885 100644
--- a/app/design/adminhtml/Magento/backend/web/css/source/actions/_actions-split.less
+++ b/app/design/adminhtml/Magento/backend/web/css/source/actions/_actions-split.less
@@ -7,15 +7,42 @@
 //  Actions -> Actions split
 //  _____________________________________________
 
+//  Actions split is a button aggregator with dropdown element
+
+//
+//  Extends
+//  ---------------------------------------------
+
+.abs-actions-split-xl {
+    @_dropdown__padding-right: 4rem;
+    @_action-toggle__width: @_dropdown__padding-right;
+
+    @_triangle__height: @button-marker-triangle__height__xl;
+    @_triangle__right: (@_dropdown__padding-right / 2) - (@_triangle__width / 2);
+    @_triangle__width: @button-marker-triangle__width__xl;
+
+    .action-default {
+        margin-right: @_action-toggle__width;
+    }
+    .action-toggle {
+        padding-right: @_dropdown__padding-right;
+        &:after {
+            border-width: @_triangle__height @_triangle__width / 2 0 @_triangle__width / 2;
+            margin-top: -((@_triangle__width / 2) / 2);
+            right: @_triangle__right;
+        }
+    }
+}
+
+//  Double button action
 .actions-split {
     @_action-split__min-width: @_action-toggle__width + @_action-default__min-width;
-    @_action-split-dropdown__hover__background-color: @color-gray89;
     @_action-default__min-width: 9.3rem;
-    @_action-toggle__width: 4rem;
+    @_action-toggle__width: @action__height;
 
     .extend__clearfix();
     position: relative;
-    z-index: @split-button__z-index;
+    z-index: @actions-split__z-index;
     &.active,
     &._active,
     &:hover {
@@ -31,8 +58,7 @@
             }
         }
         .dropdown-menu {
-            opacity: 1;
-            visibility: visible;
+            .appearing__on();
         }
     }
     .action-toggle,
@@ -50,10 +76,10 @@
         min-width: @_action-default__min-width;
     }
     .action-toggle {
-        .dropdown-triangle(
+        .action-toggle-triangle(
             @_dropdown__padding-right: @_action-toggle__width;
-            @_triangle__height: .9rem;
-            @_triangle__width: 1.2rem;
+            @_triangle__height: @button-marker-triangle__height;
+            @_triangle__width: @button-marker-triangle__width;
         );
         border-left-color: rgba(0, 0, 0, .2);
         bottom: 0;
@@ -61,13 +87,13 @@
         position: absolute;
         right: 0;
         top: 0;
-        //  Disable triangle rotation
-        &._active,
-        &.active {
-            &:after {
-                transform: none;
-            }
-        }
+        //   Disable triangle rotation
+        //  &._active,
+        //  &.active {
+        //     &:after {
+        //          transform: none;
+        //      }
+        //   }
         &.action-secondary,
         &.secondary,
         &.action-primary,
@@ -77,36 +103,11 @@
             }
         }
         > span {
-            .visually-hidden();
+            .hidden();
         }
     }
-    .dropdown-menu {
-        background-color: @page-wrapper__background-color;
-        border: 1px solid @button__hover__border-color;
-        border-radius: 1px;
-        box-shadow: @component__box-shadow__base;
-        display: block; // ToDo UI: Should be deleted with old styles
-        left: 0;
-        list-style: none;
-        margin: 2px 0 0; // Action box-shadow + 1px indent
-        min-width: 0; // ToDo UI: Should be deleted with old styles
-        opacity: 0;
-        padding: 0;
-        position: absolute;
-        right: 0;
-        top: 100%;
-        transition: opacity @appering__transition-duration @apperaing__transition-timing-function;
-        visibility: hidden;
-        > li {
-            border: none; // ToDo UI: Should be deleted with old styles
-            padding: .6875em;
-            &:hover {
-                background-color: @_action-split-dropdown__hover__background-color;
-                cursor: pointer;
-            }
-            &:active {
-                background-color: darken(@_action-split-dropdown__hover__background-color, 10%);
-            }
-        }
+    .dropdown-menu,
+    .action-menu {
+        &:extend(.abs-action-menu all);
     }
 }
diff --git a/app/design/adminhtml/Magento/backend/web/css/source/components/_calendar-temp.less b/app/design/adminhtml/Magento/backend/web/css/source/components/_calendar-temp.less
index 5e59707575f588a5996565b8c7931c0efc2ae9e4..621b01524dceea3fea33932b967c26b0dabf851b 100644
--- a/app/design/adminhtml/Magento/backend/web/css/source/components/_calendar-temp.less
+++ b/app/design/adminhtml/Magento/backend/web/css/source/components/_calendar-temp.less
@@ -16,32 +16,35 @@
 @ui-datepicker__border: 1px solid #007dbd;
 @ui-datepicker__indent: 3px;
 @ui-datepicker__padding: 20px;
-@ui-datepicker__shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.3);
+@ui-datepicker__shadow: @component__box-shadow__base;
 
 //
 //  Datepicker control
 //  ---------------------------------------------
 
-.admin__control-text.hasDatepicker {
-    width: 15rem;
-}
-
 .admin__control-text {
+    &.hasDatepicker {
+        width: 15rem;
+    }
     + .ui-datepicker-trigger {
         .button-reset();
         .icon-font(
-            @icon-calendar,
-            @_icon-font-size: 3.8rem,
-            @_icon-font-line-height: 33px,
+            @_icon-font-content: @icon-calendar__content,
+            @_icon-font: @icons-admin__font-name,
+            @_icon-font-size: 2.1rem,
+            @_icon-font-line-height: @action__height,
             @_icon-font-text-hide: true,
             @_icon-font-position: after,
             @_icon-font-color: @ui-datepicker-icon__color
         );
-        height: 3.3rem;
+        height: @action__height;
         overflow: hidden;
         vertical-align: top;
-        margin-left: -4rem;
+        margin-left: -@action__height;
         display: inline-block;
+        &:active {
+            .scale(.975);
+        }
     }
 }
 
@@ -52,6 +55,7 @@
 .ui-datepicker {
     box-sizing: border-box;
     display: none;
+    opacity: @component-modal__opacity;
     padding: @ui-datepicker__padding + @ui-datepicker__indent  @ui-datepicker__padding;
     width: auto;
     z-index: 999999 !important;
diff --git a/app/design/adminhtml/Magento/backend/web/css/source/components/_data-grid-temp.less b/app/design/adminhtml/Magento/backend/web/css/source/components/_data-grid-temp.less
index 7098e076357d147d068e180c487cf75a98da5530..2dded4e6efea6ea68ca2f2f0b9474c187b94d7c0 100644
--- a/app/design/adminhtml/Magento/backend/web/css/source/components/_data-grid-temp.less
+++ b/app/design/adminhtml/Magento/backend/web/css/source/components/_data-grid-temp.less
@@ -42,6 +42,9 @@
 //  ---------------------------------------------
 
 .grid {
+    .hor-scroll {
+        overflow-x: auto;
+    }
     table {
         &:not(.data-table) {
             border: none;
@@ -111,7 +114,7 @@
                 border: @data-grid-temp-cell__border-width @data-grid-temp-th__border-style @data-grid-temp-th__border-color;
                 color: @data-grid-temp-th__color;
                 font-weight: @font-weight__semibold;
-                padding: @data-grid-temp-cell__padding-vertical @data-grid-temp-cell__padding-horizontal;;
+                padding: @data-grid-temp-cell__padding-vertical @data-grid-temp-cell__padding-horizontal;
                 text-align: left;
                 &:first-child {
                     border-left-color: @data-grid-temp-th__border-color;
@@ -184,6 +187,9 @@
                             margin-left: .5rem;
                             width: 3.5rem;
                         }
+                        &:after {
+                            display: none;
+                        }
                     }
                 }
             }
diff --git a/app/design/adminhtml/Magento/backend/web/css/source/components/_popups.less b/app/design/adminhtml/Magento/backend/web/css/source/components/_popups.less
index abac708dc0eb592a27fde7f4d2ca8e198ab276fa..b6d5c27d02ce0a54374c1c8cfed44aa9b979dbcc 100644
--- a/app/design/adminhtml/Magento/backend/web/css/source/components/_popups.less
+++ b/app/design/adminhtml/Magento/backend/web/css/source/components/_popups.less
@@ -26,23 +26,23 @@
 
 @popup-overlay__background-color: rgba(0, 0, 0, .35);
 
+@popup-fieldset__margin-left: 34%;
+
 //
 //  Jquery UI popup window
 //  _____________________________________________
 
 .ui-dialog {
+    .appearing__off();
     background: @popup__background-color;
     min-width: 40%;
-    opacity: 0;
     transform: scale(0.7);
     transition: all 0.3s;
-    visibility: hidden;
     width: 75%;
 
     &.ui-dialog-active {
+        .appearing__on();
         transform: scale(1);
-        opacity: 1;
-        visibility: visible;
     }
 
     &.ui-draggable {
@@ -322,14 +322,13 @@
         > .admin__legend {
             float: none;
             font-size: 1.8rem;
-            margin: 0 0 2rem 34%;
+            margin: 0 0 @indent__base @popup-fieldset__margin-left;
             width: auto;
         }
-    }
-    .gift_options-popup {
-        .admin__fieldset {
-            > .admin__legend {
-                margin-left: 0;
+        .product-options {
+            margin-left: @popup-fieldset__margin-left;
+            .admin__field-control {
+                margin-bottom: @indent__base;
             }
         }
     }
diff --git a/app/design/adminhtml/Magento/backend/web/css/source/components/_tooltip-temp.less b/app/design/adminhtml/Magento/backend/web/css/source/components/_tooltip-temp.less
deleted file mode 100644
index 94e7125551a0a7cc3c696a2c5e618a7d052ef4fb..0000000000000000000000000000000000000000
--- a/app/design/adminhtml/Magento/backend/web/css/source/components/_tooltip-temp.less
+++ /dev/null
@@ -1,78 +0,0 @@
-// /**
-//  * Copyright © 2015 Magento. All rights reserved.
-//  * See COPYING.txt for license details.
-//  */
-
-//
-//  Main elements -> Tooltip
-//  _____________________________________________
-
-//  ToDo UI: Consist old styles, should be changed with new design
-
-//.tooltip {
-//    display: inline-block;
-//    margin-left: 5px;
-//    .help span,
-//    .help a {
-//        position: relative;
-//        z-index: 2;
-//        width: 22px;
-//        height: 22px;
-//        display: inline-block;
-//        vertical-align: middle;
-//        cursor: pointer;
-//        &:before {
-//            content: "?";
-//            font-weight: 500;
-//            font-size: 18px;
-//            display: inline-block;
-//            overflow: hidden;
-//            height: 22px;
-//            border-radius: 11px;
-//            line-height: 22px;
-//            width: 22px;
-//            text-align: center;
-//            color: #ffffff;
-//            background-color: #514943;
-//        }
-//        span {
-//            .visually-hidden();
-//        }
-//    }
-//    //  TODO Tooltips
-//    .tooltip-content {
-//        display: none;
-//        position: absolute;
-//        max-width: 200px;
-//        margin-top: 10px;
-//        margin-left: -19px;
-//        padding: 4px 8px;
-//        border-radius: 3px;
-//        background: #000;
-//        background: rgba(49, 48, 43, .8);
-//        color: #fff;
-//        text-shadow: none;
-//        z-index: 20;
-//        &:before {
-//            content: '';
-//            position: absolute;
-//            width: 0;
-//            height: 0;
-//            top: -5px;
-//            left: 20px;
-//            border-left: 5px solid transparent;
-//            border-right: 5px solid transparent;
-//            border-bottom: 5px solid #000;
-//            opacity: .8;
-//        }
-//        &.loading {
-//            position: absolute;
-//            &:before {
-//                border-bottom-color: rgba(0, 0, 0, .3);
-//            }
-//        }
-//    }
-//    &:hover > .tooltip-content {
-//        display: block;
-//    }
-//}
diff --git a/app/design/adminhtml/Magento/backend/web/css/source/forms/_checkbox-radio.less b/app/design/adminhtml/Magento/backend/web/css/source/forms/_checkbox-radio.less
new file mode 100644
index 0000000000000000000000000000000000000000..4ce5832e7c6e9ac8e913303c2d9008f4e8b3c7cb
--- /dev/null
+++ b/app/design/adminhtml/Magento/backend/web/css/source/forms/_checkbox-radio.less
@@ -0,0 +1,173 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Variables
+//  _____________________________________________
+
+@control-checkbox-radio__size: 1.6rem;
+@control-checkbox-radio__background-color: @color-white;
+@control-checkbox-radio-mark__color: @color-brownie;
+
+//  Checkbox & radio
+.admin__control-radio,
+.admin__control-checkbox {
+    cursor: pointer;
+    opacity: 0.01; // hack for successful selenium tests
+    overflow: hidden;
+    position: absolute;
+    vertical-align: top;
+    &:after { // ToDo UI: Should be deleted with old styles that generate styles for this element
+        display: none;
+    }
+    + label {
+        cursor: pointer;
+        display: inline-block;
+        &:before {
+            &:extend(.abs-icon all);
+            background-color: @control-checkbox-radio__background-color;
+            border: 1px solid @field-control__border-color;
+            color: transparent;
+            float: left;
+            height: @control-checkbox-radio__size;
+            text-align: center;
+            vertical-align: top;
+            width: @control-checkbox-radio__size;
+        }
+    }
+    //  Label with text content
+    + .admin__field-label {
+        padding-left: @control-checkbox-radio__size + @field-label__indent;
+        &:before {
+            margin: 1px @field-label__indent 0 -(@control-checkbox-radio__size + @field-label__indent);
+        }
+    }
+    //  Checked state
+    &:checked {
+        + label {
+            &:before {
+                color: @control-checkbox-radio-mark__color;
+            }
+        }
+    }
+    //  Disabled state
+    &.disabled,
+    &[disabled] {
+        + label {
+            cursor: default;
+            &:before {
+                background-color: @field-control__disabled__background-color;
+                border-color: @field-control__border-color;
+                cursor: default;
+            }
+            color: @field-control__color;
+            opacity: .5;
+        }
+    }
+    &:not([disabled]),
+    &:not(.disabled) {
+        //  Focus state
+        &:focus {
+            + label {
+                &:before {
+                    ._keyfocus & {
+                        border-color: @field-control__focus__border-color;
+                    }
+                }
+            }
+        }
+        //  Hover state
+        &:hover {
+            + label {
+                &:before {
+                    border-color: @field-control__hover__border-color;
+                }
+            }
+        }
+    }
+}
+
+//  Radio
+.admin__control-radio {
+    + label {
+        &:before {
+            border-radius: @control-checkbox-radio__size;
+            content: @icon-enable__content;
+            font-size: 1rem;
+            transition: @smooth__border-color, color .1s ease-in;
+        }
+    }
+    //  Discard extend line-height 1, to fix animation
+    &.admin__control-radio {
+        + label {
+            &:before {
+                line-height: 140%;
+            }
+        }
+    }
+    //  Radio checked state
+    &:checked {
+        &:not([disabled]),
+        &:not(.disabled) {
+            //  Prevent hover effects for checked radio
+            &:hover {
+                cursor: default;
+                + label {
+                    cursor: default;
+                    &:before {
+                        border-color: @field-control__border-color;
+                    }
+                }
+            }
+        }
+    }
+}
+
+//  Checkbox
+.admin__control-checkbox {
+    + label {
+        &:before {
+            border-radius: 1px;
+            content: '';
+            font-size: 0;
+            transition: font-size .1s ease-out, color .1s ease-out, @smooth__border-color;
+        }
+    }
+    &:checked {
+        + label {
+            &:before {
+                content: @icon-check-mage__content;
+                font-size: 1.1rem;
+                line-height: 125%;
+            }
+        }
+    }
+    &:not(:checked) {
+        &._indeterminate,
+        &:indeterminate {
+            + label {
+                &:before {
+                    color: @control-checkbox-radio-mark__color;
+                    content: '-';
+                    font-family: @font-family__base;
+                    font-size: @font-size__base;
+                    font-weight: @font-weight__bold;
+                }
+            }
+        }
+    }
+}
+
+//
+//  ToDo UI: Delete with old scope
+//  ---------------------------------------------
+
+input[type="checkbox"],
+input[type="radio"] {
+    &.admin__control-checkbox {
+        position: absolute;
+        margin: 0;
+    }
+}
diff --git a/app/design/adminhtml/Magento/backend/web/css/source/forms/_control-table.less b/app/design/adminhtml/Magento/backend/web/css/source/forms/_control-table.less
index 0a5bda543853f0f2734bcf8fbb3934469ac02eb2..4d4875471506fe522edf4ccb64282899c82a240d 100644
--- a/app/design/adminhtml/Magento/backend/web/css/source/forms/_control-table.less
+++ b/app/design/adminhtml/Magento/backend/web/css/source/forms/_control-table.less
@@ -52,4 +52,7 @@
             }
         }
     }
+    .action-delete {
+        &:extend(.abs-action-delete all);
+    }
 }
diff --git a/app/design/adminhtml/Magento/backend/web/css/source/forms/_controls.less b/app/design/adminhtml/Magento/backend/web/css/source/forms/_controls.less
index 6d6619c82ef5dc131ba6596b9cb36cf025615906..3c8edc32869948f9627bc02df3ba11f8db67a89d 100644
--- a/app/design/adminhtml/Magento/backend/web/css/source/forms/_controls.less
+++ b/app/design/adminhtml/Magento/backend/web/css/source/forms/_controls.less
@@ -11,16 +11,27 @@
 //  _____________________________________________
 
 @field-control__background-color: @color-white;
-@field-control__border-color: @color-gray68;
+@field-control__border-color: @action__border-color;
+@field-control__border-radius: 1px;
+@field-control__border-width: .1rem;
 @field-control__color: @color-very-dark-gray-black;
-@field-control__font-size: 1.4rem;
-@field-control__height: 3.3rem;
+@field-control__font-size: @action__font-size;
+@field-control__line-height: @action__line-height;
+@field-control__height: @action__height;
+@field-control__padding-top: @action__padding-top;
+@field-control__padding-horizontal: 1rem;
+@field-control__padding-bottom: @action__padding-bottom;
+
+@field-control__active__border-color: @field-control__focus__border-color;
+@field-control__hover__border-color: @action__hover__border-color;
+@field-control__focus__border-color: @color-blue-pure;
+@field-control__disabled__background-color: @color-lighter-gray;
+
 @field-control-addon__color: @color-gray52;
+
 @field-control-option-label__padding-left: 26px;
 
-//  States
-@field-control__disabled__background-color: @color-lighter-gray;
-@field-control__focus__border-color: @color-blue-pure;
+@field-label__indent: 1rem;
 @field-label__disabled__color: @color-gray60;
 @field-label__required__color: @color-phoenix;
 
@@ -32,26 +43,32 @@
 //  Common
 //  ---------------------------------------------
 
-.__form-control-styles() {
+.__form-control-pattern() {
     background-color: @field-control__background-color;
-    border-radius: .1rem;
-    border: 1px solid @field-control__border-color;
+    border-radius: @field-control__border-radius;
+    border: @field-control__border-width solid @field-control__border-color;
     color: @field-control__color;
     font-size: @field-control__font-size;
     font-weight: @font-weight__regular;
-    height: @field-control__height;
-    max-width: 100%;
-    padding: 0 1rem;
-    transition: border-color .1s ease-in;
+    line-height: @field-control__line-height;
+    height: auto;
+    width: auto;
+    padding: @field-control__padding-top @field-control__padding-horizontal @field-control__padding-bottom;
+    transition: @smooth__border-color;
+    vertical-align: baseline;
+}
+
+.__form-control-pattern__hover() {
+    border-color: @field-control__hover__border-color;
 }
 
-.__form-control-styles__focus() {
+.__form-control-pattern__focus() {
     border-color: @field-control__focus__border-color;
     box-shadow: none;
     outline: 0;
 }
 
-.__form-control-styles__disabled() {
+.__form-control-pattern__disabled() {
     background-color: @field-control__disabled__background-color;
     border-color: @field-control__border-color;
     color: @field-control__color;
@@ -61,14 +78,12 @@
 
 //  Input text styles
 .admin__control-text {
-    .extend__form-control-styles();
-    line-height: @field-control__height;
-    width: 100%;
+    &:extend(.abs-form-control-pattern all);
 }
 
 //  Select styles
 .admin__control-select {
-    .extend__form-control-styles();
+    &:extend(.abs-form-control-pattern all);
     .css(appearance, none, 1);
 
     background-repeat: no-repeat;
@@ -84,7 +99,14 @@
     background-position+: ~'calc(100% - 33px)' 0;
     background-size+: 1px 100%;
 
+    height: @field-control__height;
     padding-right: 4.4rem; // Distance between select switch and inner text
+    transition: @smooth__border-color;
+
+    &:hover {
+        border-color: @field-control__hover__border-color;
+        cursor: pointer;
+    }
 
     &:focus {
         background-image+: url('../images/arrows-bg.svg');
@@ -95,12 +117,14 @@
 
         background-image+: linear-gradient(@field-control__focus__border-color, @field-control__focus__border-color);
         background-position+: ~'calc(100% - 33px)' 0;
+        border-color: @field-control__focus__border-color;
     }
     &::-ms-expand {
         display: none;
     }
     .ie9 & {
-        padding-right: 0;
+        background-image: none;
+        padding-right: @field-control__padding-horizontal;
     }
 }
 
@@ -115,7 +139,7 @@ option:empty {
 
 //  Multiple select
 .admin__control-multiselect {
-    .extend__form-control-styles();
+    &:extend(.abs-form-control-pattern all);
     height: auto;
     padding: .6rem 1rem;
 }
@@ -128,20 +152,22 @@ option:empty {
     z-index: 1;
 }
 
-.admin__control-file-label:before {
-    &:extend(.__form-control-styles);
-    content:'';
-    left: 0;
-    position: absolute;
-    top: 0;
-    width: 100%;
-    z-index: 0;
-    .admin__control-file:active + &,
-    .admin__control-file:focus + & {
-        &:extend(.__form-control-styles:focus);
-    }
-    .admin__control-file[disabled] + & {
-        &:extend(.__form-control-styles[disabled]);
+.admin__control-file-label {
+    :before {
+        &:extend(.abs-form-control-pattern);
+        content:'';
+        left: 0;
+        position: absolute;
+        top: 0;
+        width: 100%;
+        z-index: 0;
+        .admin__control-file:active + &,
+        .admin__control-file:focus + & {
+            &:extend(.abs-form-control-pattern:focus);
+        }
+        .admin__control-file[disabled] + & {
+            &:extend(.abs-form-control-pattern[disabled]);
+        }
     }
 }
 
@@ -153,94 +179,35 @@ option:empty {
     width: auto;
 }
 
-//  Textarea
-.admin__control-textarea {
-    .extend__form-control-styles();
-    height: 8.48rem;
-    line-height: 1.18;
-    padding-top: .8rem;
-    resize: vertical;
-    width: 100%;
-}
+//
+//  Support text. Can be used on label or plain text to align controls & actions
+//  ---------------------------------------------
 
-//  Checkboxes and radios
-.admin__control-radio,
-.admin__control-checkbox {
-    cursor: pointer;
-    margin: .3rem 0 0;
-    opacity: 0.01; // hack for successful selenium tests
-    overflow: hidden;
-    position: absolute;
-    vertical-align: top;
-    + label {
-        cursor: pointer;
-        display: inline-block;
-        padding-left: @field-control-option-label__padding-left;
-
-        &:before {
-            background: @field-control__background-color;
-            border-radius: .2rem;
-            border: 1px solid @field-control__border-color;
-            color: transparent;
-            content: @icon-check-mage__content;
-            float: left;
-            font:  0/14px @icons-admin__font-name;
-            height: 1.6rem;
-            margin: 1px 10px 0 -26px;
-            text-align: center;
-            transition: border-color .1s ease-in, color .1s ease-in, font-size .1s ease-in;
-            vertical-align: top;
-            width: 1.6rem;
-        }
-    }
-    &:focus {
-         + label {
-            ._keyfocus & {
-                &:extend(._keyfocus *:focus);
-            }
-            &:before {
-                border-color: @field-control__focus__border-color;
-            }
-        }
-    }
-    &[disabled] {
-        + label {
-            &:before {
-                background-color: @field-control__disabled__background-color;
-                border-color: @field-control__border-color;
-            }
-            color: @field-control__color;
-            opacity: @disabled__opacity;
-        }
-    }
+.admin__control-support-text { // ToDo UI: should be renamed to .admin__control-text
+    border: @field-control__border-width solid transparent;
+    display: inline-block;
+    font-size: @field-control__font-size;
+    line-height: @field-control__line-height;
+    padding-top: @field-control__padding-top;
+    padding-bottom: @field-control__padding-bottom;
 }
 
-.admin__control-radio {
-    + label {
-        &:before {
-            border-radius: .8rem;
-            content: @icon-enable__content;
-        }
-    }
-    &:checked {
-        + label {
-            &:before {
-                color: @color-brownie;
-                font-size: 1rem;
-            }
-        }
+[class*='admin__control-'] {
+    + .admin__control-support-text {
+        margin-left: .7rem;
     }
 }
 
-.admin__control-checkbox {
-    &:checked {
-        + label {
-            &:before {
-                color: @color-brownie;
-                font-size: 1.1rem;
-            }
-        }
-    }
+//
+//  Textarea
+//  ---------------------------------------------
+
+.admin__control-textarea {
+    &:extend(.abs-form-control-pattern all);
+    height: 8.48rem;
+    line-height: 1.18;
+    padding-top: .8rem;
+    resize: vertical;
 }
 
 //  Control with additional prefix or suffix label
@@ -283,7 +250,7 @@ option:empty {
             }
         }
         & + [class*='admin__addon-']:before {
-            &:extend(.__form-control-styles);
+            &:extend(.abs-form-control-pattern);
             bottom: 0;
             box-sizing: border-box;
             content: '';
@@ -294,10 +261,10 @@ option:empty {
             z-index: 0;
         }
         &[disabled] + [class*='admin__addon-']:before {
-            &:extend(.__form-control-styles[disabled]);
+            &:extend(.abs-form-control-pattern[disabled]);
         }
         &:focus + [class*='admin__addon-']:before {
-            &:extend(.__form-control-styles:focus);
+            &:extend(.abs-form-control-pattern:focus);
         }
     }
 }
@@ -325,6 +292,7 @@ option:empty {
         order: 0;
     }
 }
+
 .ie9 {
     .admin__control-addon {
         &:after {
diff --git a/app/design/adminhtml/Magento/backend/web/css/source/forms/_dropdown.less b/app/design/adminhtml/Magento/backend/web/css/source/forms/_dropdown.less
deleted file mode 100644
index 47fec57d10e088af1bf6aaa03f602f389199accb..0000000000000000000000000000000000000000
--- a/app/design/adminhtml/Magento/backend/web/css/source/forms/_dropdown.less
+++ /dev/null
@@ -1,68 +0,0 @@
-// /**
-//  * Copyright © 2015 Magento. All rights reserved.
-//  * See COPYING.txt for license details.
-//  */
-
-//
-//  Forms -> Dropdown element
-//  _____________________________________________
-
-//
-//  Variables
-//  ---------------------------------------------
-
-@dropdown__color: @text__color;
-
-@dropdown-menu__hover__background-color: @color-blue-clear-sky;
-@dropdown-menu__active__background-color: darken(@color-blue-clear-sky, 5%);
-
-//
-//  Mixins
-//  ---------------------------------------------
-
-.dropdown-triangle (
-    @_dropdown__padding-right: 3rem;
-    @_triangle__width: .8rem;
-    @_triangle__height: .5rem;
-    @_triangle__color: @color-black;
-    @_triangle__hover__color: darken(@_triangle__color, 10%);
-    @_triangle__right: (@_dropdown__padding-right / 2) - (@_triangle__width / 2);
-) {
-    padding-right: @_dropdown__padding-right;
-    &._active,
-    &.active {
-        &:after {
-            transform: rotate(180deg);
-        }
-    }
-    &:after {
-        border-color: @_triangle__color transparent transparent transparent;
-        border-style: solid;
-        border-width: @_triangle__height @_triangle__width / 2 0 @_triangle__width / 2;
-        content: '';
-        height: 0;
-        margin-top: -((@_triangle__width / 2) / 2);
-        position: absolute;
-        right: @_triangle__right;
-        top: 50%;
-        transition: all .2s linear;
-        width: 0;
-        ._active &,
-        .active & {
-            transform: rotate(180deg);
-        }
-    }
-    &:hover {
-        &:after {
-            border-color: @_triangle__hover__color transparent transparent transparent;
-        }
-    }
-}
-
-//
-
-.admin__action-dropdown {
-    .action-reset();
-    .dropdown-triangle();
-    color: @dropdown__color;
-}
\ No newline at end of file
diff --git a/app/design/adminhtml/Magento/backend/web/css/source/forms/_extends.less b/app/design/adminhtml/Magento/backend/web/css/source/forms/_extends.less
index 699c2ba354eeb9fdf97406c9211242490823a08a..0a883946949c2fa22cdbdd52c5fd05a6a6d46934 100644
--- a/app/design/adminhtml/Magento/backend/web/css/source/forms/_extends.less
+++ b/app/design/adminhtml/Magento/backend/web/css/source/forms/_extends.less
@@ -7,23 +7,16 @@
 //  Extend common form control styles
 //  ---------------------------------------------
 
-.extend__form-control-styles() {
-    &:extend(.__form-control-styles);
-    &:focus {
-        &:extend(.__form-control-styles:focus);
-    }
-    &[disabled] {
-        &:extend(.__form-control-styles[disabled]);
+.abs-form-control-pattern {
+    .__form-control-pattern();
+    &:hover {
+        .__form-control-pattern__hover();
     }
-}
-
-.__form-control-styles {
-    .__form-control-styles();
     &:focus {
-        .__form-control-styles__focus();
+        .__form-control-pattern__focus();
     }
     &[disabled] {
-        .__form-control-styles__disabled();
+        .__form-control-pattern__disabled();
     }
 }
 
@@ -34,6 +27,7 @@
 .extend__field-rows() {
     &:extend(.abs-field-rows all);
 }
+
 .abs-field-rows[class] {
     > .admin__field-control {
         float: none;
diff --git a/app/design/adminhtml/Magento/backend/web/css/source/forms/_fields.less b/app/design/adminhtml/Magento/backend/web/css/source/forms/_fields.less
index f5ae9614e8a91894ab3da0d2197abc17a2893db9..def207f2a0bb7dab63a8eca3eab4cfd38b2e9652 100644
--- a/app/design/adminhtml/Magento/backend/web/css/source/forms/_fields.less
+++ b/app/design/adminhtml/Magento/backend/web/css/source/forms/_fields.less
@@ -28,13 +28,15 @@
 //  Form Fields
 //  _____________________________________________
 
+//
 //  Fieldset
+//  ---------------------------------------------
+
 .admin__fieldset {
     border: 0;
     margin: 0;
     min-width: 0;
     padding: 0;
-
     > .admin__field {
         border: 0;
         margin: 0;
@@ -54,7 +56,24 @@
     }
 }
 
+.admin__form-field {
+    border: 0;
+    margin: 0;
+    padding: 0;
+}
+
+.admin__form-field-control,
+.admin__field-control {
+    .admin__control-text,
+    .admin__control-textarea {
+        width: 100%;
+    }
+}
+
+//
 //  Label
+//  ---------------------------------------------
+
 .admin__field-label {
     color: @field-label__color;
     margin: 0;
@@ -64,7 +83,7 @@
         display: none;
     }
 
-    [class]:not(.admin__field-option) > & {
+    .admin__field:not(.admin__field-option) > & {
         font-family: @font-family__base;
         font-size: @field-label__font-size;
         font-weight: @font-weight__semibold;
@@ -74,11 +93,10 @@
         word-wrap: break-word;
 
         &:before {
+            .appearing__off();
             content: '.';
             margin-left: -7px;
             overflow: hidden;
-            visibility: hidden;
-            width: 0;
         }
 
         span {
@@ -109,7 +127,10 @@
     }
 }
 
+//
 //  Field
+//  ---------------------------------------------
+
 .admin__field {
     margin-bottom: 0;
 
@@ -163,13 +184,16 @@
         }
     }
 }
-
 .admin__field-control {
     & + & {
         margin-top: 1.5rem;
     }
 }
 
+//
+//  Field messages
+//  ---------------------------------------------
+
 //  Field error message
 .admin__field-error {
     background: @field-error-message__background-color;
diff --git a/app/design/adminhtml/Magento/backend/web/css/source/forms/_tooltip.less b/app/design/adminhtml/Magento/backend/web/css/source/forms/_tooltip.less
index dbb52ffa5d3b74aec7574b566ef5ff1e3858536d..67fb5f3926aac1a7e8ee4790987f2a951641a250 100644
--- a/app/design/adminhtml/Magento/backend/web/css/source/forms/_tooltip.less
+++ b/app/design/adminhtml/Magento/backend/web/css/source/forms/_tooltip.less
@@ -44,24 +44,16 @@
         display: block;
     }
     .admin__field-tooltip-content {
-        @_shadow: 0 2px 8px 0 rgba(0, 0, 0, .3);
-        .css(box-shadow, @_shadow);
-        background: @field-tooltip-content__background-color;
-        border-radius: 1px;
-        border: 1px solid @field-tooltip-content__border-color;
+        &:extend(.abs-admin__field-tooltip-content all);
         bottom: 42px;
         display: none;
-        padding: 15px 25px;
-        position: absolute;
         right: -70px;
-        width: 320px;
-        z-index: 1;
         &:after,
         &:before {
             .arrow(
-                @_position: down,
-                @_size: 16px,
-                @_color: @field-tooltip-content__border-color
+            @_position: down,
+            @_size: 16px,
+            @_color: @field-tooltip-content__border-color
             );
             content: "";
             display: block;
@@ -77,3 +69,15 @@
         }
     }
 }
+
+.abs-admin__field-tooltip-content {
+    @_shadow: 0 2px 8px 0 rgba(0, 0, 0, .3);
+    .css(box-shadow, @_shadow);
+    background: @field-tooltip-content__background-color;
+    border-radius: 1px;
+    border: 1px solid @field-tooltip-content__border-color;
+    padding: 15px 25px;
+    position: absolute;
+    width: 320px;
+    z-index: 1;
+}
diff --git a/app/design/adminhtml/Magento/backend/web/css/source/variables/_actions.less b/app/design/adminhtml/Magento/backend/web/css/source/variables/_actions.less
new file mode 100644
index 0000000000000000000000000000000000000000..6cb821a11a68f5e895607cd5a8c21224807ad21f
--- /dev/null
+++ b/app/design/adminhtml/Magento/backend/web/css/source/variables/_actions.less
@@ -0,0 +1,22 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Actions
+//  _____________________________________________
+
+@action__border-color: @color-gray68;
+@action__font-size: @font-size__base;
+@action__line-height: @line-height__base;
+@action__padding-top: round(((@field-control__height - @field-control__font-size * @field-control__line-height - @field-control__border-width * 2) / 2), 1);
+@action__padding-bottom: @field-control__padding-top;
+@action__height: 3.3rem;
+
+@action__active__border-color: @color-blue-pure; // Not the same as @button__hover__border-color
+@action__hover__background-color: @color-blue-clear-sky;
+@action__hover__border-color: darken(@action__border-color, 15%);
+
+//  Actions menu
+@action-menu__hover__background-color: @color-gray89;
diff --git a/app/design/adminhtml/Magento/backend/web/css/source/variables/_animations.less b/app/design/adminhtml/Magento/backend/web/css/source/variables/_animations.less
index 1284a440a9e5229d53ec39b228c23ea3d3f15d64..986647aefd2700ca241759e9b6b238288270a7b9 100644
--- a/app/design/adminhtml/Magento/backend/web/css/source/variables/_animations.less
+++ b/app/design/adminhtml/Magento/backend/web/css/source/variables/_animations.less
@@ -7,5 +7,9 @@
 //  Transitions
 //  _____________________________________________
 
-@appering__transition-duration: .15s;
+@appearing__transition-duration: .15s;
 @apperaing__transition-timing-function: ease;
+
+@smooth__color: color .1s linear;
+@smooth__background-color: background-color .1s linear;
+@smooth__border-color: border-color .1s linear;
diff --git a/app/design/adminhtml/Magento/backend/web/css/source/variables/_colors.less b/app/design/adminhtml/Magento/backend/web/css/source/variables/_colors.less
index 61823ceffe0be26f3e8d9bea2908fee156846cc2..80492cbd3cd378486cdda5de768ebb8eb4152145 100644
--- a/app/design/adminhtml/Magento/backend/web/css/source/variables/_colors.less
+++ b/app/design/adminhtml/Magento/backend/web/css/source/variables/_colors.less
@@ -21,6 +21,7 @@
 @color-very-dark-gray1: #777;
 @color-brownie-vanilla: #736963;
 @color-dark-gray: #808080;
+@color-darkie-gray: #8a837f;
 @color-gray65: #a6a6a6;
 @color-gray65-almost: #a79d95;
 @color-gray65-lighten: #aaa6a0;
@@ -38,6 +39,7 @@
 @color-very-light-gray: #fcfcfc;
 @color-ivory: #f7f3eb;
 @color-white-fog2: #f1f1f1;
+@color-lazy-sun-white: #fffbe6;
 @color-lazy-sun: #fffbbb;
 @color-lazy-sunny: #fff1ad;
 
diff --git a/app/design/adminhtml/Magento/backend/web/css/source/variables/_structure.less b/app/design/adminhtml/Magento/backend/web/css/source/variables/_structure.less
index 2e081b044437fa866129b1d5b83ac9b6e736bf24..65feb808800fdab0b5f6636f193159003226bf11 100644
--- a/app/design/adminhtml/Magento/backend/web/css/source/variables/_structure.less
+++ b/app/design/adminhtml/Magento/backend/web/css/source/variables/_structure.less
@@ -33,8 +33,12 @@
 @z-index-9: 900;
 @z-index-10: 1000;
 
+// z-index 2
+@actions-split__z-index: @z-index-2;
+@action-multiselect__z-index: @z-index-2;
+
 // z-index 3
-@split-button__z-index: @z-index-3;
+@data-grid-header__z-index: @z-index-3;
 
 // z-index 4
 @header__z-index: @z-index-4;
@@ -63,3 +67,5 @@
 
 @component__shadow-size__base: 5px;
 @component__box-shadow__base: 1px 1px @component__shadow-size__base rgba(0, 0, 0, .5);
+
+@component-modal__opacity: .98;
diff --git a/app/design/adminhtml/Magento/backend/web/css/source/variables/_typography.less b/app/design/adminhtml/Magento/backend/web/css/source/variables/_typography.less
index fa70769896ebb837737830e6ab90f4a4c4ada786..95422456d853c3239a80cf9bdbd14df5bdd0485e 100644
--- a/app/design/adminhtml/Magento/backend/web/css/source/variables/_typography.less
+++ b/app/design/adminhtml/Magento/backend/web/css/source/variables/_typography.less
@@ -17,6 +17,7 @@
 @font-size__l: 1.6rem;
 @font-size__base: 1.4rem;
 @font-size__s: 1.2rem;
+@font-size__tiny: 1.1rem;
 @font-size__xs: 1rem;
 
 @line-height__base: 1.4;
diff --git a/app/design/adminhtml/Magento/backend/web/css/styles-old.less b/app/design/adminhtml/Magento/backend/web/css/styles-old.less
index f6b0cff9e7c8de6cddad3de71d5e7484d8d2aa14..77fb1698576b0de4f3115cf7906241a6e82e5e9e 100644
--- a/app/design/adminhtml/Magento/backend/web/css/styles-old.less
+++ b/app/design/adminhtml/Magento/backend/web/css/styles-old.less
@@ -2013,13 +2013,9 @@ input.no-display,
         }
     }
 
-    .col-2-left-layout,
-    .col-1-layout {
+    .col-2-left-layout {
         margin: 0 auto;
         position: relative;
-    }
-
-    .col-2-left-layout {
         &:before {
             position: absolute;
             content: "";
@@ -3167,8 +3163,7 @@ input.no-display,
         border-radius: 5px;
     }
 
-    .adminhtml-rma-new .order-totals,
-    .order-comments-history .order-comments-history {
+    .adminhtml-rma-new .order-totals {
         float: none;
         width: 100%;
     }
@@ -3312,40 +3307,6 @@ input.no-display,
         }
     }
 
-    //
-    //  Order view
-    // --------------------------------------
-
-    .order-comments-history fieldset {
-        border: 0;
-        margin: 0;
-        padding: 0;
-    }
-
-    .order-comments-history textarea,
-    .rma-history-form textarea {
-        height: 6em;
-        margin: 5px 0 10px;
-        resize: vertical;
-        width: 100%;
-    }
-
-    .order-comments-history input[type="checkbox"] {
-        margin-right: 5px;
-    }
-
-    .order-history-comments-options {
-        float: left;
-    }
-
-    .order-comments-history .actions {
-        float: right;
-    }
-
-    [class*="-order-"] .fieldset-wrapper address {
-        overflow: auto;
-    }
-
     //
     //  Orders comments
     //--------------------------------------
@@ -4077,6 +4038,12 @@ input.no-display,
         display: none;
     }
 
+    .section-config > .config {
+        &.collapseable {
+            display: none;
+        }
+    }
+
     .accordion > dt.open,
     .section-config.active > .collapseable,
     .accordion .collapseable.open {
@@ -4797,7 +4764,6 @@ input.no-display,
     .page-layout-admin-1column .page-columns,
     .catalog-product-edit,
     .catalog-product-new,
-    .sales-order-view,
     .catalog-category-edit {
         table.data {
             table-layout: fixed;
@@ -4822,7 +4788,6 @@ input.no-display,
     .custom-options .data-table,
     .ui-dialog .data,
     .page-layout-admin-1column .page-columns .data,
-    .sales-order-view .data,
     .catalog-category-edit .data {
         word-wrap: break-word;
         table-layout: fixed;
@@ -5074,8 +5039,6 @@ input.no-display,
     }
 }
 
-[class*="-order-"] .admin__scope-old .order-history,
-[class*="-order-"] .admin__scope-old .order-comments-history,
 [class*="-order-"] .admin__scope-old .order-information,
 [class*="-order-"] .admin__scope-old .order-billing-address,
 [class*="-order-"] .admin__scope-old .order-payment-method,
@@ -5302,19 +5265,6 @@ input.no-display,
     }
 }
 
-.sales-order-view {
-    .admin__scope-old {
-        .grid  {
-            .col-name {
-                &:extend(.col-150-max all);
-            }
-            .col-period {
-                &:extend(.col-70-max all);
-            }
-        }
-    }
-}
-
 .sales-order-index {
     .admin__scope-old {
         .grid .col-name {
@@ -5377,15 +5327,6 @@ input.no-display,
     }
 }
 
-//  Sales -> View order
-[class^=' sales-order-view'] {
-    .admin__scope-old {
-        .grid .col-customer_name {
-            &:extend(.col-110-max all);
-        }
-    }
-}
-
 //  Sales -> Return
 [class^=' adminhtml-rma-'] {
     .admin__scope-old {
diff --git a/app/design/adminhtml/Magento/backend/web/css/styles.less b/app/design/adminhtml/Magento/backend/web/css/styles.less
index 8b9bd439e270c0f7b8b660df3c255c3b3478f761..f4f585880c7d9d1ce9db56cf76d391b57063fb40 100644
--- a/app/design/adminhtml/Magento/backend/web/css/styles.less
+++ b/app/design/adminhtml/Magento/backend/web/css/styles.less
@@ -22,12 +22,11 @@
 
 //@magento_import "source/_module.less"; // import theme styles
 
-
 //
 //  Temporary
 //  ---------------------------------------------
 
-// ToDo UI: Hiding menu (should be fixed in layouts)
+//  ToDo UI: Hiding menu (should be fixed in layouts)
 .attribute-popup {
     .page-wrapper {
         margin-left: 0;
@@ -39,7 +38,17 @@
     }
 }
 
-// ToDo UI: Temporary. Should be changed
+[class*='admin__'] {
+    + label,
+    + label:after,
+    + label:before,
+    &:before,
+    &:after {
+        box-sizing: border-box;
+    }
+}
+
+//  ToDo UI: Temporary. Should be changed
 @import 'source/components/_calendar-temp.less';
 
 //
diff --git a/app/design/adminhtml/Magento/backend/web/mui/styles/table.less b/app/design/adminhtml/Magento/backend/web/mui/styles/table.less
index 55d1128d73b7506a05226dcfbb6c9c5c44424bbc..574b9f0754306f96ac3c0950e8ae82bd2c74a046 100644
--- a/app/design/adminhtml/Magento/backend/web/mui/styles/table.less
+++ b/app/design/adminhtml/Magento/backend/web/mui/styles/table.less
@@ -67,29 +67,13 @@ table {
 }
 
 //
-//    Grid table header filters and settings
-//--------------------------------------
-
-.grid-actions,
-.pager,
-.massaction,
-.filter {
-    .input-text,
-    select,
-    .select {
-        margin: 0 10px 0 0;
-    }
-}
+//  Table Filters
+//  --------------------------------------
 
-//
-//    Table Filters
-//--------------------------------------
 .filter {
-    select {
-        width: 99%;
-    }
     input.input-text {
         width: 99%;
+        margin-right: 0;
         &::-webkit-input-placeholder {
             color: @grid-filters-placeholder-color !important;
             text-transform: lowercase;
diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/_minicart.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/_minicart.less
index d8d0b25cb90f10fa092cc096fec35d72c733fce6..486f1232621403da649c372f7f5237908cbd5e5a 100644
--- a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/_minicart.less
+++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/_minicart.less
@@ -197,9 +197,6 @@
         &:first-child {
             padding-top: 0;
         }
-        &:last-child {
-            padding-bottom: 0;
-        }
         > .product {
             &:extend(.abs-add-clearfix all);
         }
@@ -242,6 +239,9 @@
                 @_icon-font-margin: -3px 0 0 7px,
                 @_icon-font-position: after
             );
+            .details {
+                display: none;
+            }
         }
     }
     .details-qty,
diff --git a/app/design/frontend/Magento/blank/composer.json b/app/design/frontend/Magento/blank/composer.json
index 2a04bfacb343d811febc36cc9be67b7254e3eb41..f4cade65a82198127de39ab5b9f923dc8cb046ca 100644
--- a/app/design/frontend/Magento/blank/composer.json
+++ b/app/design/frontend/Magento/blank/composer.json
@@ -3,11 +3,11 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/framework": "0.74.0-beta6",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-theme",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_minicart.less b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_minicart.less
index 3a65f3be3f3055aca8770b2ec9b94145206a63fc..365f03d8f28a56c51d26d921cb5168a0daa74983 100644
--- a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_minicart.less
+++ b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_minicart.less
@@ -205,9 +205,6 @@
         &:first-child {
             padding-top: 0;
         }
-        &:last-child {
-            padding-bottom: 0;
-        }
         > .product {
             &:extend(.abs-add-clearfix all);
         }
@@ -273,6 +270,9 @@
                     @_icon-font-position: after
                 );
             }
+            .details {
+                display: none;
+            }
         }
     }
     .details-qty,
diff --git a/app/design/frontend/Magento/luma/composer.json b/app/design/frontend/Magento/luma/composer.json
index 8fa8ad3aa9e7c50206b59568b7faff068e12c61b..a402aecdcb5bc449edca9a7263e1b4043526b036 100644
--- a/app/design/frontend/Magento/luma/composer.json
+++ b/app/design/frontend/Magento/luma/composer.json
@@ -3,12 +3,12 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/theme-frontend-blank": "0.74.0-beta6",
-        "magento/framework": "0.74.0-beta6",
+        "magento/theme-frontend-blank": "0.74.0-beta7",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-theme",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/etc/di.xml b/app/etc/di.xml
index 10095a200e3bc10329a48f6a95c1fd40faa49012..7ffd8702c787b917c82fb2073953559106c98119 100755
--- a/app/etc/di.xml
+++ b/app/etc/di.xml
@@ -400,7 +400,7 @@
             <argument name="readers" xsi:type="array">
                 <item name="container" xsi:type="string">Magento\Framework\View\Layout\Reader\Container</item>
                 <item name="block" xsi:type="string">Magento\Framework\View\Layout\Reader\Block</item>
-                <item name="ui_component" xsi:type="string">Magento\Framework\View\Layout\Reader\UiComponent</item>
+                <item name="uiComponent" xsi:type="string">Magento\Framework\View\Layout\Reader\UiComponent</item>
             </argument>
         </arguments>
     </virtualType>
@@ -416,7 +416,7 @@
                 <item name="block" xsi:type="string">Magento\Framework\View\Layout\Reader\Block</item>
                 <item name="move" xsi:type="string">Magento\Framework\View\Layout\Reader\Move</item>
                 <item name="remove" xsi:type="string">Magento\Framework\View\Layout\Reader\Remove</item>
-                <item name="ui_component" xsi:type="string">Magento\Framework\View\Layout\Reader\UiComponent</item>
+                <item name="uiComponent" xsi:type="string">Magento\Framework\View\Layout\Reader\UiComponent</item>
             </argument>
         </arguments>
     </virtualType>
@@ -440,7 +440,7 @@
                 <item name="block" xsi:type="string">Magento\Framework\View\Layout\Reader\Block</item>
                 <item name="move" xsi:type="string">Magento\Framework\View\Layout\Reader\Move</item>
                 <item name="remove" xsi:type="string">Magento\Framework\View\Layout\Reader\Remove</item>
-                <item name="ui_component" xsi:type="string">Magento\Framework\View\Layout\Reader\UiComponent</item>
+                <item name="uiComponent" xsi:type="string">Magento\Framework\View\Layout\Reader\UiComponent</item>
             </argument>
         </arguments>
     </virtualType>
@@ -459,7 +459,7 @@
                 <item name="block" xsi:type="string">Magento\Framework\View\Layout\Reader\Block</item>
                 <item name="move" xsi:type="string">Magento\Framework\View\Layout\Reader\Move</item>
                 <item name="remove" xsi:type="string">Magento\Framework\View\Layout\Reader\Remove</item>
-                <item name="ui_component" xsi:type="string">Magento\Framework\View\Layout\Reader\UiComponent</item>
+                <item name="uiComponent" xsi:type="string">Magento\Framework\View\Layout\Reader\UiComponent</item>
             </argument>
         </arguments>
     </virtualType>
@@ -476,7 +476,7 @@
                 <item name="block" xsi:type="string">Magento\Framework\View\Layout\Reader\Block</item>
                 <item name="move" xsi:type="string">Magento\Framework\View\Layout\Reader\Move</item>
                 <item name="remove" xsi:type="string">Magento\Framework\View\Layout\Reader\Remove</item>
-                <item name="ui_component" xsi:type="string">Magento\Framework\View\Layout\Reader\UiComponent</item>
+                <item name="uiComponent" xsi:type="string">Magento\Framework\View\Layout\Reader\UiComponent</item>
             </argument>
         </arguments>
     </virtualType>
@@ -501,7 +501,7 @@
                 <item name="body" xsi:type="object">Magento\Framework\View\Page\Config\Generator\Body</item>
                 <item name="block" xsi:type="object">Magento\Framework\View\Layout\Generator\Block</item>
                 <item name="container" xsi:type="object">Magento\Framework\View\Layout\Generator\Container</item>
-                <item name="ui_component" xsi:type="object">Magento\Framework\View\Layout\Generator\UiComponent</item>
+                <item name="uiComponent" xsi:type="object">Magento\Framework\View\Layout\Generator\UiComponent</item>
             </argument>
         </arguments>
     </type>
@@ -512,7 +512,7 @@
                 <item name="body" xsi:type="object">Magento\Framework\View\Page\Config\Generator\Body</item>
                 <item name="block" xsi:type="object">Magento\Framework\View\Layout\Generator\Block</item>
                 <item name="container" xsi:type="object">Magento\Framework\View\Layout\Generator\Container</item>
-                <item name="ui_component" xsi:type="object">Magento\Framework\View\Layout\Generator\UiComponent</item>
+                <item name="uiComponent" xsi:type="object">Magento\Framework\View\Layout\Generator\UiComponent</item>
             </argument>
         </arguments>
     </virtualType>
@@ -964,6 +964,11 @@
             </argument>
         </arguments>
     </type>
+    <type name="Magento\Framework\Object\Copy\Config">
+        <arguments>
+            <argument name="dataStorage" xsi:type="object">Magento\Framework\Object\Copy\Config\Data\Proxy</argument>
+        </arguments>
+    </type>
     <type name="Magento\Framework\Object\Copy\Config\Reader">
         <arguments>
             <argument name="fileName" xsi:type="string">fieldset.xml</argument>
@@ -1101,4 +1106,9 @@
             </argument>
         </arguments>
     </type>
+    <type name="Magento\Framework\Url\Decoder">
+        <arguments>
+            <argument name="urlBuilder" xsi:type="object">Magento\Framework\UrlInterface\Proxy</argument>
+        </arguments>
+    </type>
 </config>
diff --git a/app/i18n/magento/de_de/composer.json b/app/i18n/magento/de_de/composer.json
index 3348716f124bbb1283aca8365bee6dc1653f53b6..d1331eacdfd3c24651ca62a9c24998294c5fef7f 100644
--- a/app/i18n/magento/de_de/composer.json
+++ b/app/i18n/magento/de_de/composer.json
@@ -1,13 +1,13 @@
 {
     "name": "magento/language-de_de",
     "description": "German (Germany) language",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
     ],
     "require": {
-        "magento/framework": "0.74.0-beta6",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-language",
diff --git a/app/i18n/magento/en_us/composer.json b/app/i18n/magento/en_us/composer.json
index 54427d660fa30d9bae85106145c1486e6e04189d..7ba926a7e7f131d32dcc6970e6a8e5354f1b9de0 100644
--- a/app/i18n/magento/en_us/composer.json
+++ b/app/i18n/magento/en_us/composer.json
@@ -1,13 +1,13 @@
 {
     "name": "magento/language-en_us",
     "description": "English (United States) language",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
     ],
     "require": {
-        "magento/framework": "0.74.0-beta6",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-language",
diff --git a/app/i18n/magento/es_es/composer.json b/app/i18n/magento/es_es/composer.json
index de93f29f35665cc28056a6bd9d273ac9a85cf89c..7499abd7c6c5e1e7f99c0aafa4db0235b5313dd5 100644
--- a/app/i18n/magento/es_es/composer.json
+++ b/app/i18n/magento/es_es/composer.json
@@ -1,13 +1,13 @@
 {
     "name": "magento/language-es_es",
     "description": "Spanish (Spain) language",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
     ],
     "require": {
-        "magento/framework": "0.74.0-beta6",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-language",
diff --git a/app/i18n/magento/fr_fr/composer.json b/app/i18n/magento/fr_fr/composer.json
index 57c2be2ed896269ff4140ad4c4970cb450ba2b67..17a7589ee6a23fde6f076caba6a050244d4be4d3 100644
--- a/app/i18n/magento/fr_fr/composer.json
+++ b/app/i18n/magento/fr_fr/composer.json
@@ -1,13 +1,13 @@
 {
     "name": "magento/language-fr_fr",
     "description": "French (France) language",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
     ],
     "require": {
-        "magento/framework": "0.74.0-beta6",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-language",
diff --git a/app/i18n/magento/nl_nl/composer.json b/app/i18n/magento/nl_nl/composer.json
index 12c4f56f07432845832714823d15a4f34d8e4b10..38bd3b93c1f0670ba4cc1bcddfd8411834492f4a 100644
--- a/app/i18n/magento/nl_nl/composer.json
+++ b/app/i18n/magento/nl_nl/composer.json
@@ -1,13 +1,13 @@
 {
     "name": "magento/language-nl_nl",
     "description": "Dutch (Netherlands) language",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
     ],
     "require": {
-        "magento/framework": "0.74.0-beta6",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-language",
diff --git a/app/i18n/magento/pt_br/composer.json b/app/i18n/magento/pt_br/composer.json
index cc1a364b3dde8fba1615b23368ee82f4041da639..240415c9b81456f5a57fdb00cafcabcb1a312639 100644
--- a/app/i18n/magento/pt_br/composer.json
+++ b/app/i18n/magento/pt_br/composer.json
@@ -1,13 +1,13 @@
 {
     "name": "magento/language-pt_br",
     "description": "Portuguese (Brazil) language",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
     ],
     "require": {
-        "magento/framework": "0.74.0-beta6",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-language",
diff --git a/app/i18n/magento/zh_cn/composer.json b/app/i18n/magento/zh_cn/composer.json
index 1088c0e650ce72ad7a50a07957c4571f156913f2..28227ddf118f2d71115548176e258f08116a2f0c 100644
--- a/app/i18n/magento/zh_cn/composer.json
+++ b/app/i18n/magento/zh_cn/composer.json
@@ -1,13 +1,13 @@
 {
     "name": "magento/language-zh_cn",
     "description": "Chinese (China) language",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
     ],
     "require": {
-        "magento/framework": "0.74.0-beta6",
+        "magento/framework": "0.74.0-beta7",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-language",
diff --git a/composer.json b/composer.json
index e99f901fde5affb0c5023710e7e9d788421aa9d0..4424cb729baf30a8a1b65ed83e644d65296a9e96 100644
--- a/composer.json
+++ b/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/magento2ce",
     "description": "Magento 2 (Community Edition)",
     "type": "project",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/composer.lock b/composer.lock
index a4498fe8e6dc972a67cd464639b3f4a7619783fd..1458a41878a67fefec425b795aad2b31fbfde8ab 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
         "This file is @generated automatically"
     ],
-    "hash": "ff2c069b557199903bafc88e8abe0cea",
+    "hash": "eb32c28075b2f343240b21d18a62385e",
     "packages": [
         {
             "name": "composer/composer",
diff --git a/dev/tests/api-functional/_files/Magento/TestModule1/etc/data_object.xml b/dev/tests/api-functional/_files/Magento/TestModule1/etc/service_data_attributes.xml
similarity index 69%
rename from dev/tests/api-functional/_files/Magento/TestModule1/etc/data_object.xml
rename to dev/tests/api-functional/_files/Magento/TestModule1/etc/service_data_attributes.xml
index de2236e2195f380aedd5614447065bc9e480f7aa..fa96514a063b6112004e7a6073a2cc131a87f44c 100644
--- a/dev/tests/api-functional/_files/Magento/TestModule1/etc/data_object.xml
+++ b/dev/tests/api-functional/_files/Magento/TestModule1/etc/service_data_attributes.xml
@@ -5,13 +5,13 @@
  * See COPYING.txt for license details.
  */
 -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/Api/etc/data_object.xsd">
-    <custom_attributes for="Magento\TestModule1\Service\V1\Entity\Item">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/Api/etc/service_data_attributes.xsd">
+    <extension_attributes for="Magento\TestModule1\Service\V1\Entity\Item">
         <attribute code="custom_attribute_data_object" type="Magento\TestModuleMSC\Model\Data\CustomAttributeDataObject" />
         <attribute code="custom_attribute_string" type="string" />
-    </custom_attributes>
-    <custom_attributes for="Magento\TestModuleMSC\Model\Data\CustomAttributeDataObject">
+    </extension_attributes>
+    <extension_attributes for="Magento\TestModuleMSC\Model\Data\CustomAttributeDataObject">
         <attribute code="custom_attribute_nested" type="Magento\TestModuleMSC\Model\Data\CustomAttributeNestedDataObject" />
         <attribute code="custom_attribute_int" type="int" />
-    </custom_attributes>
+    </extension_attributes>
 </config>
diff --git a/dev/tests/api-functional/_files/Magento/TestModuleMSC/etc/data_object.xml b/dev/tests/api-functional/_files/Magento/TestModuleMSC/etc/service_data_attributes.xml
similarity index 69%
rename from dev/tests/api-functional/_files/Magento/TestModuleMSC/etc/data_object.xml
rename to dev/tests/api-functional/_files/Magento/TestModuleMSC/etc/service_data_attributes.xml
index ece2b1f581775daa25e1acec4f4fc120a876c431..f11e639ccd2753296d65071cf32f3e5fb47e0e7d 100644
--- a/dev/tests/api-functional/_files/Magento/TestModuleMSC/etc/data_object.xml
+++ b/dev/tests/api-functional/_files/Magento/TestModuleMSC/etc/service_data_attributes.xml
@@ -5,13 +5,13 @@
  * See COPYING.txt for license details.
  */
 -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/Api/etc/data_object.xsd">
-    <custom_attributes for="Magento\TestModuleMSC\Api\Data\ItemInterface">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/Api/etc/service_data_attributes.xsd">
+    <extension_attributes for="Magento\TestModuleMSC\Api\Data\ItemInterface">
         <attribute code="custom_attribute_data_object" type="Magento\TestModuleMSC\Api\Data\CustomAttributeDataObjectInterface" />
         <attribute code="custom_attribute_string" type="string" />
-    </custom_attributes>
-    <custom_attributes for="Magento\TestModuleMSC\Api\Data\CustomAttributeDataObjectInterface">
+    </extension_attributes>
+    <extension_attributes for="Magento\TestModuleMSC\Api\Data\CustomAttributeDataObjectInterface">
         <attribute code="custom_attribute_nested" type="Magento\TestModuleMSC\Api\Data\CustomAttributeNestedDataObjectInterface" />
         <attribute code="custom_attribute_int" type="int" />
-    </custom_attributes>
+    </extension_attributes>
 </config>
diff --git a/dev/tests/api-functional/config/install-config-mysql.php.dist b/dev/tests/api-functional/config/install-config-mysql.php.dist
index 535cfb7232e8f1ef2a58a98916fe49b98bea5d6a..2f19ce10e80503908aadeea6ddaca761808bb4f3 100644
--- a/dev/tests/api-functional/config/install-config-mysql.php.dist
+++ b/dev/tests/api-functional/config/install-config-mysql.php.dist
@@ -9,22 +9,22 @@ return [
     'language'                     => 'en_US',
     'timezone'                     => 'America/Los_Angeles',
     'currency'                     => 'USD',
-    'db_host'                      => 'localhost',
-    'db_name'                      => 'magento_functional_tests',
-    'db_user'                      => 'root',
-    'db_password'                  => '',
-    'backend_frontname'            => 'backend',
-    'base_url'                     => 'http://localhost/',
-    'use_secure'                   => '0',
-    'use_rewrites'                 => '0',
-    'admin_lastname'               => 'Admin',
-    'admin_firstname'              => 'Admin',
-    'admin_email'                  => 'admin@example.com',
-    'admin_user'                   => 'admin',
-    'admin_password'               => '123123q',
-    'admin_use_security_key'       => '0',
+    'db-host'                      => 'localhost',
+    'db-name'                      => 'magento_functional_tests',
+    'db-user'                      => 'root',
+    'db-password'                  => '',
+    'backend-frontname'            => 'backend',
+    'base-url'                     => 'http://localhost/',
+    'use-secure'                   => '0',
+    'use-rewrites'                 => '0',
+    'admin-lastname'               => 'Admin',
+    'admin-firstname'              => 'Admin',
+    'admin-email'                  => 'admin@example.com',
+    'admin-user'                   => 'admin',
+    'admin-password'               => '123123q',
+    'admin-use-security-key'       => '0',
     /* PayPal has limitation for order number - 20 characters. 10 digits prefix + 8 digits number is good enough */
-    'sales_order_increment_prefix' => time(),
-    'session_save'                 => 'db',
-    'cleanup_database'             => true,
+    'sales-order-increment-prefix' => time(),
+    'session-save'                 => 'db',
+    'cleanup-database'             => true,
 ];
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php
index fb6588a7f4107cf2ff07095ff3820e442ee10a87..a0f06e0ce7aac3fa6752c18a2adb47af1ba2e544 100644
--- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php
@@ -126,7 +126,6 @@ class ProductRepositoryInterfaceTest extends WebapiAbstract
 
     public function testProductLinks()
     {
-        $this->markTestSkipped('Skipped until MAGETWO-35458 is ready');
         // Create simple product
         $productData =  [
             ProductInterface::SKU => "product_simple_500",
@@ -140,9 +139,10 @@ class ProductRepositoryInterfaceTest extends WebapiAbstract
         ];
 
         $this->saveProduct($productData);
+
         $productLinkData = ["product_sku" => "product_simple_with_related_500", "link_type" => "related",
                             "linked_product_sku" => "product_simple_500", "linked_product_type" => "simple",
-                            "position" => 0];
+                            "position" => 0, "extension_attributes" => []];
         $productWithRelatedData =  [
             ProductInterface::SKU => "product_simple_with_related_500",
             ProductInterface::NAME => "Product Simple with Related 500",
@@ -166,7 +166,7 @@ class ProductRepositoryInterfaceTest extends WebapiAbstract
         // update link information
         $productLinkData = ["product_sku" => "product_simple_with_related_500", "link_type" => "upsell",
                             "linked_product_sku" => "product_simple_500", "linked_product_type" => "simple",
-                            "position" => 0];
+                            "position" => 0, "extension_attributes" => []];
         $productWithUpsellData =  [
             ProductInterface::SKU => "product_simple_with_related_500",
             ProductInterface::NAME => "Product Simple with Related 500",
@@ -174,7 +174,6 @@ class ProductRepositoryInterfaceTest extends WebapiAbstract
             ProductInterface::TYPE_ID => 'simple',
             ProductInterface::PRICE => 100,
             ProductInterface::STATUS => 1,
-            ProductInterface::TYPE_ID => 'simple',
             ProductInterface::ATTRIBUTE_SET_ID => 4,
             "product_links" => [$productLinkData]
         ];
@@ -195,18 +194,15 @@ class ProductRepositoryInterfaceTest extends WebapiAbstract
             ProductInterface::TYPE_ID => 'simple',
             ProductInterface::PRICE => 100,
             ProductInterface::STATUS => 1,
-            ProductInterface::TYPE_ID => 'simple',
             ProductInterface::ATTRIBUTE_SET_ID => 4,
             "product_links" => []
         ];
 
         $this->saveProduct($productWithNoLinkData);
         $response = $this->getProduct("product_simple_with_related_500");
-
         $this->assertArrayHasKey('product_links', $response);
         $links = $response['product_links'];
-        $this->assertEquals(1, count($links));
-        $this->assertEquals([], $links[0]);
+        $this->assertEquals([], $links);
 
         $this->deleteProduct("product_simple_500");
         $this->deleteProduct("product_simple_with_related_500");
diff --git a/dev/tests/api-functional/testsuite/Magento/CatalogInventory/Api/ProductRepositoryInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/CatalogInventory/Api/ProductRepositoryInterfaceTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..0a5a6a9faa72c64b8ceb5dcce87fd81f55ec92f3
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/CatalogInventory/Api/ProductRepositoryInterfaceTest.php
@@ -0,0 +1,398 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\CatalogInventory\Api;
+
+use Magento\Catalog\Api\Data\ProductInterface;
+use Magento\CatalogInventory\Api\Data\StockStatusInterface;
+use Magento\Framework\Api\ExtensibleDataInterface;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+
+class ProductRepositoryInterfaceTest extends WebapiAbstract
+{
+    const SERVICE_NAME = 'catalogProductRepositoryV1';
+    const SERVICE_VERSION = 'V1';
+    const RESOURCE_PATH = '/V1/products';
+
+    const KEY_EXTENSION_ATTRIBUTES = ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY;
+    const KEY_STOCK_ITEM = StockStatusInterface::STOCK_ITEM;
+    const KEY_QTY = StockStatusInterface::QTY;
+    const KEY_ITEM_ID = 'item_id';
+    const KEY_PRODUCT_ID = StockStatusInterface::PRODUCT_ID;
+    const KEY_WEBSITE_ID = StockStatusInterface::WEBSITE_ID;
+    const KEY_CUSTOM_ATTRIBUTES = 'custom_attributes';
+    const KEY_ATTRIBUTE_CODE = \Magento\Eav\Api\Data\AttributeInterface::ATTRIBUTE_CODE;
+    const CODE_QUANTITY_AND_STOCK_STATUS = 'quantity_and_stock_status';
+
+    const PRODUCT_SKU = 'sku-test-catalog-inventory';
+
+    /**
+     * Tests the 'happy path'
+     */
+    public function testCatalogInventory()
+    {
+        // create a simple product with catalog inventory
+        $qty = 1234;
+        $productData = $this->getSimpleProductData($qty);
+        $stockItemData = $this->getStockItemData($qty);
+        $this->assertArrayNotHasKey(self::KEY_ITEM_ID, $stockItemData);
+        $this->assertArrayNotHasKey(self::KEY_WEBSITE_ID, $stockItemData);
+        $this->assertArrayNotHasKey(self::KEY_PRODUCT_ID, $stockItemData);
+        $productData[self::KEY_EXTENSION_ATTRIBUTES] = $stockItemData;
+
+        $response = $this->saveProduct($productData);
+
+        $this->assertArrayHasKey(self::KEY_EXTENSION_ATTRIBUTES, $response);
+        $this->assertTrue(isset($response[self::KEY_EXTENSION_ATTRIBUTES][self::KEY_STOCK_ITEM]));
+        $stockItemData = $response[self::KEY_EXTENSION_ATTRIBUTES][self::KEY_STOCK_ITEM];
+        $returnedQty = $stockItemData[self::KEY_QTY];
+        $this->assertEquals($qty, $returnedQty, 'CREATE: Expected qty to be same: ' . $qty .', '. $returnedQty);
+        $this->assertArrayHasKey(self::KEY_ITEM_ID, $stockItemData);
+        $this->assertArrayHasKey(self::KEY_PRODUCT_ID, $stockItemData);
+        $this->assertArrayHasKey(self::KEY_WEBSITE_ID, $stockItemData);
+
+        // officially get the product
+        $response = $this->getProduct($productData[ProductInterface::SKU]);
+
+        $stockItemData = $response[self::KEY_EXTENSION_ATTRIBUTES][self::KEY_STOCK_ITEM];
+        $returnedQty = $stockItemData[self::KEY_QTY];
+        $this->assertEquals($qty, $returnedQty, 'GET: Expected qty to be same: ' . $qty .', '. $returnedQty);
+
+        // update the catalog inventory
+        $qty = $this->getDifferent($qty);  // update the quantity
+        $response[self::KEY_EXTENSION_ATTRIBUTES][self::KEY_STOCK_ITEM][self::KEY_QTY] = $qty;
+
+        $response = $this->updateProduct($response);
+
+        $stockItemData = $response[self::KEY_EXTENSION_ATTRIBUTES][self::KEY_STOCK_ITEM];
+        $returnedQty = $stockItemData[self::KEY_QTY];
+        $this->assertEquals($qty, $returnedQty, 'UPDATE 1: Expected qty to be same: ' . $qty .', '. $returnedQty);
+
+        $customAttributeQty = $this->findCustomAttributeQty($response[self::KEY_CUSTOM_ATTRIBUTES]);
+        $this->assertTrue(!is_bool($customAttributeQty), 'Expected to find a quantity in the custom attributes');
+        $this->assertEquals(
+            $qty,
+            $customAttributeQty,
+            'UPDATE 1: Expected custom attribute qty to be updated: ' . $qty .', '. $customAttributeQty
+        );
+
+        // update the product without any mention of catalog inventory; no change expected for catalog inventory
+        // note: $qty expected to be the same as previously set, above
+        $newPrice = $this->getDifferent($response[ProductInterface::PRICE]);
+        $response[ProductInterface::PRICE] = $newPrice;
+        unset($response[self::KEY_EXTENSION_ATTRIBUTES][self::KEY_STOCK_ITEM]);
+
+        $response = $this->updateProduct($response);
+
+        $this->assertArrayHasKey(self::KEY_EXTENSION_ATTRIBUTES, $response);
+        $this->assertTrue(isset($response[self::KEY_EXTENSION_ATTRIBUTES][self::KEY_STOCK_ITEM]));
+        $stockItemData = $response[self::KEY_EXTENSION_ATTRIBUTES][self::KEY_STOCK_ITEM];
+        $returnedQty = $stockItemData[self::KEY_QTY];
+        $this->assertEquals($qty, $returnedQty, 'UPDATE 2: Expected qty to be same: ' . $qty .', '. $returnedQty);
+        $this->assertEquals($newPrice, $response[ProductInterface::PRICE]);
+
+        // delete the product; expect that all goes well
+        $response = $this->deleteProduct($productData[ProductInterface::SKU]);
+        $this->assertTrue($response);
+    }
+
+    /**
+     * Tests conditions that stray from the 'happy path'
+     */
+    public function testCatalogInventoryWithBogusData()
+    {
+        // create a simple product with catalog inventory
+        $qty = 666;
+        $productData = $this->getSimpleProductData($qty);
+        $stockItemData = $this->getStockItemData($qty);
+        $this->assertArrayNotHasKey(self::KEY_ITEM_ID, $stockItemData);
+        $this->assertArrayNotHasKey(self::KEY_WEBSITE_ID, $stockItemData);
+        $this->assertArrayNotHasKey(self::KEY_PRODUCT_ID, $stockItemData);
+        $productData[self::KEY_EXTENSION_ATTRIBUTES] = $stockItemData;
+
+        $response = $this->saveProduct($productData);
+
+        $this->assertArrayHasKey(self::KEY_EXTENSION_ATTRIBUTES, $response);
+        $this->assertTrue(isset($response[self::KEY_EXTENSION_ATTRIBUTES][self::KEY_STOCK_ITEM]));
+        $stockItemData = $response[self::KEY_EXTENSION_ATTRIBUTES][self::KEY_STOCK_ITEM];
+        $returnedQty = $stockItemData[self::KEY_QTY];
+        $this->assertEquals($qty, $returnedQty, 'POST 1: Expected qty to be same: ' . $qty .', '. $returnedQty);
+        $this->assertArrayHasKey(self::KEY_ITEM_ID, $stockItemData);
+        $this->assertArrayHasKey(self::KEY_PRODUCT_ID, $stockItemData);
+        $this->assertArrayHasKey(self::KEY_WEBSITE_ID, $stockItemData);
+
+        // re-save the catalog inventory:
+        // -- update quantity (which should be honored)
+        // -- supply an incorrect product id (which should be ignored, and be replaced with the actual one)
+        // -- supply an incorrect website id (which should be ignored, and be replaced with the actual one)
+        $qty = 777;  // update the quantity
+        $response[self::KEY_EXTENSION_ATTRIBUTES][self::KEY_STOCK_ITEM][self::KEY_QTY] = $qty;
+
+        $originalProductId = $stockItemData[self::KEY_PRODUCT_ID];
+        $bogusProductId = $this->getDifferent($originalProductId);
+        $response[self::KEY_EXTENSION_ATTRIBUTES][self::KEY_STOCK_ITEM][self::KEY_PRODUCT_ID] = $bogusProductId;
+
+        $originalWebsiteId = $stockItemData[self::KEY_WEBSITE_ID];
+        $bogusWebsiteId = $this->getDifferent($originalWebsiteId);
+        $response[self::KEY_EXTENSION_ATTRIBUTES][self::KEY_STOCK_ITEM][self::KEY_WEBSITE_ID] = $bogusWebsiteId;
+
+        $response = $this->saveProduct($response);
+
+        $stockItemData = $response[self::KEY_EXTENSION_ATTRIBUTES][self::KEY_STOCK_ITEM];
+        $returnedQty = $stockItemData[self::KEY_QTY];
+        $this->assertEquals($qty, $returnedQty, 'POST 2: Expected qty to be same: ' . $qty .', '. $returnedQty);
+
+        $returnedProductId = $stockItemData[self::KEY_PRODUCT_ID];
+        $this->assertEquals($originalProductId, $returnedProductId);
+
+        $returnedWebsiteId = $stockItemData[self::KEY_WEBSITE_ID];
+        $this->assertEquals($originalWebsiteId, $returnedWebsiteId);
+
+        // delete the product; expect that all goes well
+        $response = $this->deleteProduct($productData[ProductInterface::SKU]);
+        $this->assertTrue($response);
+    }
+
+    /**
+     * Tests that creating a simple product has a side-effect of creating catalog inventory
+     */
+    public function testSimpleProductCreationWithoutSpecifyingCatalogInventory()
+    {
+        // create a simple product with catalog inventory
+        $qty = null;
+        $productData = $this->getSimpleProductData($qty);
+        $this->assertArrayNotHasKey(self::KEY_CUSTOM_ATTRIBUTES, $productData);
+        $this->assertArrayNotHasKey(self::KEY_EXTENSION_ATTRIBUTES, $productData);
+
+        $response = $this->saveProduct($productData);
+
+        $this->assertArrayHasKey(self::KEY_EXTENSION_ATTRIBUTES, $response);
+        $this->assertTrue(isset($response[self::KEY_EXTENSION_ATTRIBUTES][self::KEY_STOCK_ITEM]));
+        $stockItemData = $response[self::KEY_EXTENSION_ATTRIBUTES][self::KEY_STOCK_ITEM];
+        $this->assertArrayHasKey(self::KEY_ITEM_ID, $stockItemData);
+        $this->assertArrayHasKey(self::KEY_PRODUCT_ID, $stockItemData);
+        $this->assertArrayHasKey(self::KEY_WEBSITE_ID, $stockItemData);
+
+        // delete the product; expect that all goes well
+        $response = $this->deleteProduct($productData[ProductInterface::SKU]);
+        $this->assertTrue($response);
+    }
+
+    // --- my helpers -----------------------------------------------------------------------------
+
+    /**
+     * Return a value that is different than the original one
+     *
+     * @param int $original
+     * @return int
+     */
+    protected function getDifferent($original)
+    {
+        return 1 + $original * $original;
+    }
+
+    /**
+     * Returns the product's quantity from the array of custom attributes.
+     * If no quantity can be found, will return false.
+     *
+     * @param array $customAttributes
+     * @return int|bool
+     */
+    protected function findCustomAttributeQty($customAttributes)
+    {
+        $qty = false;
+        $qtyAndStockStatus = [];
+        foreach ($customAttributes as $customAttribute) {
+            if ($customAttribute[self::KEY_ATTRIBUTE_CODE] == self::CODE_QUANTITY_AND_STOCK_STATUS) {
+                $qtyAndStockStatus = $customAttribute['value'];
+                break;
+            }
+        }
+        if (!empty($qtyAndStockStatus) && is_array($qtyAndStockStatus)) {
+
+            if (array_key_exists('any_type', $qtyAndStockStatus)) {
+                // for SOAP, need to use the inner array
+                $qtyAndStockStatus = $qtyAndStockStatus['any_type'];
+            }
+
+            // ex: [true, 1234]
+            if (is_bool($qtyAndStockStatus[0]) || is_string($qtyAndStockStatus[0])) {
+                $qty = $qtyAndStockStatus[1];
+            } else {
+                $qty = $qtyAndStockStatus[0];
+            }
+        }
+        return $qty;
+    }
+
+    /**
+     * Get Simple Product Data
+     *
+     * @param int $qty
+     * @return array
+     */
+    protected function getSimpleProductData($qty = 1000)
+    {
+        $productData = [
+            ProductInterface::SKU => self::PRODUCT_SKU,
+            ProductInterface::NAME => self::PRODUCT_SKU,
+            ProductInterface::VISIBILITY => 4,
+            ProductInterface::TYPE_ID => 'simple',
+            ProductInterface::PRICE => 10,
+            ProductInterface::STATUS => 1,
+            ProductInterface::ATTRIBUTE_SET_ID => 4,
+        ];
+
+        if ($qty != null) {
+            $productData[self::KEY_CUSTOM_ATTRIBUTES] = [
+                [self::KEY_ATTRIBUTE_CODE => 'description', 'value' => 'My Product Description'],
+                [self::KEY_ATTRIBUTE_CODE => self::CODE_QUANTITY_AND_STOCK_STATUS, 'value' => [true, $qty]],
+            ];
+        }
+
+        return $productData;
+    }
+
+    /**
+     * Get sample Stock Item data
+     *
+     * @param int $qty
+     * @return array
+     */
+    protected function getStockItemData($qty = 1000)
+    {
+        return [
+            self::KEY_STOCK_ITEM => [
+                self::KEY_QTY => $qty,
+                'is_in_stock' => true,
+                'is_qty_decimal' => false,
+                'show_default_notification_message' => false,
+                'use_config_min_qty' => true,
+                'min_qty' => 0,
+                'use_config_min_sale_qty' => 1,
+                'min_sale_qty' => 1,
+                'use_config_max_sale_qty' => true,
+                'max_sale_qty' => 10000,
+                'use_config_backorders' => true,
+                'backorders' => 0,
+                'use_config_notify_stock_qty' => true,
+                'notify_stock_qty' => 1,
+                'use_config_qty_increments' => true,
+                'qty_increments' => 0,
+                'use_config_enable_qty_inc' => false,
+                'enable_qty_increments' => false,
+                'use_config_manage_stock' => false,
+                'manage_stock' => true,
+                'low_stock_date' => "0",
+                'is_decimal_divided' => false,
+                'stock_status_changed_auto' => 0,
+            ]
+        ];
+    }
+
+    // --- common REST helpers --------------------------------------------------------------------
+
+    /**
+     * Get a product via its sku
+     *
+     * @param string $sku
+     * @return array the product data
+     */
+    protected function getProduct($sku)
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $sku,
+                'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Get',
+            ],
+        ];
+
+        $response = $this->_webApiCall($serviceInfo, ['sku' => $sku]);
+        return $response;
+    }
+
+    /**
+     * Save a product
+     *
+     * @param array $product
+     * @return array the created product data
+     */
+    protected function saveProduct($product)
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH,
+                'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Save',
+            ],
+        ];
+        $requestData = ['product' => $product];
+        $response = $this->_webApiCall($serviceInfo, $requestData);
+        return $response;
+    }
+
+    /**
+     * Update an existing product via its sku
+     *
+     * @param array $product
+     * @return array the product data, including any updates
+     */
+    protected function updateProduct($product)
+    {
+        $sku = $product[ProductInterface::SKU];
+        if (TESTS_WEB_API_ADAPTER == self::ADAPTER_REST) {
+            $product[ProductInterface::SKU] = null;
+        }
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $sku,
+                'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Save',
+            ],
+        ];
+        $requestData = ['product' => $product];
+        $response =  $this->_webApiCall($serviceInfo, $requestData);
+        return $response;
+    }
+
+    /**
+     * Delete a product via its sku
+     *
+     * @param string $sku
+     * @return bool
+     */
+    protected function deleteProduct($sku)
+    {
+        $resourcePath = self::RESOURCE_PATH . '/' . $sku;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $resourcePath,
+                'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_DELETE
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'deleteById',
+            ],
+        ];
+        $requestData = ['sku' => $sku];
+        $response = $this->_webApiCall($serviceInfo, $requestData);
+        return $response;
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/CatalogInventory/Api/StockItemTest.php b/dev/tests/api-functional/testsuite/Magento/CatalogInventory/Api/StockItemTest.php
index 0513f5e68abfdbe603bb5972604abb8d21453165..f8ef77f8e297b3bdf6a41c501c70adb40d31db99 100644
--- a/dev/tests/api-functional/testsuite/Magento/CatalogInventory/Api/StockItemTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/CatalogInventory/Api/StockItemTest.php
@@ -223,7 +223,7 @@ class StockItemTest extends WebapiAbstract
                     'enable_qty_increments' => '',
                     'use_config_manage_stock' => 1,
                     'manage_stock' => 1,
-                    'low_stock_date' => 0,
+                    'low_stock_date' => '',
                     'is_decimal_divided' => '',
                     'stock_status_changed_auto' => 0
                 ],
diff --git a/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/OptionRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/OptionRepositoryTest.php
index 4551eaa3e45e2d713487938cf485344c5ff10b5c..bf9607d24969cae9ad70a61e46973c1ce2d95fb3 100644
--- a/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/OptionRepositoryTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/OptionRepositoryTest.php
@@ -166,7 +166,6 @@ class OptionRepositoryTest extends \Magento\TestFramework\TestCase\WebapiAbstrac
         ];
         $option = [
             'attribute_id' => 'test_configurable',
-            'type' => 'select',
             'label' => 'Test',
             'values' => [
                 [
diff --git a/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/OptionTypesListTest.php b/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/OptionTypesListTest.php
deleted file mode 100644
index a96d5ca79a5cb22ccf148210a39a37f0b545ba81..0000000000000000000000000000000000000000
--- a/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/OptionTypesListTest.php
+++ /dev/null
@@ -1,40 +0,0 @@
-<?php
-/**
- *
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\ConfigurableProduct\Api;
-
-class OptionTypesListTest extends \Magento\TestFramework\TestCase\WebapiAbstract
-{
-    const SERVICE_READ_NAME = 'configurableProductOptionTypesListV1';
-    const SERVICE_VERSION = 'V1';
-    const RESOURCE_PATH = '/V1/configurable-products/:sku/options/';
-
-    public function testGetTypes()
-    {
-        $expectedTypes = ['multiselect', 'select'];
-        $result = $this->getTypes();
-        $this->assertEquals($expectedTypes, $result);
-    }
-
-    /**
-     * @return array
-     */
-    protected function getTypes()
-    {
-        $serviceInfo = [
-            'rest' => [
-                'resourcePath' => str_replace(':sku/', '', self::RESOURCE_PATH) . 'types',
-                'httpMethod'   => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET
-            ],
-            'soap' => [
-                'service'        => self::SERVICE_READ_NAME,
-                'serviceVersion' => self::SERVICE_VERSION,
-                'operation'      => self::SERVICE_READ_NAME . 'GetItems'
-            ]
-        ];
-        return $this->_webApiCall($serviceInfo);
-    }
-}
diff --git a/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/ProductRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/ProductRepositoryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..b9a2c658dfa3bd771656523fa6a3669ec2eaf411
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/ProductRepositoryTest.php
@@ -0,0 +1,486 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\ConfigurableProduct\Api;
+
+use Magento\Catalog\Api\Data\ProductInterface;
+use Magento\Framework\Api\ExtensibleDataInterface;
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+
+/**
+ * Class ProductRepositoryTest for testing ConfigurableProduct integration
+ */
+class ProductRepositoryTest extends WebapiAbstract
+{
+    const SERVICE_NAME = 'catalogProductRepositoryV1';
+    const SERVICE_VERSION = 'V1';
+    const RESOURCE_PATH = '/V1/products';
+    const CONFIGURABLE_PRODUCT_SKU = 'configurable-product-sku';
+
+    /**
+     * @var \Magento\Eav\Model\Config
+     */
+    protected $eavConfig;
+
+    /**
+     * @var \Magento\Framework\ObjectManagerInterface
+     */
+    protected $objectManager;
+
+    /**
+     * @var \Magento\Catalog\Model\Entity\Attribute
+     */
+    protected $configurableAttribute;
+
+    /**
+     * Execute per test initialization
+     */
+    public function setUp()
+    {
+        $this->objectManager = Bootstrap::getObjectManager();
+        $this->eavConfig = $this->objectManager->get('Magento\Eav\Model\Config');
+    }
+
+    /**
+     * Execute per test cleanup
+     */
+    public function tearDown()
+    {
+        $this->deleteProductBySku(self::CONFIGURABLE_PRODUCT_SKU);
+        parent::tearDown();
+    }
+
+    protected function getConfigurableAttributeOptions()
+    {
+        /** @var \Magento\Eav\Model\Resource\Entity\Attribute\Option\Collection $optionCollection */
+        $optionCollection = $this->objectManager->create(
+            'Magento\Eav\Model\Resource\Entity\Attribute\Option\Collection'
+        );
+        $options = $optionCollection->setAttributeFilter($this->configurableAttribute->getId())->getData();
+        return $options;
+    }
+
+    protected function createConfigurableProduct()
+    {
+        $productId1 = 10;
+        $productId2 = 20;
+
+        $label = "color";
+
+        $this->configurableAttribute = $this->eavConfig->getAttribute('catalog_product', 'test_configurable');
+        $this->assertNotNull($this->configurableAttribute);
+
+        $options = $this->getConfigurableAttributeOptions();
+        $this->assertEquals(2, count($options));
+
+        $configurableProductOptions = [
+            [
+                "attribute_id" =>  $this->configurableAttribute->getId(),
+                "label" => $label,
+                "position" => 0,
+                "values" => [
+                    [
+                        "pricing_value" => 10,
+                        "is_percent" =>  0,
+                        "value_index" =>  $options[0]['option_id'],
+                    ],
+                    [
+                        "pricing_value" => 5,
+                        "is_percent" =>  1,
+                        "value_index" =>  $options[1]['option_id'],
+                    ]
+                ],
+            ]
+        ];
+
+        $product = [
+            "sku" => self::CONFIGURABLE_PRODUCT_SKU,
+            "name" => self::CONFIGURABLE_PRODUCT_SKU,
+            "type_id" => "configurable",
+            "price" => 50,
+            'attribute_set_id' => 4,
+            "custom_attributes" => [
+                [
+                    "attribute_code" => $this->configurableAttribute->getAttributeCode(),
+                    "value" => $options[0]['option_id'],
+                ],
+            ],
+            "extension_attributes" => [
+                "configurable_product_options" => $configurableProductOptions,
+                "configurable_product_links" => [$productId1, $productId2],
+            ],
+        ];
+
+        $response = $this->createProduct($product);
+        return $response;
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_configurable.php
+     */
+    public function testCreateConfigurableProduct()
+    {
+        $productId1 = 10;
+        $productId2 = 20;
+        $label = "color";
+
+        $response = $this->createConfigurableProduct();
+        $this->assertEquals(self::CONFIGURABLE_PRODUCT_SKU, $response[ProductInterface::SKU]);
+        $this->assertEquals(50, $response['price']);
+        $this->assertTrue(
+            isset($response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["configurable_product_options"])
+        );
+        $resultConfigurableProductOptions
+            = $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["configurable_product_options"];
+        $this->assertEquals(1, count($resultConfigurableProductOptions));
+        $this->assertTrue(isset($resultConfigurableProductOptions[0]['label']));
+        $this->assertTrue(isset($resultConfigurableProductOptions[0]['id']));
+        $this->assertEquals($label, $resultConfigurableProductOptions[0]['label']);
+        $this->assertTrue(
+            isset($resultConfigurableProductOptions[0]['values'])
+        );
+        $this->assertEquals(2, count($resultConfigurableProductOptions[0]['values']));
+
+        $this->assertTrue(
+            isset($response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["configurable_product_links"])
+        );
+        $resultConfigurableProductLinks
+            = $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["configurable_product_links"];
+        $this->assertEquals(2, count($resultConfigurableProductLinks));
+
+        $this->assertEquals([$productId1, $productId2], $resultConfigurableProductLinks);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_configurable.php
+     */
+    public function testDeleteConfigurableProductOption()
+    {
+        $productId1 = 10;
+        $productId2 = 20;
+
+        $response = $this->createConfigurableProduct();
+        //delete existing option
+        $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]['configurable_product_options'] = [];
+        //leave the product links unchanged
+        unset($response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]['configurable_product_links']);
+        $response = $this->saveProduct($response);
+
+        $this->assertTrue(
+            isset($response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["configurable_product_options"])
+        );
+        $resultConfigurableProductOptions
+            = $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["configurable_product_options"];
+        $this->assertEquals(0, count($resultConfigurableProductOptions));
+
+        $this->assertTrue(
+            isset($response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["configurable_product_links"])
+        );
+        $resultConfigurableProductLinks
+            = $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["configurable_product_links"];
+        $this->assertEquals(2, count($resultConfigurableProductLinks));
+
+        $this->assertEquals([$productId1, $productId2], $resultConfigurableProductLinks);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_configurable.php
+     */
+    public function testUpdateConfigurableProductOption()
+    {
+        $productId1 = 10;
+        $newLabel = 'size';
+
+        $response = $this->createConfigurableProduct();
+        $option = $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["configurable_product_options"][0];
+
+        $optionId = $option['id'];
+        $updatedOption = [
+            'id' => $optionId,
+            'attribute_id' => $option['attribute_id'],
+            'label' => $newLabel,
+            'position' => 1,
+            'values' => [
+                [
+                    'pricing_value' => 15,
+                    'is_percent' => 1,
+                    'value_index' => $option['values'][0]['value_index'],
+                ],
+            ],
+        ];
+        $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]['configurable_product_options'][0] =
+            $updatedOption;
+        $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]['configurable_product_links'] = [$productId1];
+        $response = $this->saveProduct($response);
+
+        $this->assertTrue(
+            isset($response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["configurable_product_options"])
+        );
+        $resultConfigurableProductOptions
+            = $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["configurable_product_options"];
+        $this->assertEquals(1, count($resultConfigurableProductOptions));
+
+        $this->assertEquals($updatedOption, $resultConfigurableProductOptions[0]);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_configurable.php
+     */
+    public function testUpdateConfigurableProductLinks()
+    {
+        $productId1 = 10;
+        $productId2 = 20;
+
+        $response = $this->createConfigurableProduct();
+        $options = $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]['configurable_product_options'];
+        //leave existing option untouched
+        unset($response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]['configurable_product_options']);
+        $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]['configurable_product_links'] = [$productId1];
+        $response = $this->saveProduct($response);
+
+        $this->assertTrue(
+            isset($response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["configurable_product_options"])
+        );
+        $resultConfigurableProductOptions
+            = $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["configurable_product_options"];
+        $this->assertEquals(1, count($resultConfigurableProductOptions));
+        //Since one product is removed, the available values for the option is reduced
+        $this->assertEquals(1, count($resultConfigurableProductOptions[0]['values']));
+
+        $this->assertTrue(
+            isset($response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["configurable_product_links"])
+        );
+        $resultConfigurableProductLinks
+            = $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["configurable_product_links"];
+        $this->assertEquals(1, count($resultConfigurableProductLinks));
+        $this->assertEquals([$productId1], $resultConfigurableProductLinks);
+
+        //adding back the product links, the option value should be restored
+        unset($response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]['configurable_product_options']);
+        $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]['configurable_product_links']
+            = [$productId1, $productId2];
+        //set the value for required attribute
+        $response["custom_attributes"][] =
+        [
+            "attribute_code" => $this->configurableAttribute->getAttributeCode(),
+            "value" => $resultConfigurableProductOptions[0]['values'][0]['value_index'],
+        ];
+
+        $response = $this->saveProduct($response);
+        $currentOptions = $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]['configurable_product_options'];
+
+        $this->assertEquals($options, $currentOptions);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_configurable.php
+     */
+    public function testUpdateConfigurableProductLinksWithNonExistingProduct()
+    {
+        $productId1 = 10;
+        $nonExistingId = 999;
+
+        $response = $this->createConfigurableProduct();
+        //leave existing option untouched
+        unset($response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]['configurable_product_options']);
+        $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]['configurable_product_links'] = [
+            $productId1, $nonExistingId
+        ];
+
+        $expectedMessage = 'Product with id "%1" does not exist.';
+        try {
+            $this->saveProduct($response);
+            $this->fail("Expected exception");
+        } catch (\SoapFault $e) {
+            $this->assertContains(
+                $expectedMessage,
+                $e->getMessage(),
+                "SoapFault does not contain expected message."
+            );
+        } catch (\Exception $e) {
+            $errorObj = $this->processRestExceptionResult($e);
+            $this->assertEquals($expectedMessage, $errorObj['message']);
+            $this->assertEquals(['0' => '999'], $errorObj['parameters']);
+        }
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_configurable.php
+     */
+    public function testUpdateConfigurableProductLinksWithDuplicateAttributes()
+    {
+        $productId1 = 10;
+        $productId2 = 20;
+
+        $response = $this->createConfigurableProduct();
+        $options = $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]['configurable_product_options'];
+        //make product2 and product1 have the same value for the configurable attribute
+        $optionValue1 = $options[0]['values'][0]['value_index'];
+        $product2 = $this->getProduct('simple_' . $productId2);
+        $product2['custom_attributes'] = [
+            [
+                'attribute_code' => 'test_configurable',
+                'value' => $optionValue1,
+            ]
+        ];
+        $this->saveProduct($product2);
+
+        //leave existing option untouched
+        unset($response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]['configurable_product_options']);
+        $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]['configurable_product_links'] = [
+            $productId1, $productId2
+        ];
+
+        $expectedMessage = 'Products "%1" and %2 have the same set of attribute values.';
+        try {
+            $this->saveProduct($response);
+            $this->fail("Expected exception");
+        } catch (\SoapFault $e) {
+            $this->assertContains(
+                $expectedMessage,
+                $e->getMessage(),
+                "SoapFault does not contain expected message."
+            );
+        } catch (\Exception $e) {
+            $errorObj = $this->processRestExceptionResult($e);
+            $this->assertEquals($expectedMessage, $errorObj['message']);
+            $this->assertEquals(['0' => 20, '1' => 10], $errorObj['parameters']);
+        }
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_configurable.php
+     */
+    public function testUpdateConfigurableProductLinksWithWithoutVariationAttributes()
+    {
+        $productId1 = 10;
+        $productId2 = 20;
+
+        $response = $this->createConfigurableProduct();
+
+        /** delete all variation attribute */
+        $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]['configurable_product_options'] = [];
+        $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]['configurable_product_links'] = [
+            $productId1, $productId2
+        ];
+
+        $expectedMessage = 'The configurable product does not have any variation attribute.';
+        try {
+            $this->saveProduct($response);
+            $this->fail("Expected exception");
+        } catch (\SoapFault $e) {
+            $this->assertContains(
+                $expectedMessage,
+                $e->getMessage(),
+                "SoapFault does not contain expected message."
+            );
+        } catch (\Exception $e) {
+            $errorObj = $this->processRestExceptionResult($e);
+            $this->assertEquals($expectedMessage, $errorObj['message']);
+        }
+    }
+
+    /**
+     * Get product
+     *
+     * @param string $productSku
+     * @return array the product data
+     */
+    protected function getProduct($productSku)
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $productSku,
+                'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Get',
+            ],
+        ];
+
+        $response = (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) ?
+            $this->_webApiCall($serviceInfo, ['sku' => $productSku]) : $this->_webApiCall($serviceInfo);
+
+        return $response;
+    }
+
+    /**
+     * Create product
+     *
+     * @param array $product
+     * @return array the created product data
+     */
+    protected function createProduct($product)
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH,
+                'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Save',
+            ],
+        ];
+        $requestData = ['product' => $product];
+        $response = $this->_webApiCall($serviceInfo, $requestData);
+        return $response;
+    }
+
+    /**
+     * Delete a product by sku
+     *
+     * @param $productSku
+     * @return bool
+     */
+    protected function deleteProductBySku($productSku)
+    {
+        $resourcePath = self::RESOURCE_PATH . '/' . $productSku;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $resourcePath,
+                'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_DELETE
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'deleteById',
+            ],
+        ];
+        $requestData = ["sku" => $productSku];
+        $response = $this->_webApiCall($serviceInfo, $requestData);
+        return $response;
+    }
+
+    /**
+     * Save product
+     *
+     * @param array $product
+     * @return array the created product data
+     */
+    protected function saveProduct($product)
+    {
+        $resourcePath = self::RESOURCE_PATH . '/' . $product['sku'];
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $resourcePath,
+                'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_PUT
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Save',
+            ],
+        ];
+        $requestData = ['product' => $product];
+        $response = $this->_webApiCall($serviceInfo, $requestData);
+        return $response;
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php
index 4234afc66f27883af89395192189e18bf3c154e0..656da53f38e842a1f3122b6fd35fbd87cdb24c05 100644
--- a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php
@@ -80,9 +80,10 @@ class LinkRepositoryTest extends WebapiAbstract
     protected function getTargetProduct($isScopeGlobal = false)
     {
         $objectManager = Bootstrap::getObjectManager();
-        $product = $objectManager->get('Magento\Catalog\Model\ProductFactory')->create()->load(1);
         if ($isScopeGlobal) {
-            $product->setStoreId(0);
+            $product = $objectManager->get('Magento\Catalog\Model\ProductFactory')->create()->setStoreId(0)->load(1);
+        } else {
+            $product = $objectManager->get('Magento\Catalog\Model\ProductFactory')->create()->load(1);
         }
 
         return $product;
@@ -114,18 +115,18 @@ class LinkRepositoryTest extends WebapiAbstract
         $requestData = [
             'isGlobalScopeContent' => true,
             'sku' => 'downloadable-product',
-            'linkContent' => [
+            'link' => [
                 'title' => 'Title',
                 'sort_order' => 1,
                 'price' => 10.1,
-                'shareable' => true,
+                'is_shareable' => true,
                 'number_of_downloads' => 100,
                 'link_type' => 'file',
-                'link_file' => [
+                'link_file_content' => [
                     'file_data' => base64_encode(file_get_contents($this->testImagePath)),
                     'name' => 'image.jpg',
                 ],
-                'sample_file' => [
+                'sample_file_content' => [
                     'file_data' => base64_encode(file_get_contents($this->testImagePath)),
                     'name' => 'image.jpg',
                 ],
@@ -137,15 +138,15 @@ class LinkRepositoryTest extends WebapiAbstract
         $globalScopeLink = $this->getTargetLink($this->getTargetProduct(true), $newLinkId);
         $link = $this->getTargetLink($this->getTargetProduct(), $newLinkId);
         $this->assertNotNull($link);
-        $this->assertEquals($requestData['linkContent']['title'], $link->getTitle());
-        $this->assertEquals($requestData['linkContent']['title'], $globalScopeLink->getTitle());
-        $this->assertEquals($requestData['linkContent']['sort_order'], $link->getSortOrder());
-        $this->assertEquals($requestData['linkContent']['price'], $link->getPrice());
-        $this->assertEquals($requestData['linkContent']['price'], $globalScopeLink->getPrice());
-        $this->assertEquals($requestData['linkContent']['shareable'], $link->getIsShareable());
-        $this->assertEquals($requestData['linkContent']['number_of_downloads'], $link->getNumberOfDownloads());
-        $this->assertEquals($requestData['linkContent']['link_type'], $link->getLinkType());
-        $this->assertEquals($requestData['linkContent']['sample_type'], $link->getSampleType());
+        $this->assertEquals($requestData['link']['title'], $link->getTitle());
+        $this->assertEquals($requestData['link']['title'], $globalScopeLink->getTitle());
+        $this->assertEquals($requestData['link']['sort_order'], $link->getSortOrder());
+        $this->assertEquals($requestData['link']['price'], $link->getPrice());
+        $this->assertEquals($requestData['link']['price'], $globalScopeLink->getPrice());
+        $this->assertEquals($requestData['link']['is_shareable'], $link->getIsShareable());
+        $this->assertEquals($requestData['link']['number_of_downloads'], $link->getNumberOfDownloads());
+        $this->assertEquals($requestData['link']['link_type'], $link->getLinkType());
+        $this->assertEquals($requestData['link']['sample_type'], $link->getSampleType());
         $this->assertStringEndsWith('.jpg', $link->getSampleFile());
         $this->assertStringEndsWith('.jpg', $link->getLinkFile());
         $this->assertNull($link->getLinkUrl());
@@ -160,11 +161,11 @@ class LinkRepositoryTest extends WebapiAbstract
         $requestData = [
             'isGlobalScopeContent' => false,
             'sku' => 'downloadable-product',
-            'linkContent' => [
+            'link' => [
                 'title' => 'Store View Title',
                 'sort_order' => 1,
                 'price' => 150,
-                'shareable' => true,
+                'is_shareable' => true,
                 'number_of_downloads' => 100,
                 'link_url' => 'http://www.example.com/',
                 'link_type' => 'url',
@@ -177,15 +178,15 @@ class LinkRepositoryTest extends WebapiAbstract
         $link = $this->getTargetLink($this->getTargetProduct(), $newLinkId);
         $globalScopeLink = $this->getTargetLink($this->getTargetProduct(true), $newLinkId);
         $this->assertNotNull($link);
-        $this->assertEquals($requestData['linkContent']['title'], $link->getTitle());
-        $this->assertEquals($requestData['linkContent']['sort_order'], $link->getSortOrder());
-        $this->assertEquals($requestData['linkContent']['price'], $link->getPrice());
-        $this->assertEquals($requestData['linkContent']['shareable'], $link->getIsShareable());
-        $this->assertEquals($requestData['linkContent']['number_of_downloads'], $link->getNumberOfDownloads());
-        $this->assertEquals($requestData['linkContent']['link_url'], $link->getLinkUrl());
-        $this->assertEquals($requestData['linkContent']['link_type'], $link->getLinkType());
-        $this->assertEquals($requestData['linkContent']['sample_url'], $link->getSampleUrl());
-        $this->assertEquals($requestData['linkContent']['sample_type'], $link->getSampleType());
+        $this->assertEquals($requestData['link']['title'], $link->getTitle());
+        $this->assertEquals($requestData['link']['sort_order'], $link->getSortOrder());
+        $this->assertEquals($requestData['link']['price'], $link->getPrice());
+        $this->assertEquals($requestData['link']['is_shareable'], $link->getIsShareable());
+        $this->assertEquals($requestData['link']['number_of_downloads'], $link->getNumberOfDownloads());
+        $this->assertEquals($requestData['link']['link_url'], $link->getLinkUrl());
+        $this->assertEquals($requestData['link']['link_type'], $link->getLinkType());
+        $this->assertEquals($requestData['link']['sample_url'], $link->getSampleUrl());
+        $this->assertEquals($requestData['link']['sample_type'], $link->getSampleType());
         $this->assertEmpty($globalScopeLink->getTitle());
         $this->assertEmpty($globalScopeLink->getPrice());
     }
@@ -198,11 +199,11 @@ class LinkRepositoryTest extends WebapiAbstract
         $requestData = [
             'isGlobalScopeContent' => false,
             'sku' => 'downloadable-product',
-            'linkContent' => [
+            'link' => [
                 'title' => 'Link with URL resources',
                 'sort_order' => 1,
                 'price' => 10.1,
-                'shareable' => true,
+                'is_shareable' => true,
                 'number_of_downloads' => 100,
                 'link_url' => 'http://www.example.com/',
                 'link_type' => 'url',
@@ -214,15 +215,15 @@ class LinkRepositoryTest extends WebapiAbstract
         $newLinkId = $this->_webApiCall($this->createServiceInfo, $requestData);
         $link = $this->getTargetLink($this->getTargetProduct(), $newLinkId);
         $this->assertNotNull($link);
-        $this->assertEquals($requestData['linkContent']['title'], $link->getTitle());
-        $this->assertEquals($requestData['linkContent']['sort_order'], $link->getSortOrder());
-        $this->assertEquals($requestData['linkContent']['price'], $link->getPrice());
-        $this->assertEquals($requestData['linkContent']['shareable'], $link->getIsShareable());
-        $this->assertEquals($requestData['linkContent']['number_of_downloads'], $link->getNumberOfDownloads());
-        $this->assertEquals($requestData['linkContent']['link_url'], $link->getLinkUrl());
-        $this->assertEquals($requestData['linkContent']['link_type'], $link->getLinkType());
-        $this->assertEquals($requestData['linkContent']['sample_type'], $link->getSampleType());
-        $this->assertEquals($requestData['linkContent']['sample_url'], $link->getSampleUrl());
+        $this->assertEquals($requestData['link']['title'], $link->getTitle());
+        $this->assertEquals($requestData['link']['sort_order'], $link->getSortOrder());
+        $this->assertEquals($requestData['link']['price'], $link->getPrice());
+        $this->assertEquals($requestData['link']['is_shareable'], $link->getIsShareable());
+        $this->assertEquals($requestData['link']['number_of_downloads'], $link->getNumberOfDownloads());
+        $this->assertEquals($requestData['link']['link_url'], $link->getLinkUrl());
+        $this->assertEquals($requestData['link']['link_type'], $link->getLinkType());
+        $this->assertEquals($requestData['link']['sample_type'], $link->getSampleType());
+        $this->assertEquals($requestData['link']['sample_url'], $link->getSampleUrl());
     }
 
     /**
@@ -235,12 +236,15 @@ class LinkRepositoryTest extends WebapiAbstract
         $requestData = [
             'isGlobalScopeContent' => false,
             'sku' => 'downloadable-product',
-            'linkContent' => [
+            'link' => [
                 'title' => 'Link with URL resources',
                 'sort_order' => 1,
                 'price' => 10.1,
-                'shareable' => true,
+                'is_shareable' => true,
                 'number_of_downloads' => 100,
+                'link_type' => 'invalid',
+                'sample_type' => 'url',
+                'sample_url' => 'http://www.example.com',
             ],
         ];
 
@@ -257,16 +261,16 @@ class LinkRepositoryTest extends WebapiAbstract
         $requestData = [
             'isGlobalScopeContent' => false,
             'sku' => 'downloadable-product',
-            'linkContent' => [
+            'link' => [
                 'title' => 'Link Title',
                 'sort_order' => 1,
                 'price' => 10,
-                'shareable' => true,
+                'is_shareable' => true,
                 'number_of_downloads' => 100,
                 'link_type' => 'url',
                 'link_url' => 'http://www.example.com/',
                 'sample_type' => 'file',
-                'sample_file' => [
+                'sample_file_content' => [
                     'file_data' => 'not_a_base64_encoded_content',
                     'name' => 'image.jpg',
                 ],
@@ -286,17 +290,19 @@ class LinkRepositoryTest extends WebapiAbstract
         $requestData = [
             'isGlobalScopeContent' => false,
             'sku' => 'downloadable-product',
-            'linkContent' => [
+            'link' => [
                 'title' => 'Link Title',
                 'sort_order' => 1,
                 'price' => 10,
-                'shareable' => true,
+                'is_shareable' => true,
                 'number_of_downloads' => 100,
                 'link_type' => 'file',
-                'link_file' => [
+                'link_file_content' => [
                     'file_data' => 'not_a_base64_encoded_content',
                     'name' => 'image.jpg',
                 ],
+                'sample_type' => 'url',
+                'sample_url' => 'http://www.example.com/',
             ],
         ];
 
@@ -313,17 +319,19 @@ class LinkRepositoryTest extends WebapiAbstract
         $requestData = [
             'isGlobalScopeContent' => false,
             'sku' => 'downloadable-product',
-            'linkContent' => [
+            'link' => [
                 'title' => 'Title',
                 'sort_order' => 15,
                 'price' => 10,
-                'shareable' => true,
+                'is_shareable' => true,
                 'number_of_downloads' => 100,
                 'link_type' => 'file',
-                'link_file' => [
+                'link_file_content' => [
                     'file_data' => base64_encode(file_get_contents($this->testImagePath)),
                     'name' => 'name/with|forbidden{characters',
                 ],
+                'sample_type' => 'url',
+                'sample_url' => 'http://www.example.com/',
             ],
         ];
 
@@ -340,16 +348,16 @@ class LinkRepositoryTest extends WebapiAbstract
         $requestData = [
             'isGlobalScopeContent' => false,
             'sku' => 'downloadable-product',
-            'linkContent' => [
+            'link' => [
                 'title' => 'Link Title',
                 'sort_order' => 1,
                 'price' => 10,
-                'shareable' => true,
+                'is_shareable' => true,
                 'number_of_downloads' => 100,
                 'link_type' => 'url',
                 'link_url' => 'http://www.example.com/',
                 'sample_type' => 'file',
-                'sample_file' => [
+                'sample_file_content' => [
                     'file_data' => base64_encode(file_get_contents($this->testImagePath)),
                     'name' => 'name/with|forbidden{characters',
                 ],
@@ -369,14 +377,16 @@ class LinkRepositoryTest extends WebapiAbstract
         $requestData = [
             'isGlobalScopeContent' => false,
             'sku' => 'downloadable-product',
-            'linkContent' => [
+            'link' => [
                 'title' => 'Link Title',
                 'sort_order' => 1,
                 'price' => 10,
-                'shareable' => true,
+                'is_shareable' => true,
                 'number_of_downloads' => 100,
                 'link_type' => 'url',
                 'link_url' => 'http://example<.>com/',
+                'sample_type' => 'url',
+                'sample_url' => 'http://www.example.com/',
             ],
         ];
 
@@ -393,11 +403,11 @@ class LinkRepositoryTest extends WebapiAbstract
         $requestData = [
             'isGlobalScopeContent' => false,
             'sku' => 'downloadable-product',
-            'linkContent' => [
+            'link' => [
                 'title' => 'Link Title',
                 'sort_order' => 1,
                 'price' => 150,
-                'shareable' => true,
+                'is_shareable' => true,
                 'number_of_downloads' => 0,
                 'sample_type' => 'url',
                 'sample_url' => 'http://example<.>com/',
@@ -420,11 +430,11 @@ class LinkRepositoryTest extends WebapiAbstract
         $requestData = [
             'isGlobalScopeContent' => false,
             'sku' => 'downloadable-product',
-            'linkContent' => [
+            'link' => [
                 'title' => 'Link Title',
                 'sort_order' => 1,
                 'price' => $linkPrice,
-                'shareable' => true,
+                'is_shareable' => true,
                 'number_of_downloads' => 0,
                 'sample_type' => 'url',
                 'sample_url' => 'http://example.com/',
@@ -442,7 +452,6 @@ class LinkRepositoryTest extends WebapiAbstract
     public function getInvalidLinkPrice()
     {
         return [
-            ['string_value'],
             [-1.5],
         ];
     }
@@ -458,11 +467,11 @@ class LinkRepositoryTest extends WebapiAbstract
         $requestData = [
             'isGlobalScopeContent' => false,
             'sku' => 'downloadable-product',
-            'linkContent' => [
+            'link' => [
                 'title' => 'Link Title',
                 'sort_order' => $sortOrder,
                 'price' => 10,
-                'shareable' => false,
+                'is_shareable' => false,
                 'number_of_downloads' => 0,
                 'sample_type' => 'url',
                 'sample_url' => 'http://example.com/',
@@ -494,11 +503,11 @@ class LinkRepositoryTest extends WebapiAbstract
         $requestData = [
             'isGlobalScopeContent' => false,
             'sku' => 'downloadable-product',
-            'linkContent' => [
+            'link' => [
                 'title' => 'Link Title',
                 'sort_order' => 0,
                 'price' => 10,
-                'shareable' => false,
+                'is_shareable' => false,
                 'number_of_downloads' => $numberOfDownloads,
                 'sample_type' => 'url',
                 'sample_url' => 'http://example.com/',
@@ -530,11 +539,11 @@ class LinkRepositoryTest extends WebapiAbstract
         $requestData = [
             'isGlobalScopeContent' => false,
             'sku' => 'simple',
-            'linkContent' => [
+            'link' => [
                 'title' => 'Link Title',
                 'sort_order' => 50,
                 'price' => 200,
-                'shareable' => false,
+                'is_shareable' => false,
                 'number_of_downloads' => 10,
                 'sample_type' => 'url',
                 'sample_url' => 'http://example.com/',
@@ -555,11 +564,11 @@ class LinkRepositoryTest extends WebapiAbstract
         $requestData = [
             'isGlobalScopeContent' => false,
             'sku' => 'wrong-sku',
-            'linkContent' => [
+            'link' => [
                 'title' => 'Link Title',
                 'sort_order' => 15,
                 'price' => 200,
-                'shareable' => true,
+                'is_shareable' => true,
                 'number_of_downloads' => 100,
                 'sample_type' => 'url',
                 'sample_url' => 'http://example.com/',
@@ -580,24 +589,26 @@ class LinkRepositoryTest extends WebapiAbstract
             = "/V1/products/downloadable-product/downloadable-links/{$linkId}";
         $requestData = [
             'isGlobalScopeContent' => false,
-            'linkId' => $linkId,
             'sku' => 'downloadable-product',
-            'linkContent' => [
+            'link' => [
+                'id' => $linkId,
                 'title' => 'Updated Title',
                 'sort_order' => 2,
                 'price' => 100.10,
-                'shareable' => false,
+                'is_shareable' => false,
                 'number_of_downloads' => 50,
+                'link_type' => 'url',
+                'sample_type' => 'url',
             ],
         ];
         $this->assertEquals($linkId, $this->_webApiCall($this->updateServiceInfo, $requestData));
         $link = $this->getTargetLink($this->getTargetProduct(), $linkId);
         $this->assertNotNull($link);
-        $this->assertEquals($requestData['linkContent']['title'], $link->getTitle());
-        $this->assertEquals($requestData['linkContent']['sort_order'], $link->getSortOrder());
-        $this->assertEquals($requestData['linkContent']['price'], $link->getPrice());
-        $this->assertEquals($requestData['linkContent']['shareable'], (bool)$link->getIsShareable());
-        $this->assertEquals($requestData['linkContent']['number_of_downloads'], $link->getNumberOfDownloads());
+        $this->assertEquals($requestData['link']['title'], $link->getTitle());
+        $this->assertEquals($requestData['link']['sort_order'], $link->getSortOrder());
+        $this->assertEquals($requestData['link']['price'], $link->getPrice());
+        $this->assertEquals($requestData['link']['is_shareable'], (bool)$link->getIsShareable());
+        $this->assertEquals($requestData['link']['number_of_downloads'], $link->getNumberOfDownloads());
     }
 
     /**
@@ -611,14 +622,16 @@ class LinkRepositoryTest extends WebapiAbstract
             = "/V1/products/downloadable-product/downloadable-links/{$linkId}";
         $requestData = [
             'isGlobalScopeContent' => true,
-            'linkId' => $linkId,
             'sku' => 'downloadable-product',
-            'linkContent' => [
+            'link' => [
+                'id' => $linkId,
                 'title' => 'Updated Title',
                 'sort_order' => 2,
                 'price' => 100.10,
-                'shareable' => false,
+                'is_shareable' => false,
                 'number_of_downloads' => 50,
+                'link_type' => 'url',
+                'sample_type' => 'url',
             ],
         ];
 
@@ -629,11 +642,11 @@ class LinkRepositoryTest extends WebapiAbstract
         // Title and price were set on store view level in fixture so they must be the same
         $this->assertEquals($originalLink->getTitle(), $link->getTitle());
         $this->assertEquals($originalLink->getPrice(), $link->getPrice());
-        $this->assertEquals($requestData['linkContent']['title'], $globalScopeLink->getTitle());
-        $this->assertEquals($requestData['linkContent']['price'], $globalScopeLink->getPrice());
-        $this->assertEquals($requestData['linkContent']['sort_order'], $link->getSortOrder());
-        $this->assertEquals($requestData['linkContent']['shareable'], (bool)$link->getIsShareable());
-        $this->assertEquals($requestData['linkContent']['number_of_downloads'], $link->getNumberOfDownloads());
+        $this->assertEquals($requestData['link']['title'], $globalScopeLink->getTitle());
+        $this->assertEquals($requestData['link']['price'], $globalScopeLink->getPrice());
+        $this->assertEquals($requestData['link']['sort_order'], $link->getSortOrder());
+        $this->assertEquals($requestData['link']['is_shareable'], (bool)$link->getIsShareable());
+        $this->assertEquals($requestData['link']['number_of_downloads'], $link->getNumberOfDownloads());
     }
 
     /**
@@ -645,14 +658,16 @@ class LinkRepositoryTest extends WebapiAbstract
         $this->updateServiceInfo['rest']['resourcePath'] = '/V1/products/wrong-sku/downloadable-links/1';
         $requestData = [
             'isGlobalScopeContent' => true,
-            'linkId' => 1,
             'sku' => 'wrong-sku',
-            'linkContent' => [
+            'link' => [
+                'id' => 1,
                 'title' => 'Updated Title',
                 'sort_order' => 2,
                 'price' => 100.10,
-                'shareable' => false,
+                'is_shareable' => false,
                 'number_of_downloads' => 50,
+                'link_type' => 'url',
+                'sample_type' => 'url',
             ],
         ];
         $this->_webApiCall($this->updateServiceInfo, $requestData);
@@ -670,14 +685,16 @@ class LinkRepositoryTest extends WebapiAbstract
             = "/V1/products/downloadable-product/downloadable-links/{$linkId}";
         $requestData = [
             'isGlobalScopeContent' => true,
-            'linkId' => 9999,
             'sku' => 'downloadable-product',
-            'linkContent' => [
+            'link' => [
+                'id' => $linkId,
                 'title' => 'Title',
                 'sort_order' => 2,
                 'price' => 100.10,
-                'shareable' => false,
+                'is_shareable' => false,
                 'number_of_downloads' => 50,
+                'link_type' => 'url',
+                'sample_type' => 'url',
             ],
         ];
 
@@ -697,14 +714,16 @@ class LinkRepositoryTest extends WebapiAbstract
             = "/V1/products/downloadable-product/downloadable-links/{$linkId}";
         $requestData = [
             'isGlobalScopeContent' => false,
-            'linkId' => $linkId,
             'sku' => 'downloadable-product',
-            'linkContent' => [
+            'link' => [
+                'id' => $linkId,
                 'title' => 'Updated Link Title',
                 'sort_order' => 2,
                 'price' => $linkPrice,
-                'shareable' => false,
+                'is_shareable' => false,
                 'number_of_downloads' => 50,
+                'link_type' => 'url',
+                'sample_type' => 'url',
             ],
         ];
 
@@ -724,14 +743,16 @@ class LinkRepositoryTest extends WebapiAbstract
             = "/V1/products/downloadable-product/downloadable-links/{$linkId}";
         $requestData = [
             'isGlobalScopeContent' => false,
-            'linkId' => $linkId,
             'sku' => 'downloadable-product',
-            'linkContent' => [
+            'link' => [
+                'id' => $linkId,
                 'title' => 'Updated Link Title',
                 'sort_order' => $sortOrder,
                 'price' => 100.50,
-                'shareable' => false,
+                'is_shareable' => false,
                 'number_of_downloads' => 50,
+                'link_type' => 'url',
+                'sample_type' => 'url',
             ],
         ];
         $this->_webApiCall($this->updateServiceInfo, $requestData);
@@ -750,14 +771,16 @@ class LinkRepositoryTest extends WebapiAbstract
             = "/V1/products/downloadable-product/downloadable-links/{$linkId}";
         $requestData = [
             'isGlobalScopeContent' => false,
-            'linkId' => $linkId,
             'sku' => 'downloadable-product',
-            'linkContent' => [
+            'link' => [
+                'id' => $linkId,
                 'title' => 'Updated Link Title',
                 'sort_order' => 200,
                 'price' => 100.50,
-                'shareable' => false,
+                'is_shareable' => false,
                 'number_of_downloads' => $numberOfDownloads,
+                'link_type' => 'url',
+                'sample_type' => 'url',
             ],
         ];
         $this->_webApiCall($this->updateServiceInfo, $requestData);
@@ -771,7 +794,7 @@ class LinkRepositoryTest extends WebapiAbstract
         $linkId = $this->getTargetLink($this->getTargetProduct())->getId();
         $this->deleteServiceInfo['rest']['resourcePath'] = "/V1/products/downloadable-links/{$linkId}";
         $requestData = [
-            'linkId' => $linkId,
+            'id' => $linkId,
         ];
 
         $this->assertTrue($this->_webApiCall($this->deleteServiceInfo, $requestData));
@@ -788,7 +811,7 @@ class LinkRepositoryTest extends WebapiAbstract
         $linkId = 9999;
         $this->deleteServiceInfo['rest']['resourcePath'] = "/V1/products/downloadable-links/{$linkId}";
         $requestData = [
-            'linkId' => $linkId,
+            'id' => $linkId,
         ];
 
         $this->_webApiCall($this->deleteServiceInfo, $requestData);
diff --git a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/ProductRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/ProductRepositoryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..a079eb6d4b6bfa58256a646f396a535c91a0e0cc
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/ProductRepositoryTest.php
@@ -0,0 +1,627 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Downloadable\Api;
+
+use Magento\Catalog\Api\Data\ProductInterface;
+use Magento\Framework\Api\ExtensibleDataInterface;
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Bundle\Api\Data\LinkInterface;
+
+/**
+ * Class ProductRepositoryTest for testing ProductRepository interface with Downloadable Product
+ */
+class ProductRepositoryTest extends WebapiAbstract
+{
+    const SERVICE_NAME = 'catalogProductRepositoryV1';
+    const SERVICE_VERSION = 'V1';
+    const RESOURCE_PATH = '/V1/products';
+    const PRODUCT_SKU = 'sku-test-product-downloadable';
+
+    /**
+     * @var string
+     */
+    protected $testImagePath;
+
+    protected function setUp()
+    {
+        $this->testImagePath = __DIR__ . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'test_image.jpg';
+    }
+
+    /**
+     * Execute per test cleanup
+     */
+    public function tearDown()
+    {
+        $this->deleteProductBySku(self::PRODUCT_SKU);
+        parent::tearDown();
+    }
+
+    protected function getLinkData()
+    {
+        return [
+            'link1' => [
+                'title' => "link1",
+                'sort_order'=> 10,
+                'is_shareable' => 1,
+                'price' => 2.0,
+                'number_of_downloads' => 0,
+                'link_type' => 'file',
+                'link_file_content' => [
+                    'name' => 'link1_content.jpg',
+                    'file_data' => base64_encode(file_get_contents($this->testImagePath)),
+                ],
+                'sample_type' => 'file',
+                'sample_file_content' => [
+                    'name' => 'link1_sample.jpg',
+                    'file_data' => base64_encode(file_get_contents($this->testImagePath)),
+                ],
+            ],
+            'link2' => [
+                'title' => 'link2',
+                'sort_order'=> 20,
+                'is_shareable' => 0,
+                'price' => 3.0,
+                'number_of_downloads' => 100,
+                'link_type' => "url",
+                'link_url' => 'http://www.example.com/link2.jpg',
+                'sample_type' => 'url',
+                'sample_url' => 'http://www.example.com/link2.jpg',
+            ],
+        ];
+    }
+
+    protected function getExpectedLinkData()
+    {
+        return [
+            [
+                'title' => 'link1',
+                'sort_order' => 10,
+                'is_shareable' => 1,
+                'price' => 2,
+                'number_of_downloads' => 0,
+                'link_type' => 'file',
+                'sample_type' => 'file',
+            ],
+            [
+                'title' => 'link2',
+                'sort_order' => 20,
+                'is_shareable' => 0,
+                'price' => 3,
+                'number_of_downloads' => 100,
+                'link_type' => 'url',
+                'link_url' => 'http://www.example.com/link2.jpg',
+                'sample_type' => 'url',
+                'sample_url' => 'http://www.example.com/link2.jpg',
+            ],
+        ];
+    }
+
+    protected function getSampleData()
+    {
+        return [
+            'sample1' => [
+                'title' => 'sample1',
+                'sort_order' => 10,
+                'sample_type' => 'url',
+                'sample_url' => 'http://www.example.com/sample1.jpg',
+            ],
+            'sample2' => [
+                'title' => 'sample2',
+                'sort_order' => 20,
+                'sample_type' => 'file',
+                'sample_file_content' => [
+                    'name' => 'sample2.jpg',
+                    'file_data' => base64_encode(file_get_contents($this->testImagePath)),
+                ],
+            ],
+        ];
+    }
+
+    protected function getExpectedSampleData()
+    {
+        return [
+            [
+                'title' => 'sample1',
+                'sort_order' => 10,
+                'sample_type' => 'url',
+                'sample_url' => 'http://www.example.com/sample1.jpg',
+            ],
+            [
+                'title' => 'sample2',
+                'sort_order' => 20,
+                'sample_type' => 'file',
+            ],
+        ];
+    }
+
+    protected function createDownloadableProduct()
+    {
+        $product = [
+            "sku" => self::PRODUCT_SKU,
+            "name" => self::PRODUCT_SKU,
+            "type_id" => \Magento\Downloadable\Model\Product\Type::TYPE_DOWNLOADABLE,
+            "price" => 10,
+            'attribute_set_id' => 4,
+            "extension_attributes" => [
+                "downloadable_product_links" => array_values($this->getLinkData()),
+                "downloadable_product_samples" => array_values($this->getSampleData()),
+            ],
+        ];
+
+        $response =  $this->createProduct($product);
+        $this->assertEquals(self::PRODUCT_SKU, $response[ProductInterface::SKU]);
+        $this->assertEquals(10, $response['price']);
+        $this->assertEquals(
+            \Magento\Downloadable\Model\Product\Type::TYPE_DOWNLOADABLE,
+            $response['type_id']
+        );
+        return $response;
+    }
+
+    /**
+     * Create a downloadable product with two links and two samples
+     */
+    public function testCreateDownloadableProduct()
+    {
+        $response = $this->createDownloadableProduct();
+        $this->assertTrue(
+            isset($response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["downloadable_product_links"])
+        );
+        $this->assertTrue(
+            isset($response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["downloadable_product_samples"])
+        );
+        $resultLinks
+            = $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["downloadable_product_links"];
+        $this->assertEquals(2, count($resultLinks));
+        $this->assertTrue(isset($resultLinks[0]['id']));
+        $this->assertTrue(isset($resultLinks[0]['link_file']));
+        $this->assertTrue(isset($resultLinks[0]['sample_file']));
+        unset($resultLinks[0]['id']);
+        unset($resultLinks[0]['link_file']);
+        unset($resultLinks[0]['sample_file']);
+        $this->assertTrue(isset($resultLinks[1]['id']));
+        unset($resultLinks[1]['id']);
+
+        $expectedLinkData = $this->getExpectedLinkData();
+        $this->assertEquals($expectedLinkData, $resultLinks);
+
+        $resultSamples = $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["downloadable_product_samples"];
+        $this->assertEquals(2, count($resultSamples));
+        $this->assertTrue(isset($resultSamples[0]['id']));
+        unset($resultSamples[0]['id']);
+        $this->assertTrue(isset($resultSamples[1]['id']));
+        $this->assertTrue(isset($resultSamples[1]['sample_file']));
+        unset($resultSamples[1]['sample_file']);
+        unset($resultSamples[1]['id']);
+
+        $expectedSampleData = $this->getExpectedSampleData();
+        $this->assertEquals($expectedSampleData, $resultSamples);
+    }
+
+    /**
+     * Update downloadable product, update a link, add two link, delete a link
+     */
+    public function testUpdateDownloadableProductLinks()
+    {
+        $response = $this->createDownloadableProduct();
+        $resultLinks
+            = $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["downloadable_product_links"];
+        $link1Id = $resultLinks[0]['id'];
+        $link2Id = $resultLinks[1]['id'];
+
+        $linkFile = $resultLinks[0]['link_file'];
+        $sampleFile = $resultLinks[0]['sample_file'];
+        $updatedLink1Data = [
+            'id' => $link1Id,
+            'title' => 'link1_updated',
+            'sort_order' => 1, //the sort order needs to be smaller than 10
+            'is_shareable' => 0,
+            'price' => 5.0,
+            'number_of_downloads' => 999,
+            'link_type' => 'file',
+            'sample_type' => 'file',
+            'link_file' =>  'http://www.example.com/invalid', //this field will be overridden
+            'sample_file' => 'http://www.example.com/invalid', //this field will be overridden
+        ];
+        $linkData = $this->getLinkData();
+
+        $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["downloadable_product_links"] =
+            [$updatedLink1Data, $linkData['link1'], $linkData['link2']];
+        unset($response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["downloadable_product_samples"]);
+
+        $response = $this->saveProduct($response);
+        $this->assertTrue(
+            isset($response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["downloadable_product_links"])
+        );
+        $this->assertTrue(
+            isset($response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["downloadable_product_samples"])
+        );
+        $resultLinks
+            = $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["downloadable_product_links"];
+
+        $this->assertEquals(3, count($resultLinks));
+        $this->assertTrue(isset($resultLinks[0]['id']));
+        $this->assertEquals($link1Id, $resultLinks[0]['id']);
+        $this->assertTrue(isset($resultLinks[0]['link_file']));
+        $this->assertEquals($linkFile, $resultLinks[0]['link_file']);
+        $this->assertTrue(isset($resultLinks[0]['sample_file']));
+        $this->assertEquals($sampleFile, $resultLinks[0]['sample_file']);
+        unset($resultLinks[0]['id']);
+        unset($resultLinks[0]['link_file']);
+        unset($resultLinks[0]['sample_file']);
+        $this->assertTrue(isset($resultLinks[1]['id']));
+        $this->assertGreaterThan($link2Id, $resultLinks[1]['id']);
+        $this->assertTrue(isset($resultLinks[1]['link_file']));
+        $this->assertTrue(isset($resultLinks[1]['sample_file']));
+        unset($resultLinks[1]['id']);
+        unset($resultLinks[1]['link_file']);
+        unset($resultLinks[1]['sample_file']);
+        $this->assertTrue(isset($resultLinks[2]['id']));
+        $this->assertGreaterThan($link2Id, $resultLinks[2]['id']);
+        unset($resultLinks[2]['id']);
+
+        $expectedLinkData[] = [
+            'title' => 'link1_updated',
+            'sort_order' => 1, //the sort order needs to be smaller than 10
+            'is_shareable' => 0,
+            'price' => 5.0,
+            'number_of_downloads' => 999,
+            'link_type' => 'file',
+            'sample_type' => 'file',
+        ];
+        $expectedLinkData = array_merge($expectedLinkData, $this->getExpectedLinkData());
+        $this->assertEquals($expectedLinkData, $resultLinks);
+
+        $resultSamples = $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["downloadable_product_samples"];
+        $this->assertEquals(2, count($resultSamples));
+    }
+
+    /**
+     * Update downloadable product, update two links and change file content
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     */
+    public function testUpdateDownloadableProductLinksWithNewFile()
+    {
+        $response = $this->createDownloadableProduct();
+        $resultLinks
+            = $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["downloadable_product_links"];
+        $link1Id = $resultLinks[0]['id'];
+        $link2Id = $resultLinks[1]['id'];
+
+        $linkFile = 'link1_content_updated.jpg';
+        $sampleFile = 'link1_sample_updated.jpg';
+        $updatedLink1Data = [
+            'id' => $link1Id,
+            'title' => 'link1_updated',
+            'sort_order' => 1, //the sort order needs to be smaller than 10
+            'is_shareable' => 0,
+            'price' => 5.0,
+            'number_of_downloads' => 999,
+            'link_type' => 'file',
+            'link_file_content' => [
+                'name' => $linkFile,
+                'file_data' => base64_encode(file_get_contents($this->testImagePath)),
+            ],
+            'sample_type' => 'file',
+            'sample_file_content' => [
+                'name' => $sampleFile,
+                'file_data' => base64_encode(file_get_contents($this->testImagePath)),
+            ],
+        ];
+        $updatedLink2Data = [
+            'id' => $link2Id,
+            'title' => 'link2_updated',
+            'sort_order' => 2,
+            'is_shareable' => 0,
+            'price' => 6.0,
+            'number_of_downloads' => 0,
+            'link_type' => 'file',
+            'link_file_content' => [
+                'name' => 'link2_content.jpg',
+                'file_data' => base64_encode(file_get_contents($this->testImagePath)),
+            ],
+            'sample_type' => 'file',
+            'sample_file_content' => [
+                'name' => 'link2_sample.jpg',
+                'file_data' => base64_encode(file_get_contents($this->testImagePath)),
+            ],
+        ];
+
+        $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["downloadable_product_links"] =
+            [$updatedLink1Data, $updatedLink2Data];
+        unset($response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["downloadable_product_samples"]);
+
+        $response = $this->saveProduct($response);
+        $this->assertTrue(
+            isset($response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["downloadable_product_links"])
+        );
+        $this->assertTrue(
+            isset($response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["downloadable_product_samples"])
+        );
+        $resultLinks
+            = $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["downloadable_product_links"];
+
+        $this->assertEquals(2, count($resultLinks));
+        $this->assertTrue(isset($resultLinks[0]['id']));
+        $this->assertEquals($link1Id, $resultLinks[0]['id']);
+        $this->assertTrue(isset($resultLinks[0]['link_file']));
+        $this->assertGreaterThan(0, strpos($resultLinks[0]['link_file'], $linkFile));
+        $this->assertTrue(isset($resultLinks[0]['sample_file']));
+        $this->assertGreaterThan(0, strpos($resultLinks[0]['sample_file'], $sampleFile));
+        unset($resultLinks[0]['id']);
+        unset($resultLinks[0]['link_file']);
+        unset($resultLinks[0]['sample_file']);
+        $this->assertTrue(isset($resultLinks[1]['id']));
+        $this->assertEquals($link2Id, $resultLinks[1]['id']);
+        $this->assertTrue(isset($resultLinks[1]['link_file']));
+        $this->assertTrue(isset($resultLinks[1]['sample_file']));
+        unset($resultLinks[1]['id']);
+        unset($resultLinks[1]['link_file']);
+        unset($resultLinks[1]['sample_file']);
+
+        $expectedLinkData = [
+            [
+                'title' => 'link1_updated',
+                'sort_order' => 1, //the sort order needs to be smaller than 10
+                'is_shareable' => 0,
+                'price' => 5.0,
+                'number_of_downloads' => 999,
+                'link_type' => 'file',
+                'sample_type' => 'file',
+            ],
+            [
+                'title' => 'link2_updated',
+                'sort_order' => 2,
+                'is_shareable' => 0,
+                'price' => 6.0,
+                'number_of_downloads' => 0,
+                'link_type' => 'file',
+                'sample_type' => 'file',
+                'link_url' => 'http://www.example.com/link2.jpg', //urls are still saved, just not used
+                'sample_url' => 'http://www.example.com/link2.jpg',
+            ]
+        ];
+        $this->assertEquals($expectedLinkData, $resultLinks);
+
+        $resultSamples = $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["downloadable_product_samples"];
+        $this->assertEquals(2, count($resultSamples));
+    }
+
+    public function testUpdateDownloadableProductSamples()
+    {
+        $response = $this->createDownloadableProduct();
+
+        $resultSample
+            = $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["downloadable_product_samples"];
+        $sample1Id = $resultSample[0]['id'];
+        $sample2Id = $resultSample[1]['id'];
+
+        $updatedSample1Data = [
+            'id' => $sample1Id,
+            'title' => 'sample1_updated',
+            'sort_order' => 1,
+            'sample_type' => 'url',
+            'sample_url' => 'http://www.example.com/sample1.jpg',
+        ];
+        $sampleData = $this->getSampleData();
+
+        unset($response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["downloadable_product_links"]);
+        $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["downloadable_product_samples"] =
+            [$updatedSample1Data, $sampleData['sample1'], $sampleData['sample2']];
+
+        $response = $this->saveProduct($response);
+        $this->assertTrue(
+            isset($response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["downloadable_product_links"])
+        );
+        $this->assertTrue(
+            isset($response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["downloadable_product_samples"])
+        );
+        $resultLinks
+            = $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["downloadable_product_links"];
+
+        $this->assertEquals(2, count($resultLinks));
+
+        $resultSamples = $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["downloadable_product_samples"];
+        $this->assertEquals(3, count($resultSamples));
+        $this->assertTrue(isset($resultSamples[0]['id']));
+        $this->assertEquals($sample1Id, $resultSamples[0]['id']);
+        unset($resultSamples[0]['id']);
+        $this->assertTrue(isset($resultSamples[1]['id']));
+        $this->assertGreaterThan($sample2Id, $resultSamples[1]['id']);
+        unset($resultSamples[1]['id']);
+        $this->assertTrue(isset($resultSamples[2]['id']));
+        $this->assertGreaterThan($sample2Id, $resultSamples[2]['id']);
+        $this->assertTrue(isset($resultSamples[2]['sample_file']));
+        unset($resultSamples[2]['sample_file']);
+        unset($resultSamples[2]['id']);
+
+        $expectedSampleData[] = [
+            'title' => 'sample1_updated',
+            'sort_order' => 1,
+            'sample_type' => 'url',
+            'sample_url' => 'http://www.example.com/sample1.jpg',
+        ];
+        $expectedSampleData = array_merge($expectedSampleData, $this->getExpectedSampleData());
+        $this->assertEquals($expectedSampleData, $resultSamples);
+    }
+
+    public function testUpdateDownloadableProductSamplesWithNewFile()
+    {
+        $response = $this->createDownloadableProduct();
+
+        $resultSample
+            = $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["downloadable_product_samples"];
+        $sample1Id = $resultSample[0]['id'];
+        $sample2Id = $resultSample[1]['id'];
+
+        //upload a file for sample 1
+        $updatedSample1Data = [
+            'id' => $sample1Id,
+            'title' => 'sample1_updated',
+            'sort_order' => 1,
+            'sample_type' => 'file',
+            'sample_file_content' => [
+                'name' => 'sample1.jpg',
+                'file_data' => base64_encode(file_get_contents($this->testImagePath)),
+            ],
+        ];
+        //change title for sample 2
+        $updatedSamp2e1Data = [
+            'id' => $sample2Id,
+            'title' => 'sample2_updated',
+            'sort_order' => 2,
+            'sample_type' => 'file',
+        ];
+
+        unset($response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["downloadable_product_links"]);
+        $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["downloadable_product_samples"] =
+            [$updatedSample1Data, $updatedSamp2e1Data];
+
+        $response = $this->saveProduct($response);
+        $this->assertTrue(
+            isset($response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["downloadable_product_links"])
+        );
+        $this->assertTrue(
+            isset($response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["downloadable_product_samples"])
+        );
+        $resultLinks
+            = $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["downloadable_product_links"];
+
+        $this->assertEquals(2, count($resultLinks));
+
+        $resultSamples = $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["downloadable_product_samples"];
+        $this->assertEquals(2, count($resultSamples));
+        $this->assertTrue(isset($resultSamples[0]['id']));
+        $this->assertEquals($sample1Id, $resultSamples[0]['id']);
+        unset($resultSamples[0]['id']);
+        $this->assertTrue(isset($resultSamples[0]['sample_file']));
+        $this->assertContains('sample1.jpg', $resultSamples[0]['sample_file']);
+        unset($resultSamples[0]['sample_file']);
+        $this->assertTrue(isset($resultSamples[1]['id']));
+        $this->assertEquals($sample2Id, $resultSamples[1]['id']);
+        unset($resultSamples[1]['id']);
+        $this->assertTrue(isset($resultSamples[1]['sample_file']));
+        $this->assertContains('sample2.jpg', $resultSamples[1]['sample_file']);
+        unset($resultSamples[1]['sample_file']);
+
+        $expectedSampleData = [
+            [
+                'title' => 'sample1_updated',
+                'sort_order' => 1,
+                'sample_type' => 'file',
+                'sample_url' => 'http://www.example.com/sample1.jpg',
+            ],
+            [
+                'title' => 'sample2_updated',
+                'sort_order' => 2,
+                'sample_type' => 'file',
+            ],
+        ];
+        $this->assertEquals($expectedSampleData, $resultSamples);
+    }
+
+    /**
+     * Get product
+     *
+     * @param string $productSku
+     * @return array the product data
+     */
+    protected function getProduct($productSku)
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $productSku,
+                'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Get',
+            ],
+        ];
+
+        $response = (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) ?
+            $this->_webApiCall($serviceInfo, ['sku' => $productSku]) : $this->_webApiCall($serviceInfo);
+
+        return $response;
+    }
+
+    /**
+     * Create product
+     *
+     * @param array $product
+     * @return array the created product data
+     */
+    protected function createProduct($product)
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH,
+                'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Save',
+            ],
+        ];
+        $requestData = ['product' => $product];
+        $response = $this->_webApiCall($serviceInfo, $requestData);
+        return $response;
+    }
+
+    /**
+     * Delete a product by sku
+     *
+     * @param $productSku
+     * @return bool
+     */
+    protected function deleteProductBySku($productSku)
+    {
+        $resourcePath = self::RESOURCE_PATH . '/' . $productSku;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $resourcePath,
+                'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_DELETE
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'deleteById',
+            ],
+        ];
+        $requestData = ["sku" => $productSku];
+        $response = $this->_webApiCall($serviceInfo, $requestData);
+        return $response;
+    }
+
+    /**
+     * Save product
+     *
+     * @param array $product
+     * @return array the created product data
+     */
+    protected function saveProduct($product)
+    {
+        $resourcePath = self::RESOURCE_PATH . '/' . $product['sku'];
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $resourcePath,
+                'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_PUT
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Save',
+            ],
+        ];
+        $requestData = ['product' => $product];
+        $response = $this->_webApiCall($serviceInfo, $requestData);
+        return $response;
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/SampleRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/SampleRepositoryTest.php
index c4fe8606cb8bc9f680e3db3da0bdc4061941a05c..0a1bba69a89890b7feeec2afd84a793181e2d239 100644
--- a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/SampleRepositoryTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/SampleRepositoryTest.php
@@ -79,9 +79,11 @@ class SampleRepositoryTest extends WebapiAbstract
      */
     protected function getTargetProduct($isScopeGlobal = false)
     {
-        $product = Bootstrap::getObjectManager()->get('Magento\Catalog\Model\ProductFactory')->create()->load(1);
         if ($isScopeGlobal) {
-            $product->setStoreId(0);
+            $product = Bootstrap::getObjectManager()->get('Magento\Catalog\Model\ProductFactory')
+                ->create()->setStoreId(0)->load(1);
+        } else {
+            $product = Bootstrap::getObjectManager()->get('Magento\Catalog\Model\ProductFactory')->create()->load(1);
         }
 
         return $product;
@@ -120,11 +122,11 @@ class SampleRepositoryTest extends WebapiAbstract
     {
         $requestData = [
             'isGlobalScopeContent' => true,
-            'productSku' => 'downloadable-product',
-            'sampleContent' => [
+            'sku' => 'downloadable-product',
+            'sample' => [
                 'title' => 'Title',
                 'sort_order' => 1,
-                'sample_file' => [
+                'sample_file_content' => [
                     'file_data' => base64_encode(file_get_contents($this->testImagePath)),
                     'name' => 'image.jpg',
                 ],
@@ -136,10 +138,11 @@ class SampleRepositoryTest extends WebapiAbstract
         $globalScopeSample = $this->getTargetSample($this->getTargetProduct(true), $newSampleId);
         $sample = $this->getTargetSample($this->getTargetProduct(), $newSampleId);
         $this->assertNotNull($sample);
-        $this->assertEquals($requestData['sampleContent']['title'], $sample->getTitle());
-        $this->assertEquals($requestData['sampleContent']['title'], $globalScopeSample->getTitle());
-        $this->assertEquals($requestData['sampleContent']['sort_order'], $sample->getSortOrder());
-        $this->assertEquals($requestData['sampleContent']['sample_type'], $sample->getSampleType());
+        $this->assertNotNull($sample->getId());
+        $this->assertEquals($requestData['sample']['title'], $sample->getTitle());
+        $this->assertEquals($requestData['sample']['title'], $globalScopeSample->getTitle());
+        $this->assertEquals($requestData['sample']['sort_order'], $sample->getSortOrder());
+        $this->assertEquals($requestData['sample']['sample_type'], $sample->getSampleType());
         $this->assertStringEndsWith('.jpg', $sample->getSampleFile());
         $this->assertNull($sample->getSampleUrl());
     }
@@ -151,8 +154,8 @@ class SampleRepositoryTest extends WebapiAbstract
     {
         $requestData = [
             'isGlobalScopeContent' => false,
-            'productSku' => 'downloadable-product',
-            'sampleContent' => [
+            'sku' => 'downloadable-product',
+            'sample' => [
                 'title' => 'Store View Title',
                 'sort_order' => 1,
                 'sample_url' => 'http://www.sample.example.com/',
@@ -164,10 +167,10 @@ class SampleRepositoryTest extends WebapiAbstract
         $sample = $this->getTargetSample($this->getTargetProduct(), $newSampleId);
         $globalScopeSample = $this->getTargetSample($this->getTargetProduct(true), $newSampleId);
         $this->assertNotNull($sample);
-        $this->assertEquals($requestData['sampleContent']['title'], $sample->getTitle());
-        $this->assertEquals($requestData['sampleContent']['sort_order'], $sample->getSortOrder());
-        $this->assertEquals($requestData['sampleContent']['sample_url'], $sample->getSampleUrl());
-        $this->assertEquals($requestData['sampleContent']['sample_type'], $sample->getSampleType());
+        $this->assertEquals($requestData['sample']['title'], $sample->getTitle());
+        $this->assertEquals($requestData['sample']['sort_order'], $sample->getSortOrder());
+        $this->assertEquals($requestData['sample']['sample_url'], $sample->getSampleUrl());
+        $this->assertEquals($requestData['sample']['sample_type'], $sample->getSampleType());
         $this->assertEmpty($globalScopeSample->getTitle());
     }
 
@@ -178,8 +181,8 @@ class SampleRepositoryTest extends WebapiAbstract
     {
         $requestData = [
             'isGlobalScopeContent' => false,
-            'productSku' => 'downloadable-product',
-            'sampleContent' => [
+            'sku' => 'downloadable-product',
+            'sample' => [
                 'title' => 'Sample with URL resource',
                 'sort_order' => 1,
                 'sample_url' => 'http://www.sample.example.com/',
@@ -190,10 +193,10 @@ class SampleRepositoryTest extends WebapiAbstract
         $newSampleId = $this->_webApiCall($this->createServiceInfo, $requestData);
         $sample = $this->getTargetSample($this->getTargetProduct(), $newSampleId);
         $this->assertNotNull($sample);
-        $this->assertEquals($requestData['sampleContent']['title'], $sample->getTitle());
-        $this->assertEquals($requestData['sampleContent']['sort_order'], $sample->getSortOrder());
-        $this->assertEquals($requestData['sampleContent']['sample_type'], $sample->getSampleType());
-        $this->assertEquals($requestData['sampleContent']['sample_url'], $sample->getSampleUrl());
+        $this->assertEquals($requestData['sample']['title'], $sample->getTitle());
+        $this->assertEquals($requestData['sample']['sort_order'], $sample->getSortOrder());
+        $this->assertEquals($requestData['sample']['sample_type'], $sample->getSampleType());
+        $this->assertEquals($requestData['sample']['sample_url'], $sample->getSampleUrl());
     }
 
     /**
@@ -201,14 +204,15 @@ class SampleRepositoryTest extends WebapiAbstract
      * @expectedException \Exception
      * @expectedExceptionMessage Invalid sample type.
      */
-    public function testCreateThrowsExceptionIfSampleTypeIsNotSpecified()
+    public function testCreateThrowsExceptionIfSampleTypeIsInvalid()
     {
         $requestData = [
             'isGlobalScopeContent' => false,
-            'productSku' => 'downloadable-product',
-            'sampleContent' => [
+            'sku' => 'downloadable-product',
+            'sample' => [
                 'title' => 'Sample with URL resource',
                 'sort_order' => 1,
+                'sample_type' => 'invalid',
             ],
         ];
 
@@ -224,12 +228,12 @@ class SampleRepositoryTest extends WebapiAbstract
     {
         $requestData = [
             'isGlobalScopeContent' => false,
-            'productSku' => 'downloadable-product',
-            'sampleContent' => [
+            'sku' => 'downloadable-product',
+            'sample' => [
                 'title' => 'Sample Title',
                 'sort_order' => 1,
                 'sample_type' => 'file',
-                'sample_file' => [
+                'sample_file_content' => [
                     'file_data' => 'not_a_base64_encoded_content',
                     'name' => 'image.jpg',
                 ],
@@ -248,12 +252,12 @@ class SampleRepositoryTest extends WebapiAbstract
     {
         $requestData = [
             'isGlobalScopeContent' => false,
-            'productSku' => 'downloadable-product',
-            'sampleContent' => [
+            'sku' => 'downloadable-product',
+            'sample' => [
                 'title' => 'Title',
                 'sort_order' => 15,
                 'sample_type' => 'file',
-                'sample_file' => [
+                'sample_file_content' => [
                     'file_data' => base64_encode(file_get_contents($this->testImagePath)),
                     'name' => 'name/with|forbidden{characters',
                 ],
@@ -272,8 +276,8 @@ class SampleRepositoryTest extends WebapiAbstract
     {
         $requestData = [
             'isGlobalScopeContent' => false,
-            'productSku' => 'downloadable-product',
-            'sampleContent' => [
+            'sku' => 'downloadable-product',
+            'sample' => [
                 'title' => 'Sample Title',
                 'sort_order' => 1,
                 'sample_type' => 'url',
@@ -294,8 +298,8 @@ class SampleRepositoryTest extends WebapiAbstract
     {
         $requestData = [
             'isGlobalScopeContent' => false,
-            'productSku' => 'downloadable-product',
-            'sampleContent' => [
+            'sku' => 'downloadable-product',
+            'sample' => [
                 'title' => 'Sample Title',
                 'sort_order' => $sortOrder,
                 'sample_type' => 'url',
@@ -325,8 +329,8 @@ class SampleRepositoryTest extends WebapiAbstract
         $this->createServiceInfo['rest']['resourcePath'] = '/V1/products/simple/downloadable-links/samples';
         $requestData = [
             'isGlobalScopeContent' => false,
-            'productSku' => 'simple',
-            'sampleContent' => [
+            'sku' => 'simple',
+            'sample' => [
                 'title' => 'Sample Title',
                 'sort_order' => 50,
                 'sample_type' => 'url',
@@ -345,8 +349,8 @@ class SampleRepositoryTest extends WebapiAbstract
         $this->createServiceInfo['rest']['resourcePath'] = '/V1/products/wrong-sku/downloadable-links/samples';
         $requestData = [
             'isGlobalScopeContent' => false,
-            'productSku' => 'wrong-sku',
-            'sampleContent' => [
+            'sku' => 'wrong-sku',
+            'sample' => [
                 'title' => 'Title',
                 'sort_order' => 15,
                 'sample_type' => 'url',
@@ -366,19 +370,21 @@ class SampleRepositoryTest extends WebapiAbstract
             = "/V1/products/downloadable-product/downloadable-links/samples/{$sampleId}";
         $requestData = [
             'isGlobalScopeContent' => false,
-            'sampleId' => $sampleId,
-            'productSku' => 'downloadable-product',
-            'sampleContent' => [
+            'sku' => 'downloadable-product',
+            'sample' => [
+                'id' => $sampleId,
                 'title' => 'Updated Title',
                 'sort_order' => 2,
+                'sample_type' => 'url',
             ],
         ];
 
         $this->assertEquals($sampleId, $this->_webApiCall($this->updateServiceInfo, $requestData));
         $sample = $this->getTargetSample($this->getTargetProduct(), $sampleId);
         $this->assertNotNull($sample);
-        $this->assertEquals($requestData['sampleContent']['title'], $sample->getTitle());
-        $this->assertEquals($requestData['sampleContent']['sort_order'], $sample->getSortOrder());
+        $this->assertEquals($requestData['sample']['id'], $sample->getId());
+        $this->assertEquals($requestData['sample']['title'], $sample->getTitle());
+        $this->assertEquals($requestData['sample']['sort_order'], $sample->getSortOrder());
     }
 
     /**
@@ -392,11 +398,12 @@ class SampleRepositoryTest extends WebapiAbstract
             = "/V1/products/downloadable-product/downloadable-links/samples/{$sampleId}";
         $requestData = [
             'isGlobalScopeContent' => true,
-            'sampleId' => $sampleId,
-            'productSku' => 'downloadable-product',
-            'sampleContent' => [
+            'sku' => 'downloadable-product',
+            'sample' => [
+                'id' => $sampleId,
                 'title' => 'Updated Title',
                 'sort_order' => 2,
+                'sample_type' => 'url',
             ],
         ];
 
@@ -406,8 +413,8 @@ class SampleRepositoryTest extends WebapiAbstract
         $this->assertNotNull($sample);
         // Title was set on store view level in fixture so it must be the same
         $this->assertEquals($originalSample->getTitle(), $sample->getTitle());
-        $this->assertEquals($requestData['sampleContent']['title'], $globalScopeSample->getTitle());
-        $this->assertEquals($requestData['sampleContent']['sort_order'], $sample->getSortOrder());
+        $this->assertEquals($requestData['sample']['title'], $globalScopeSample->getTitle());
+        $this->assertEquals($requestData['sample']['sort_order'], $sample->getSortOrder());
     }
 
     /**
@@ -419,11 +426,12 @@ class SampleRepositoryTest extends WebapiAbstract
         $this->updateServiceInfo['rest']['resourcePath'] = '/V1/products/wrong-sku/downloadable-links/samples/1';
         $requestData = [
             'isGlobalScopeContent' => true,
-            'sampleId' => 1,
-            'productSku' => 'wrong-sku',
-            'sampleContent' => [
+            'sku' => 'wrong-sku',
+            'sample' => [
+                'id' => 1,
                 'title' => 'Updated Title',
                 'sort_order' => 2,
+                'sample_type' => 'url',
             ],
         ];
         $this->_webApiCall($this->updateServiceInfo, $requestData);
@@ -441,11 +449,12 @@ class SampleRepositoryTest extends WebapiAbstract
             = "/V1/products/downloadable-product/downloadable-links/samples/{$sampleId}";
         $requestData = [
             'isGlobalScopeContent' => true,
-            'sampleId' => 9999,
-            'productSku' => 'downloadable-product',
-            'sampleContent' => [
+            'sku' => 'downloadable-product',
+            'sample' => [
+                'id' => $sampleId,
                 'title' => 'Title',
                 'sort_order' => 2,
+                'sample_type' => 'url',
             ],
         ];
 
@@ -465,11 +474,12 @@ class SampleRepositoryTest extends WebapiAbstract
             = "/V1/products/downloadable-product/downloadable-links/samples/{$sampleId}";
         $requestData = [
             'isGlobalScopeContent' => false,
-            'sampleId' => $sampleId,
-            'productSku' => 'downloadable-product',
-            'sampleContent' => [
+            'sku' => 'downloadable-product',
+            'sample' => [
+                'id' => $sampleId,
                 'title' => 'Updated Sample Title',
                 'sort_order' => $sortOrder,
+                'sample_type' => 'url',
             ],
         ];
         $this->_webApiCall($this->updateServiceInfo, $requestData);
@@ -483,7 +493,7 @@ class SampleRepositoryTest extends WebapiAbstract
         $sampleId = $this->getTargetSample($this->getTargetProduct())->getId();
         $this->deleteServiceInfo['rest']['resourcePath'] = "/V1/products/downloadable-links/samples/{$sampleId}";
         $requestData = [
-            'sampleId' => $sampleId,
+            'id' => $sampleId,
         ];
 
         $this->assertTrue($this->_webApiCall($this->deleteServiceInfo, $requestData));
@@ -500,7 +510,7 @@ class SampleRepositoryTest extends WebapiAbstract
         $sampleId = 9999;
         $this->deleteServiceInfo['rest']['resourcePath'] = "/V1/products/downloadable-links/samples/{$sampleId}";
         $requestData = [
-            'sampleId' => $sampleId,
+            'id' => $sampleId,
         ];
 
         $this->_webApiCall($this->deleteServiceInfo, $requestData);
diff --git a/dev/tests/api-functional/testsuite/Magento/GroupedProduct/Api/ProductRepositoryInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/GroupedProduct/Api/ProductRepositoryInterfaceTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..c8ab24527c633a12fd46442a9528570a4586e458
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/GroupedProduct/Api/ProductRepositoryInterfaceTest.php
@@ -0,0 +1,203 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\GroupedProduct\Api;
+
+use Magento\Catalog\Api\Data\ProductInterface;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+
+class ProductRepositoryInterfaceTest extends WebapiAbstract
+{
+    const SERVICE_NAME = 'catalogProductRepositoryV1';
+    const SERVICE_VERSION = 'V1';
+    const RESOURCE_PATH = '/V1/products';
+
+    /**
+     * Get Product
+     *
+     * @param $sku
+     * @return ProductInterface
+     */
+    protected function getProduct($sku)
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $sku,
+                'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Get',
+            ],
+        ];
+
+        $response = $this->_webApiCall($serviceInfo, ['sku' => $sku]);
+        return $response;
+    }
+
+    /**
+     * Update Product
+     *
+     * @param $product
+     * @return mixed
+     */
+    protected function updateProduct($product)
+    {
+        $sku = $product[ProductInterface::SKU];
+        if (TESTS_WEB_API_ADAPTER == self::ADAPTER_REST) {
+            $product[ProductInterface::SKU] = null;
+        }
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $sku,
+                'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Save',
+            ],
+        ];
+        $requestData = ['product' => $product];
+        $response =  $this->_webApiCall($serviceInfo, $requestData);
+        return $response;
+    }
+
+    /**
+     * Save Product
+     *
+     * @param $product
+     * @return mixed
+     */
+    protected function saveProduct($product)
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH,
+                'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Save',
+            ],
+        ];
+        $requestData = ['product' => $product];
+        return $this->_webApiCall($serviceInfo, $requestData);
+    }
+
+    /**
+     * Delete Product
+     *
+     * @param string $sku
+     * @return boolean
+     */
+    protected function deleteProduct($sku)
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $sku,
+                'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_DELETE,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'DeleteById',
+            ],
+        ];
+
+        return (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) ?
+            $this->_webApiCall($serviceInfo, ['sku' => $sku]) : $this->_webApiCall($serviceInfo);
+    }
+
+    public function testProductLinks()
+    {
+        // Create simple product
+        $productData =  [
+            ProductInterface::SKU => "product_simple_500",
+            ProductInterface::NAME => "Product Simple 500",
+            ProductInterface::VISIBILITY => 4,
+            ProductInterface::TYPE_ID => 'simple',
+            ProductInterface::PRICE => 100,
+            ProductInterface::STATUS => 1,
+            ProductInterface::TYPE_ID => 'simple',
+            ProductInterface::ATTRIBUTE_SET_ID => 4,
+        ];
+
+        $this->saveProduct($productData);
+
+        // Create a group product
+        $productLinkData = ["product_sku" => "group_product_500", "link_type" => "associated",
+                            "linked_product_sku" => "product_simple_500", "linked_product_type" => "simple",
+                            "position" => 0, "extension_attributes" => ["qty" => 1]];
+        $productWithGroupData =  [
+            ProductInterface::SKU => "group_product_500",
+            ProductInterface::NAME => "Group Product 500",
+            ProductInterface::VISIBILITY => 4,
+            ProductInterface::TYPE_ID => 'grouped',
+            ProductInterface::PRICE => 300,
+            ProductInterface::STATUS => 1,
+            ProductInterface::ATTRIBUTE_SET_ID => 4,
+            "product_links" => [$productLinkData]
+        ];
+
+        $this->saveProduct($productWithGroupData);
+        $response = $this->getProduct("group_product_500");
+        $this->assertArrayHasKey('product_links', $response);
+        $links = $response['product_links'];
+        $this->assertEquals(1, count($links));
+        $this->assertEquals($productLinkData, $links[0]);
+
+        // update link information for Group Product
+        $productLinkData1 = ["product_sku" => "group_product_500", "link_type" => "associated",
+                            "linked_product_sku" => "product_simple_500", "linked_product_type" => "simple",
+                            "position" => 0, "extension_attributes" => ["qty" => 4]];
+        $productLinkData2 = ["product_sku" => "group_product_500", "link_type" => "upsell",
+                             "linked_product_sku" => "product_simple_500", "linked_product_type" => "simple",
+                             "position" => 0, "extension_attributes" => []];
+        $productWithGroupData =  [
+            ProductInterface::SKU => "group_product_500",
+            ProductInterface::NAME => "Group Product 500",
+            ProductInterface::VISIBILITY => 4,
+            ProductInterface::TYPE_ID => 'grouped',
+            ProductInterface::PRICE => 300,
+            ProductInterface::STATUS => 1,
+            ProductInterface::ATTRIBUTE_SET_ID => 4,
+            "product_links" => [$productLinkData1, $productLinkData2]
+        ];
+
+        $this->saveProduct($productWithGroupData);
+        $response = $this->getProduct("group_product_500");
+
+        $this->assertArrayHasKey('product_links', $response);
+        $links = $response['product_links'];
+        $this->assertEquals(2, count($links));
+        $this->assertEquals($productLinkData1, $links[1]);
+        $this->assertEquals($productLinkData2, $links[0]);
+
+        // Remove link
+        $productWithNoLinkData =  [
+            ProductInterface::SKU => "group_product_500",
+            ProductInterface::NAME => "Group Product 500",
+            ProductInterface::VISIBILITY => 4,
+            ProductInterface::TYPE_ID => 'grouped',
+            ProductInterface::PRICE => 300,
+            ProductInterface::STATUS => 1,
+            ProductInterface::ATTRIBUTE_SET_ID => 4,
+            "product_links" => []
+        ];
+
+        $this->saveProduct($productWithNoLinkData);
+        $response = $this->getProduct("group_product_500");
+        $this->assertArrayHasKey('product_links', $response);
+        $links = $response['product_links'];
+        $this->assertEquals([], $links);
+
+        $this->deleteProduct("product_simple_500");
+        $this->deleteProduct("group_product_500");
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Tax/Api/TaxClassRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Tax/Api/TaxClassRepositoryTest.php
index 1557278ce1bb31a76ac96d90a90c57b6bada4d21..2d20a4e9110939aa3c8298b8eb6e317436bf2454 100644
--- a/dev/tests/api-functional/testsuite/Magento/Tax/Api/TaxClassRepositoryTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Tax/Api/TaxClassRepositoryTest.php
@@ -12,6 +12,7 @@ use Magento\Framework\Api\FilterBuilder;
 use Magento\Framework\Api\SearchCriteriaBuilder;
 use Magento\Framework\Exception\NoSuchEntityException;
 use Magento\Tax\Api\Data\TaxClassInterfaceFactory;
+use Magento\Tax\Model\ClassModel;
 use Magento\Tax\Model\ClassModelRegistry;
 use Magento\TestFramework\Helper\Bootstrap;
 use Magento\TestFramework\TestCase\WebapiAbstract;
@@ -171,9 +172,9 @@ class TaxClassRepositoryTest extends WebapiAbstract
         ];
         $requestData = ['taxClassId' => $taxClassId];
         $taxClassData = $this->_webApiCall($serviceInfo, $requestData);
-        $this->assertEquals($taxClassData[Data\TaxClassInterface::KEY_NAME], $taxClassName);
+        $this->assertEquals($taxClassData[ClassModel::KEY_NAME], $taxClassName);
         $this->assertEquals(
-            $taxClassData[Data\TaxClassInterface::KEY_TYPE],
+            $taxClassData[ClassModel::KEY_TYPE],
             TaxClassManagementInterface::TYPE_CUSTOMER
         );
     }
@@ -220,7 +221,7 @@ class TaxClassRepositoryTest extends WebapiAbstract
     public function testSearchTaxClass()
     {
         $taxClassName = 'Retail Customer';
-        $taxClassNameField = Data\TaxClassInterface::KEY_NAME;
+        $taxClassNameField = ClassModel::KEY_NAME;
         $filter = $this->filterBuilder->setField($taxClassNameField)
             ->setValue($taxClassName)
             ->create();
@@ -249,23 +250,23 @@ class TaxClassRepositoryTest extends WebapiAbstract
     public function testSearchTaxClassMultipleFilterGroups()
     {
         $productTaxClass = [
-            Data\TaxClassInterface::KEY_NAME => 'Taxable Goods',
-            Data\TaxClassInterface::KEY_TYPE => 'PRODUCT',
+            ClassModel::KEY_NAME => 'Taxable Goods',
+            ClassModel::KEY_TYPE => 'PRODUCT',
         ];
-        $customerTaxClass = [Data\TaxClassInterface::KEY_NAME => 'Retail Customer',
-            Data\TaxClassInterface::KEY_TYPE => 'CUSTOMER', ];
+        $customerTaxClass = [ClassModel::KEY_NAME => 'Retail Customer',
+            ClassModel::KEY_TYPE => 'CUSTOMER', ];
 
-        $filter1 = $this->filterBuilder->setField(Data\TaxClassInterface::KEY_NAME)
-            ->setValue($productTaxClass[Data\TaxClassInterface::KEY_NAME])
+        $filter1 = $this->filterBuilder->setField(ClassModel::KEY_NAME)
+            ->setValue($productTaxClass[ClassModel::KEY_NAME])
             ->create();
-        $filter2 = $this->filterBuilder->setField(Data\TaxClassInterface::KEY_NAME)
-            ->setValue($customerTaxClass[Data\TaxClassInterface::KEY_NAME])
+        $filter2 = $this->filterBuilder->setField(ClassModel::KEY_NAME)
+            ->setValue($customerTaxClass[ClassModel::KEY_NAME])
             ->create();
-        $filter3 = $this->filterBuilder->setField(Data\TaxClassInterface::KEY_TYPE)
-            ->setValue($productTaxClass[Data\TaxClassInterface::KEY_TYPE])
+        $filter3 = $this->filterBuilder->setField(ClassModel::KEY_TYPE)
+            ->setValue($productTaxClass[ClassModel::KEY_TYPE])
             ->create();
-        $filter4 = $this->filterBuilder->setField(Data\TaxClassInterface::KEY_TYPE)
-            ->setValue($customerTaxClass[Data\TaxClassInterface::KEY_TYPE])
+        $filter4 = $this->filterBuilder->setField(ClassModel::KEY_TYPE)
+            ->setValue($customerTaxClass[ClassModel::KEY_TYPE])
             ->create();
 
         /**
@@ -291,12 +292,12 @@ class TaxClassRepositoryTest extends WebapiAbstract
         $searchResults = $this->_webApiCall($serviceInfo, $requestData);
         $this->assertEquals(2, $searchResults['total_count']);
         $this->assertEquals(
-            $productTaxClass[Data\TaxClassInterface::KEY_NAME],
-            $searchResults['items'][0][Data\TaxClassInterface::KEY_NAME]
+            $productTaxClass[ClassModel::KEY_NAME],
+            $searchResults['items'][0][ClassModel::KEY_NAME]
         );
         $this->assertEquals(
-            $customerTaxClass[Data\TaxClassInterface::KEY_NAME],
-            $searchResults['items'][1][Data\TaxClassInterface::KEY_NAME]
+            $customerTaxClass[ClassModel::KEY_NAME],
+            $searchResults['items'][1][ClassModel::KEY_NAME]
         );
 
         /** class_name == 'Retail Customer' && ( class_type == 'CUSTOMER' || class_type == 'PRODUCT') */
@@ -309,8 +310,8 @@ class TaxClassRepositoryTest extends WebapiAbstract
         $searchResults = $this->_webApiCall($serviceInfo, $requestData);
         $this->assertEquals(1, $searchResults['total_count']);
         $this->assertEquals(
-            $customerTaxClass[Data\TaxClassInterface::KEY_NAME],
-            $searchResults['items'][0][Data\TaxClassInterface::KEY_NAME]
+            $customerTaxClass[ClassModel::KEY_NAME],
+            $searchResults['items'][0][ClassModel::KEY_NAME]
         );
     }
 }
diff --git a/dev/tests/api-functional/testsuite/Magento/Tax/Api/TaxRateRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Tax/Api/TaxRateRepositoryTest.php
index 9f47505721b8f6bb1e4b403e6b2f56b861fd3668..a140347e2498fe75163c9822a4f5f8eb80fd9506 100644
--- a/dev/tests/api-functional/testsuite/Magento/Tax/Api/TaxRateRepositoryTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Tax/Api/TaxRateRepositoryTest.php
@@ -10,7 +10,7 @@ use Magento\Framework\Api\FilterBuilder;
 use Magento\Framework\Api\SearchCriteria;
 use Magento\Framework\Api\SearchCriteriaBuilder;
 use Magento\Framework\Api\SortOrderBuilder;
-use Magento\Tax\Api\Data\TaxRateInterface as TaxRate;
+use Magento\Tax\Model\Calculation\Rate;
 use Magento\TestFramework\Helper\Bootstrap;
 use Magento\TestFramework\TestCase\WebapiAbstract;
 
@@ -433,7 +433,7 @@ class TaxRateRepositoryTest extends WebapiAbstract
         $rates = $this->setupTaxRatesForSearch();
 
         // Find rates whose code is 'codeUs12'
-        $filter = $this->filterBuilder->setField(TaxRate::KEY_CODE)
+        $filter = $this->filterBuilder->setField(Rate::KEY_CODE)
             ->setValue('codeUs12')
             ->create();
 
@@ -480,11 +480,11 @@ class TaxRateRepositoryTest extends WebapiAbstract
         $rates = $this->setupTaxRatesForSearch();
 
         // Find rates which country id 'CZ'
-        $filter = $this->filterBuilder->setField(TaxRate::KEY_COUNTRY_ID)
+        $filter = $this->filterBuilder->setField(Rate::KEY_COUNTRY_ID)
             ->setValue('CZ')
             ->create();
         $sortOrder = $this->sortOrderBuilder
-            ->setField(TaxRate::KEY_POSTCODE)
+            ->setField(Rate::KEY_POSTCODE)
             ->setDirection(SearchCriteria::SORT_DESC)
             ->create();
         // Order them by descending postcode (not the default order)
diff --git a/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/RestErrorHandlingTest.php b/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/RestErrorHandlingTest.php
index 41d6e8a2914deb9a863b42d2634d0c9aab934324..a64744df17ad68e016255d6d2396bad4e59564f6 100644
--- a/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/RestErrorHandlingTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/RestErrorHandlingTest.php
@@ -81,7 +81,7 @@ class RestErrorHandlingTest extends \Magento\TestFramework\TestCase\WebapiAbstra
     {
         $serviceInfo = [
             'rest' => [
-                'resourcePath' => '/V1/errortest/otherexception',
+                'resourcePath' => '/V1/errortest/otherException',
                 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET,
             ],
         ];
diff --git a/dev/tests/functional/lib/Magento/Mtf/Client/Element/ConditionsElement.php b/dev/tests/functional/lib/Magento/Mtf/Client/Element/ConditionsElement.php
index 8b04e6bd56c8408b7af23580dd19600adae5d53e..d805ea841654d68eed204e683be0d18bf194b5d1 100644
--- a/dev/tests/functional/lib/Magento/Mtf/Client/Element/ConditionsElement.php
+++ b/dev/tests/functional/lib/Magento/Mtf/Client/Element/ConditionsElement.php
@@ -11,8 +11,7 @@ use Magento\Mtf\Client\Locator;
 use Magento\Mtf\Client\ElementInterface;
 
 /**
- * Class ConditionsElement
- * Typified element class for conditions
+ * Typified element class for conditions.
  *
  * Format value.
  * Add slash to symbols: "{", "}", "[", "]", ":".
@@ -39,77 +38,110 @@ use Magento\Mtf\Client\ElementInterface;
 class ConditionsElement extends SimpleElement
 {
     /**
-     * Main condition
+     * Count for trying fill condition element.
+     */
+    const TRY_COUNT = 3;
+
+    /**
+     * Main condition.
      *
      * @var string
      */
     protected $mainCondition = './/ul[contains(@id,"__1__children")]/..';
 
     /**
-     * Identification for chooser grid
+     * Identification for chooser grid.
      *
      * @var string
      */
     protected $chooserLocator = '.rule-chooser-trigger';
 
     /**
-     * Button add condition
+     * Button add condition.
      *
      * @var string
      */
     protected $addNew = './/*[contains(@class,"rule-param-new-child")]/a';
 
     /**
-     * Button remove condition
+     * Button remove condition.
      *
      * @var string
      */
     protected $remove = './/*/a[@class="rule-param-remove"]';
 
     /**
-     * New condition
+     * New condition.
      *
      * @var string
      */
     protected $newCondition = './ul/li/span[contains(@class,"rule-param-new-child")]/..';
 
     /**
-     * Type of new condition
+     * Type of new condition.
      *
      * @var string
      */
     protected $typeNew = './/*[@class="element"]/select';
 
     /**
-     * Created condition
+     * Created condition.
      *
      * @var string
      */
     protected $created = './ul/li[span[contains(@class,"rule-param-new-child")]]/preceding-sibling::li[1]';
 
     /**
-     * Children condition
+     * Children condition.
      *
      * @var string
      */
     protected $children = './/ul[contains(@id,"conditions__")]';
 
     /**
-     * Parameter of condition
+     * Parameter of condition.
      *
      * @var string
      */
     protected $param = './span[span[*[substring(@id,(string-length(@id)-%d+1))="%s"]]]';
 
     /**
-     * Key of last find param
+     * Rule param wait locator.
+     *
+     * @var string
+     */
+    protected $ruleParamWait = './/*[@class="rule-param-wait"]';
+
+    /**
+     * Rule param input selector.
+     *
+     * @var string
+     */
+    protected $ruleParamInput = '[name^="rule"]';
+
+    /**
+     * Apply rule param link.
+     *
+     * @var string
+     */
+    protected $applyRuleParam = './/*[@class="rule-param-apply"]';
+
+    /**
+     * Chooser grid locator.
+     *
+     * @var string
+     */
+    protected $chooserGridLocator = 'div[id*=chooser]';
+
+    /**
+     * Key of last find param.
      *
      * @var int
      */
     protected $findKeyParam = 0;
 
     /**
-     * Map of parameters
+     * Map of parameters.
      *
      * @var array
      */
@@ -122,7 +154,7 @@ class ConditionsElement extends SimpleElement
     ];
 
     /**
-     * Map encode special chars
+     * Map encode special chars.
      *
      * @var array
      */
@@ -135,7 +167,7 @@ class ConditionsElement extends SimpleElement
     ];
 
     /**
-     * Map decode special chars
+     * Map decode special chars.
      *
      * @var array
      */
@@ -148,34 +180,22 @@ class ConditionsElement extends SimpleElement
     ];
 
     /**
-     * Rule param wait locator
-     *
-     * @var string
-     */
-    protected $ruleParamWait = './/*[@class="rule-param-wait"]';
-
-    /**
-     * Chooser grid locator
-     *
-     * @var string
-     */
-    protected $chooserGridLocator = 'div[id*=chooser]';
-
-    /**
-     * Rule param input selector.
+     * Latest occurred exception.
      *
-     * @var string
+     * @var \Exception
      */
-    protected $ruleParamInput = '.element [name^="rule"]';
+    protected $exception;
 
     /**
-     * Set value to conditions
+     * Set value to conditions.
      *
      * @param string $value
      * @return void
      */
     public function setValue($value)
     {
+        $this->eventManager->dispatchEvent(['set_value'], [__METHOD__, $this->getAbsoluteSelector()]);
+
         $conditions = $this->decodeValue($value);
         $context = $this->find($this->mainCondition, Locator::SELECTOR_XPATH);
         $this->clear();
@@ -183,7 +203,7 @@ class ConditionsElement extends SimpleElement
     }
 
     /**
-     * Add condition combination
+     * Add conditions combination.
      *
      * @param string $condition
      * @param ElementInterface $context
@@ -192,15 +212,7 @@ class ConditionsElement extends SimpleElement
     protected function addConditionsCombination($condition, ElementInterface $context)
     {
         $condition = $this->parseCondition($condition);
-
-        $this->driver->selectWindow();
-        $newCondition = $context->find($this->newCondition, Locator::SELECTOR_XPATH);
-        $newCondition->find($this->addNew, Locator::SELECTOR_XPATH)->click();
-
-        $this->driver->selectWindow();
-        $typeNewCondition = $newCondition->find($this->typeNew, Locator::SELECTOR_XPATH, 'select');
-        $typeNewCondition->setValue($condition['type']);
-
+        $this->addCondition($condition['type'], $context);
         $createdCondition = $context->find($this->created, Locator::SELECTOR_XPATH);
         $this->waitForCondition($createdCondition);
         if (!empty($condition['rules'])) {
@@ -210,7 +222,7 @@ class ConditionsElement extends SimpleElement
     }
 
     /**
-     * Add conditions
+     * Add conditions.
      *
      * @param array $conditions
      * @param ElementInterface $context
@@ -229,7 +241,7 @@ class ConditionsElement extends SimpleElement
     }
 
     /**
-     * Add single Condition
+     * Add single Condition.
      *
      * @param string $condition
      * @param ElementInterface $context
@@ -238,36 +250,55 @@ class ConditionsElement extends SimpleElement
     protected function addSingleCondition($condition, ElementInterface $context)
     {
         $condition = $this->parseCondition($condition);
+        $this->addCondition($condition['type'], $context);
+        $createdCondition = $context->find($this->created, Locator::SELECTOR_XPATH);
+        $this->waitForCondition($createdCondition);
+        $this->fillCondition($condition['rules'], $createdCondition);
+    }
 
-        $this->driver->selectWindow();
+    /**
+     * Click to add condition button and set type.
+     *
+     * @param string $type
+     * @param ElementInterface $context
+     * @return void
+     * @throws \Exception
+     */
+    protected function addCondition($type, ElementInterface $context)
+    {
         $newCondition = $context->find($this->newCondition, Locator::SELECTOR_XPATH);
-        $newCondition->find($this->addNew, Locator::SELECTOR_XPATH)->click();
-
-        $typeNew = $this->typeNew;
-        $newCondition->waitUntil(
-            function () use ($newCondition, $typeNew) {
-                $element = $newCondition->find($typeNew, Locator::SELECTOR_XPATH, 'select');
-                if ($element->isVisible()) {
-                    return true;
-                }
-                $this->driver->selectWindow();
-                return null;
+        $count = 0;
+
+        do {
+            $newCondition->find($this->addNew, Locator::SELECTOR_XPATH)->click();
+
+            try {
+                $newCondition->find($this->typeNew, Locator::SELECTOR_XPATH, 'select')->setValue($type);
+                $isSetType = true;
+            } catch (\PHPUnit_Extensions_Selenium2TestCase_WebDriverException $e) {
+                $isSetType = false;
+                $this->exception = $e;
+                $this->eventManager->dispatchEvent(['exception'], [__METHOD__, $this->getAbsoluteSelector()]);
             }
-        );
-        $newCondition->find($this->typeNew, Locator::SELECTOR_XPATH, 'select')->setValue($condition['type']);
+            $count++;
+        } while (!$isSetType && $count < self::TRY_COUNT);
 
-        $createdCondition = $context->find($this->created, Locator::SELECTOR_XPATH);
-        $this->waitForCondition($createdCondition);
-        $this->fillCondition($condition['rules'], $createdCondition);
+        if (!$isSetType) {
+            $exception = $this->exception ? $this->exception : (new \Exception("Can not add condition: {$type}"));
+            throw $exception;
+        }
     }
 
     /**
-     * Fill single condition
+     * Fill single condition.
      *
      * @param array $rules
      * @param ElementInterface $element
      * @return void
      * @throws \Exception
+     *
+     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+     * @SuppressWarnings(PHPMD.NPathComplexity)
      */
     protected function fillCondition(array $rules, ElementInterface $element)
     {
@@ -275,52 +306,117 @@ class ConditionsElement extends SimpleElement
         foreach ($rules as $rule) {
             /** @var ElementInterface $param */
             $param = $this->findNextParam($element);
+            $isSet = false;
+            $count = 0;
+
+            do {
+                try {
+                    $openParamLink = $param->find('a');
+                    if ($openParamLink->isVisible()) {
+                        $openParamLink->click();
+                    }
+                    $this->waitUntil(function () use ($param) {
+                        return $param->find($this->ruleParamInput)->isVisible() ? true : null;
+                    });
+
+                    if ($this->fillGrid($rule, $param)) {
+                        $isSet = true;
+                    } elseif ($this->fillSelect($rule, $param)) {
+                        $isSet = true;
+                    } elseif ($this->fillText($rule, $param)) {
+                        $isSet = true;
+                    }
+                } catch (\PHPUnit_Extensions_Selenium2TestCase_WebDriverException $e) {
+                    $isSet = false;
+                    $this->exception = $e;
+                    $this->eventManager->dispatchEvent(['exception'], [__METHOD__, $this->getAbsoluteSelector()]);
+                }
+                $count++;
+            } while (!$isSet && $count < self::TRY_COUNT);
 
-            $this->driver->selectWindow();
-            $param->find('a')->click();
-
-            if (preg_match('`%(.*?)%`', $rule, $chooserGrid)) {
-                $chooserConfig = explode('#', $chooserGrid[1]);
-                $param->find($this->chooserLocator)->click();
-                $rule = preg_replace('`%(.*?)%`', '', $rule);
-                $grid = ObjectManager::getInstance()->create(
-                    str_replace('/', '\\', $chooserConfig[0]),
-                    [
-                        'element' => $this->find($this->chooserGridLocator)
-                    ]
-                );
-                $grid->searchAndSelect([$chooserConfig[1] => $rule]);
-                continue;
+            if (!$isSet) {
+                $exception = $this->exception ? $this->exception : (new \Exception('Can not set value: ' . $rule));
+                throw $exception;
             }
-            $input = $this->ruleParamInput;
-            $param->waitUntil(
-                function () use ($param, $input) {
-                    $element = $param->find($input);
-                    return $element->isVisible() ? true : null;
-                }
+        }
+    }
+
+    /**
+     * Fill grid element.
+     *
+     * @param string $rule
+     * @param ElementInterface $param
+     * @return bool
+     */
+    protected function fillGrid($rule, ElementInterface $param)
+    {
+        if (preg_match('`%(.*?)%`', $rule, $chooserGrid)) {
+            $chooserConfig = explode('#', $chooserGrid[1]);
+            $rule = preg_replace('`%(.*?)%`', '', $rule);
+
+            $param->find($this->chooserLocator)->click();
+            $grid = ObjectManager::getInstance()->create(
+                str_replace('/', '\\', $chooserConfig[0]),
+                [
+                    'element' => $this->find($this->chooserGridLocator)
+                ]
             );
-            $value = $param->find('select', Locator::SELECTOR_TAG_NAME, 'select');
-            if ($value->isVisible()) {
-                $value->setValue($rule);
-                $this->click();
-                continue;
+            $grid->searchAndSelect([$chooserConfig[1] => $rule]);
+
+            $apply = $param->find($this->applyRuleParam, Locator::SELECTOR_XPATH);
+            if ($apply->isVisible()) {
+                $apply->click();
             }
-            $value = $param->find('input', Locator::SELECTOR_TAG_NAME);
-            if ($value->isVisible()) {
-                $value->setValue($rule);
 
-                $apply = $param->find('.//*[@class="rule-param-apply"]', Locator::SELECTOR_XPATH);
-                if ($apply->isVisible()) {
-                    $apply->click();
-                }
-                continue;
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Fill select element.
+     *
+     * @param string $rule
+     * @param ElementInterface $param
+     * @return bool
+     */
+    protected function fillSelect($rule, ElementInterface $param)
+    {
+        $value = $param->find('select', Locator::SELECTOR_TAG_NAME, 'select');
+        if ($value->isVisible()) {
+            $value->setValue($rule);
+            $this->click();
+
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Fill text element.
+     *
+     * @param string $rule
+     * @param ElementInterface $param
+     * @return bool
+     */
+    protected function fillText($rule, ElementInterface $param)
+    {
+        $value = $param->find('input', Locator::SELECTOR_TAG_NAME);
+        if ($value->isVisible()) {
+            $value->setValue($rule);
+
+            $apply = $param->find('.//*[@class="rule-param-apply"]', Locator::SELECTOR_XPATH);
+            if ($apply->isVisible()) {
+                $apply->click();
             }
-            throw new \Exception('Undefined type of value ');
+
+            return true;
         }
+        return false;
     }
 
     /**
-     * Decode value
+     * Decode value.
      *
      * @param string $value
      * @return array
@@ -344,7 +440,7 @@ class ConditionsElement extends SimpleElement
     }
 
     /**
-     * Parse condition
+     * Parse condition.
      *
      * @param string $condition
      * @return array
@@ -366,7 +462,7 @@ class ConditionsElement extends SimpleElement
     }
 
     /**
-     * Find next param of condition for fill
+     * Find next param of condition for fill.
      *
      * @param ElementInterface $context
      * @return ElementInterface
@@ -387,7 +483,7 @@ class ConditionsElement extends SimpleElement
     }
 
     /**
-     * Reset key of last find param
+     * Reset key of last find param.
      *
      * @return void
      */
@@ -397,25 +493,21 @@ class ConditionsElement extends SimpleElement
     }
 
     /**
-     * Param wait loader
+     * Param wait loader.
      *
-     * @return void
+     * @param ElementInterface $element
      */
     protected function waitForCondition(ElementInterface $element)
     {
         $this->waitUntil(
             function () use ($element) {
-                if ($element->getAttribute('class') == 'rule-param-wait') {
-                    $this->driver->selectWindow();
-                    return null;
-                }
-                return true;
+                return $element->getAttribute('class') == 'rule-param-wait' ? null : true;
             }
         );
     }
 
     /**
-     * Clear conditions
+     * Clear conditions.
      *
      * @return void
      */
@@ -429,7 +521,7 @@ class ConditionsElement extends SimpleElement
     }
 
     /**
-     * Get value from conditions
+     * Get value from conditions.
      *
      * @return null
      */
diff --git a/dev/tests/functional/lib/Magento/Mtf/Client/Element/LiselectstoreElement.php b/dev/tests/functional/lib/Magento/Mtf/Client/Element/LiselectstoreElement.php
index 5d3f79b515b8d7c140a7221c49b7977cbafeef82..5df3f333d46ed0297873f0c650ab387ab7f660ff 100644
--- a/dev/tests/functional/lib/Magento/Mtf/Client/Element/LiselectstoreElement.php
+++ b/dev/tests/functional/lib/Magento/Mtf/Client/Element/LiselectstoreElement.php
@@ -65,7 +65,7 @@ class LiselectstoreElement extends SimpleElement
     public function setValue($value)
     {
         $this->eventManager->dispatchEvent(['set_value'], [__METHOD__, $this->getAbsoluteSelector()]);
-        $this->driver->find($this->toggleSelector)->click();
+        $this->context->find($this->toggleSelector)->click();
 
         $value = explode('/', $value);
         $optionSelector = [];
@@ -88,7 +88,7 @@ class LiselectstoreElement extends SimpleElement
      */
     protected function getLiElements()
     {
-        $this->driver->find($this->toggleSelector)->click();
+        $this->find($this->toggleSelector)->click();
         $elements = $this->driver->getElements($this, 'li', Locator::SELECTOR_TAG_NAME);
         $dropdownData = [];
         foreach ($elements as $element) {
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Page/Header.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Page/Header.php
index 6685ac3f6f7877ecd19204061077d4ce1e2ce2c3..cbe0c75b7d923176473dc55456345d4fee719b1f 100644
--- a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Page/Header.php
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Page/Header.php
@@ -20,7 +20,7 @@ class Header extends Block
      *
      * @var string
      */
-    protected $adminAccountLink = '.admin-user-account';
+    protected $adminAccountLink = '.admin-user-account-text';
 
     /**
      * Selector for Log Out Link.
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Config/PageActions.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Config/PageActions.php
index 8ed2b6a7bfb7acdadf0b2fd106939052fb7de5d2..2dbbdd6fe04c8e4a7b57f1fc71316dd4e1c85023 100644
--- a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Config/PageActions.php
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Config/PageActions.php
@@ -23,7 +23,7 @@ class PageActions extends AbstractPageActions
      *
      * @var string
      */
-    protected $scopeSelector = '.actions.dropdown';
+    protected $scopeSelector = '.store-switcher .actions.dropdown';
 
     /**
      * Select store
@@ -41,7 +41,7 @@ class PageActions extends AbstractPageActions
     }
 
     /**
-     * Check if store visible in scope dropdown
+     * Check if store is visible in scope dropdown
      *
      * @param Store $store
      * @return bool
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Widget/Grid.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Widget/Grid.php
index 59a11f436051b6e190f286e7c9f1feb12fa2e50b..40d04bc0fd76f92725a84952a1c143dc8fee50b9 100644
--- a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Widget/Grid.php
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Widget/Grid.php
@@ -32,7 +32,7 @@ abstract class Grid extends Block
      *
      * @var string
      */
-    protected $searchButton = '[title=Search][class*=action]';
+    protected $searchButton = '[data-action="grid-filter-apply"]';
 
     /**
      * Locator for 'Sort' link
@@ -46,7 +46,7 @@ abstract class Grid extends Block
      *
      * @var string
      */
-    protected $resetButton = '.action-reset';
+    protected $resetButton = '[data-action="grid-filter-reset"]';
 
     /**
      * The first row in grid. For this moment we suggest that we should strictly define what we are going to search
@@ -137,21 +137,14 @@ abstract class Grid extends Block
      *
      * @var string
      */
-    protected $filterButton = '.action.filters-toggle';
+    protected $filterButton = '[data-action="grid-filter-expand"]';
 
     /**
      * Active class
      *
      * @var string
      */
-    protected $active = '.active';
-
-    /**
-     * Base part of row locator template for getRow() method
-     *
-     * @var string
-     */
-    protected $location = '//div[@class="grid"]//tr[';
+    protected $active = '[class=*_active]';
 
     /**
      * Secondary part of row locator template for getRow() method
@@ -381,16 +374,12 @@ abstract class Grid extends Block
         if ($isSearchable) {
             $this->search($filter);
         }
-        $location = '//div[@class="grid"]//tr[';
-        $rowTemplate = 'td[contains(.,normalize-space("%s"))]';
-        if ($isStrict) {
-            $rowTemplate = 'td[text()[normalize-space()="%s"]]';
-        }
+        $rowTemplate = ($isStrict) ? $this->rowTemplateStrict : $this->rowTemplate;
         $rows = [];
         foreach ($filter as $value) {
             $rows[] = sprintf($rowTemplate, $value);
         }
-        $location = $location . implode(' and ', $rows) . ']';
+        $location = '//tr[' . implode(' and ', $rows) . ']';
         return $this->_rootElement->find($location, Locator::SELECTOR_XPATH);
     }
 
@@ -428,7 +417,6 @@ abstract class Grid extends Block
      */
     public function isRowVisible(array $filter, $isSearchable = true, $isStrict = true)
     {
-        $this->openFilterBlock();
         return $this->getRow($filter, $isSearchable, $isStrict)->isVisible();
     }
 
@@ -457,14 +445,14 @@ abstract class Grid extends Block
     {
         $this->getTemplateBlock()->waitForElementNotVisible($this->loader);
 
-        $button = $this->_rootElement->find($this->filterButton);
-        if ($button->isVisible() && !$this->_rootElement->find($this->filterButton . $this->active)->isVisible()) {
-            $button->click();
+        $toggleFilterButton = $this->_rootElement->find($this->filterButton);
+        $searchButton = $this->_rootElement->find($this->searchButton);
+        if ($toggleFilterButton->isVisible() && !$searchButton->isVisible()) {
+            $toggleFilterButton->click();
             $browser = $this->_rootElement;
-            $selector = $this->searchButton;
             $browser->waitUntil(
-                function () use ($browser, $selector) {
-                    return $browser->find($selector)->isVisible() ? true : null;
+                function () use ($searchButton) {
+                    return $searchButton->isVisible() ? true : null;
                 }
             );
         }
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php
index 19ee690cba1cf208e20885459ea8fd11e32ffbf6..b262b81e09c0ebfdcef2d6ff555e9d756713aa8e 100644
--- a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php
@@ -38,7 +38,7 @@ class AdminAuthLogin extends Page
      *
      * @var string
      */
-    protected $messagesBlock = '.messages .message';
+    protected $messagesBlock = '.messages';
 
     /**
      * Constructor.
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ListProduct.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ListProduct.php
index 535cc6ef859eaa1d2a01df74a95d2625b8025b21..c4a1925081da60591b258109dcc11ed13326b030 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ListProduct.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ListProduct.php
@@ -23,6 +23,13 @@ class ListProduct extends Block
      */
     protected $productItem = './/*[contains(@class,"product-item-link") and normalize-space(text())="%s"]/ancestor::li';
 
+    /**
+     * Locator for product item link.
+     *
+     * @var string
+     */
+    protected $productItemLink = '.product-item-link';
+
     /**
      * Sorter dropdown selector.
      *
@@ -46,6 +53,23 @@ class ListProduct extends Block
         );
     }
 
+    /**
+     * Get product names list.
+     *
+     * @return array
+     */
+    public function getProductNames()
+    {
+        $itemLinks = $this->_rootElement->getElements($this->productItemLink);
+        $productNames = [];
+
+        foreach ($itemLinks as $itemLink) {
+            $productNames[] = trim($itemLink->getText());
+        }
+
+        return $productNames;
+    }
+
     /**
      * Get all terms used in sort.
      *
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/Category/Curl.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/Category/Curl.php
index e684946a46f47f152fdd1d4373f31a31b1142dd4..bd7a938684dd27bf7d38724ecc1f6cd046788381 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/Category/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/Category/Curl.php
@@ -6,6 +6,7 @@
 
 namespace Magento\Catalog\Test\Handler\Category;
 
+use Magento\Catalog\Test\Fixture\Category;
 use Magento\Mtf\Fixture\FixtureInterface;
 use Magento\Mtf\Handler\Curl as AbstractCurl;
 use Magento\Mtf\Util\Protocol\CurlInterface;
@@ -58,20 +59,24 @@ class Curl extends AbstractCurl implements CategoryInterface
      *
      * @param FixtureInterface|null $fixture [optional]
      * @return array
+     * @throws \Exception
      */
     public function persist(FixtureInterface $fixture = null)
     {
         $data = $this->prepareData($fixture);
-
         $url = $_ENV['app_backend_url'] . 'catalog/category/save/store/0/parent/' . $data['general']['parent_id'] . '/';
         $curl = new BackendDecorator(new CurlTransport(), $this->_configuration);
         $curl->write(CurlInterface::POST, $url, '1.0', [], $data);
         $response = $curl->read();
         $curl->close();
 
+        if (!strpos($response, 'data-ui-id="messages-message-success"')) {
+            $this->_eventManager->dispatchEvent(['curl_failed'], [$response]);
+            throw new \Exception('Category creation by curl handler was not successful!');
+        }
+
         preg_match('#http://.+/id/(\d+).+store/#m', $response, $matches);
         $id = isset($matches[1]) ? (int)$matches[1] : null;
-
         return ['id' => $id];
     }
 
@@ -83,12 +88,16 @@ class Curl extends AbstractCurl implements CategoryInterface
      */
     protected function prepareData(FixtureInterface $fixture)
     {
-        $data['general'] = $this->replaceMappingData($fixture->getData());
-        $data['is_anchor'] = isset($data['is_anchor']) ? $data['is_anchor'] : 0;
+        $data = ['general' => $this->replaceMappingData($fixture->getData())];
+        $data['general']['is_anchor'] = isset($data['general']['is_anchor']) ? $data['general']['is_anchor'] : 0;
+
         if ($fixture->hasData('landing_page')) {
             $data['general']['landing_page'] = $this->getBlockId($fixture->getLandingPage());
         }
 
+        $data['category_products'] = $this->prepareCategoryProducts($fixture);
+        unset($data['general']['category_products']);
+
         $diff = array_diff($this->dataUseConfig, array_keys($data['general']));
         if (!empty($diff)) {
             $data['use_config'] = $diff;
@@ -97,6 +106,28 @@ class Curl extends AbstractCurl implements CategoryInterface
         return $data;
     }
 
+    /**
+     * Prepare category products data for curl.
+     *
+     * @param FixtureInterface $category
+     * @return array
+     */
+    protected function prepareCategoryProducts(FixtureInterface $category)
+    {
+        $categoryProducts = [];
+        $defaultPosition = 0;
+
+        /** @var Category $category */
+        if ($category->hasData('category_products')) {
+            $products = $category->getDataFieldConfig('category_products')['source']->getProducts();
+            foreach ($products as $product) {
+                $categoryProducts[$product->getId()] = $defaultPosition;
+            }
+        }
+
+        return json_encode($categoryProducts);
+    }
+
     /**
      * Getting block id by name.
      *
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Category/CatalogCategoryView.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Category/CatalogCategoryView.xml
index 392a1ff131e7fbee4246d32285458c1c4d086030..45839712e35c673123d36d46d33b1aaa8b869979 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Category/CatalogCategoryView.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Category/CatalogCategoryView.xml
@@ -8,7 +8,6 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/pages.xsd">
     <page name="CatalogCategoryView" area="Category" mca="catalog/category/view" module="Magento_Catalog">
         <block name="titleBlock" class="Magento\Theme\Test\Block\Html\Title" locator=".page-title-wrapper h1.page-title .base" strategy="css selector"/>
-        <block name="layeredNavigationBlock" class="Magento\LayeredNavigation\Test\Block\Navigation" locator=".block.filter" strategy="css selector"/>
         <block name="widgetView" class="Magento\Widget\Test\Block\WidgetView" locator=".widget" strategy="css selector"/>
         <block name="viewBlock" class="Magento\Catalog\Test\Block\Category\View" locator="#maincontent" strategy="css selector"/>
         <block name="listProductBlock" class="Magento\Catalog\Test\Block\Product\ListProduct" locator=".products.wrapper.grid" strategy="css selector"/>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.xml
index 4998c9d9604744c84511a07a10c321a6cc29bd02..c4ae2d72fde4dc62c6c352172b7510b3a237138e 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.xml
@@ -65,6 +65,31 @@
             </field>
         </dataset>
 
+        <dataset name="product_20_dollar">
+            <field name="attribute_set_id" xsi:type="array">
+                <item name="dataSet" xsi:type="string">default</item>
+            </field>
+            <field name="name" xsi:type="string">product_20_dollar %isolation%</field>
+            <field name="sku" xsi:type="string">sku_product_20_dollar_%isolation%</field>
+            <field name="is_virtual" xsi:type="string">No</field>
+            <field name="weight" xsi:type="string">1</field>
+            <field name="quantity_and_stock_status" xsi:type="array">
+                <item name="qty" xsi:type="string">1000</item>
+                <item name="is_in_stock" xsi:type="string">In Stock</item>
+            </field>
+            <field name="price" xsi:type="array">
+                <item name="value" xsi:type="string">20</item>
+            </field>
+            <field name="tax_class_id" xsi:type="array">
+                <item name="dataSet" xsi:type="string">taxable_goods</item>
+            </field>
+            <field name="website_ids" xsi:type="array">
+                <item name="0" xsi:type="string">Main Website</item>
+            </field>
+            <field name="visibility" xsi:type="string">Catalog, Search</field>
+            <field name="url_key" xsi:type="string">product-20-dollar-%isolation%</field>
+        </dataset>
+
         <dataset name="product_with_url_key">
             <field name="name" xsi:type="string">Simple Product %isolation%</field>
             <field name="sku" xsi:type="string">sku_simple_product_%isolation%</field>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest.xml
index b4b2da10a3d7350c0a210b8c9d4bdf3b67c8ec64..83d80113af0ae3d885bd6e2f706b904a39164dfd 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest.xml
@@ -69,7 +69,6 @@
             <data name="category/data/available_product_listing_config" xsi:type="string">Yes</data>
             <data name="category/data/default_product_listing_config" xsi:type="string">Yes</data>
             <data name="category/data/use_config_price_range" xsi:type="string">Yes</data>
-            <data name="category/data/category_products_data/preset" xsi:type="string">default</data>
             <data name="category/data/category_products/dataSet" xsi:type="string">catalogProductSimple::default,catalogProductSimple::default</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertCategorySaveMessage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertCategoryForm" />
@@ -97,7 +96,6 @@
             <data name="category/data/default_sort_by" xsi:type="string">Price</data>
             <data name="category/data/use_config_price_range" xsi:type="string">No</data>
             <data name="category/data/layered_navigation_price_step" xsi:type="string">50</data>
-            <data name="category/data/category_products_data/preset" xsi:type="string">default</data>
             <data name="category/data/category_products/dataSet" xsi:type="string">catalogProductSimple::default,catalogProductSimple::default</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertCategorySaveMessage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertCategoryForm" />
diff --git a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/AbstractCatalogRuleEntityTest.php b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/AbstractCatalogRuleEntityTest.php
index 8c2ab9474a2c002767159584ba680781934ade83..8cc2bbcd11900b03ac123fee638555e84de93a19 100644
--- a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/AbstractCatalogRuleEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/AbstractCatalogRuleEntityTest.php
@@ -38,13 +38,6 @@ abstract class AbstractCatalogRuleEntityTest extends Injectable
      */
     protected $adminCache;
 
-    /**
-     * Fixture CatalogRule.
-     *
-     * @var array
-     */
-    protected $catalogRules = [];
-
     /**
      * Fixture factory.
      *
@@ -80,12 +73,6 @@ abstract class AbstractCatalogRuleEntityTest extends Injectable
      */
     public function tearDown()
     {
-        foreach ($this->catalogRules as $catalogRule) {
-            $filter = ['name' => $catalogRule->getName()];
-            $this->catalogRuleIndex->open();
-            $this->catalogRuleIndex->getCatalogRuleGrid()->searchAndOpen($filter);
-            $this->catalogRuleNew->getFormPageActions()->delete();
-        }
-        $this->catalogRules = [];
+        $this->objectManager->create('\Magento\CatalogRule\Test\TestStep\DeleteAllCatalogRulesStep')->run();
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/ApplySeveralCatalogPriceRuleEntityTest.php b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/ApplySeveralCatalogPriceRuleEntityTest.php
index 84f9cd923b6ef87fa44b77d82c0874529f0362fa..1ef4e30a3e542de934a5f0b55e214460b385c8a5 100644
--- a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/ApplySeveralCatalogPriceRuleEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/ApplySeveralCatalogPriceRuleEntityTest.php
@@ -9,17 +9,15 @@ namespace Magento\CatalogRule\Test\TestCase;
 use Magento\Catalog\Test\Fixture\CatalogProductSimple;
 
 /**
- * Test Creation for Apply several CatalogPriceRuleEntity
- *
- * Test Flow:
  * Preconditions:
- *  1. Execute before each variation:
- *   - Delete all active catalog price rules
- *   - Create catalog price rule from dataSet using Curl
+ * 1. Execute before each variation:
+ *  - Delete all active catalog price rules
+ *  - Create catalog price rule from dataSet using Curl
+ *
  * Steps:
- *  1. Apply all created rules
- *  2. Create simple product
- *  3. Perform all assertions
+ * 1. Apply all created rules.
+ * 2. Create simple product.
+ * 3. Perform all assertions.
  *
  * @group Catalog_Price_Rules_(MX)
  * @ZephyrId MAGETWO-24780
@@ -32,7 +30,7 @@ class ApplySeveralCatalogPriceRuleEntityTest extends AbstractCatalogRuleEntityTe
     /* end tags */
 
     /**
-     * Apply several catalog price rules
+     * Apply several catalog price rules.
      *
      * @param array $catalogRulesOriginal
      * @return array
@@ -44,15 +42,15 @@ class ApplySeveralCatalogPriceRuleEntityTest extends AbstractCatalogRuleEntityTe
             if ($catalogPriceRule == '-') {
                 continue;
             }
-            $this->catalogRules[$key] = $this->fixtureFactory->createByCode(
+            $catalogRules[$key] = $this->fixtureFactory->createByCode(
                 'catalogRule',
                 ['dataSet' => $catalogPriceRule]
             );
-            $this->catalogRules[$key]->persist();
+            $catalogRules[$key]->persist();
 
             $filter = [
-                'name' => $this->catalogRules[$key]->getName(),
-                'rule_id' => $this->catalogRules[$key]->getId(),
+                'name' => $catalogRules[$key]->getName(),
+                'rule_id' => $catalogRules[$key]->getId(),
             ];
             $this->catalogRuleIndex->getCatalogRuleGrid()->searchAndOpen($filter);
             $this->catalogRuleNew->getFormPageActions()->saveAndApply();
diff --git a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/CreateCatalogPriceRuleEntityTest.php b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/CreateCatalogPriceRuleEntityTest.php
index 20ddb3397e1a54e507e8dd9893b587a79caea588..be62cb21448e54bfb45f6d86c18f3019b485a66a 100644
--- a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/CreateCatalogPriceRuleEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/CreateCatalogPriceRuleEntityTest.php
@@ -9,15 +9,13 @@ namespace Magento\CatalogRule\Test\TestCase;
 use Magento\CatalogRule\Test\Fixture\CatalogRule;
 
 /**
- * Test Creation for Create CatalogPriceRuleEntity
- *
- * Test Flow:
+ * Steps:
  * 1. Log in as default admin user.
- * 2. Go to Marketing > Catalog Price Rules
- * 3. Press "+" button to start create new catalog price rule
- * 4. Fill in all data according to data set
- * 5. Save rule
- * 6. Perform appropriate assertions
+ * 2. Go to Marketing > Catalog Price Rules.
+ * 3. Press "+" button to start create new catalog price rule.
+ * 4. Fill in all data according to data set.
+ * 5. Save rule.
+ * 6. Perform appropriate assertions.
  *
  * @group Catalog_Price_Rules_(MX)
  * @ZephyrId MAGETWO-24341
@@ -42,8 +40,5 @@ class CreateCatalogPriceRuleEntityTest extends AbstractCatalogRuleEntityTest
         $this->catalogRuleIndex->getGridPageActions()->addNew();
         $this->catalogRuleNew->getEditForm()->fill($catalogPriceRule);
         $this->catalogRuleNew->getFormPageActions()->save();
-
-        // Prepare data for tear down
-        $this->catalogRules[] = $catalogPriceRule;
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/CreateCatalogRuleTest.php b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/CreateCatalogRuleTest.php
index 6649d45ba0e6312653b5c6766ab1727f20786aed..18815f160fa7f9f1b2ea52a6b64a8b28ad32c568 100644
--- a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/CreateCatalogRuleTest.php
+++ b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/CreateCatalogRuleTest.php
@@ -12,18 +12,16 @@ use Magento\Catalog\Test\Fixture\CatalogProductSimple;
 use Magento\Customer\Test\Fixture\CustomerGroupInjectable;
 
 /**
- * Test Coverage for Create Catalog Rule
- *
- * Test Flow:
+ * Steps:
  * 1. Log in as default admin user.
- * 2. Go to Marketing > Catalog Price Rules
- * 3. Press "+" button to start create new catalog price rule
- * 4. Fill in all data according to data set
- * 5. Save rule
- * 6. Apply newly created catalog rule
- * 7. Create simple product
- * 8. Clear cache
- * 9. Perform all assertions
+ * 2. Go to Marketing > Catalog Price Rules.
+ * 3. Press "+" button to start create new catalog price rule.
+ * 4. Fill in all data according to data set.
+ * 5. Save rule.
+ * 6. Apply newly created catalog rule.
+ * 7. Create simple product.
+ * 8. Clear cache.
+ * 9. Perform all assertions.
  *
  * @ticketId MAGETWO-23036
  */
@@ -37,7 +35,7 @@ class CreateCatalogRuleTest extends AbstractCatalogRuleEntityTest
     /* end tags */
 
     /**
-     * Create Catalog Price Rule
+     * Create Catalog Price Rule.
      *
      * @param CatalogRule $catalogPriceRule
      * @param Customer $customer
@@ -70,9 +68,6 @@ class CreateCatalogRuleTest extends AbstractCatalogRuleEntityTest
         $this->catalogRuleNew->getEditForm()->fill($catalogPriceRule, null, $replace);
         $this->catalogRuleNew->getFormPageActions()->save();
 
-        // Prepare data for tear down
-        $this->catalogRules[] = $catalogPriceRule;
-
         // Apply Catalog Price Rule
         $this->catalogRuleIndex->getGridPageActions()->applyRules();
 
diff --git a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/UpdateCatalogPriceRuleEntityTest.php b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/UpdateCatalogPriceRuleEntityTest.php
index 29339f794b99555a85bd92961ac02a638902d344..fd30614dd24abfbdd239882132548305f5199cd0 100755
--- a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/UpdateCatalogPriceRuleEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/UpdateCatalogPriceRuleEntityTest.php
@@ -11,19 +11,17 @@ use Magento\Catalog\Test\Fixture\CatalogProductSimple\CategoryIds;
 use Magento\CatalogRule\Test\Fixture\CatalogRule;
 
 /**
- * Test Creation for UpdateCatalogPriceRuleEntity
- *
- * Test Flow:
  * Preconditions:
- * 1. Catalog Price Rule is created
+ * 1. Catalog Price Rule is created.
+ *
  * Steps:
- * 1. Login to backend
- * 2. Navigate to MARKETING > Catalog Price Rules
- * 3. Click Catalog Price Rule from grid
- * 4. Edit test value(s) according to dataSet
- * 5. Click 'Save'/ 'Apply' button
- * 6. Create simple product with category
- * 7. Perform all asserts
+ * 1. Login to backend.
+ * 2. Navigate to MARKETING > Catalog Price Rules.
+ * 3. Click Catalog Price Rule from grid.
+ * 4. Edit test value(s) according to dataSet.
+ * 5. Click 'Save'/ 'Apply' button.
+ * 6. Create simple product with category.
+ * 7. Perform all asserts.
  *
  * @group Catalog_Price_Rules_(MX)
  * @ZephyrId MAGETWO-25187
@@ -37,7 +35,7 @@ class UpdateCatalogPriceRuleEntityTest extends AbstractCatalogRuleEntityTest
     /* end tags */
 
     /**
-     * Update catalog price rule
+     * Update catalog price rule.
      *
      * @param CatalogRule $catalogPriceRule
      * @param CatalogRule $catalogPriceRuleOriginal
@@ -81,9 +79,6 @@ class UpdateCatalogPriceRuleEntityTest extends AbstractCatalogRuleEntityTest
         $this->catalogRuleNew->getEditForm()->fill($catalogPriceRule, null, $replace);
         $this->catalogRuleNew->getFormPageActions()->$saveAction();
 
-        // Prepare data for tear down
-        $this->catalogRules[] = $catalogPriceRule;
-
         // Create simple product with category
         $productSimple->persist();
 
diff --git a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestStep/DeleteAllCatalogRulesStep.php b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestStep/DeleteAllCatalogRulesStep.php
index a30825ebf60af09f0a09ddd652c6d9c7af830cb5..dcc06c224c0baafb2d9429ba256b7d922cbb6136 100644
--- a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestStep/DeleteAllCatalogRulesStep.php
+++ b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestStep/DeleteAllCatalogRulesStep.php
@@ -51,6 +51,7 @@ class DeleteAllCatalogRulesStep implements TestStepInterface
     public function run()
     {
         $this->catalogRuleIndex->open();
+        $this->catalogRuleIndex->getCatalogRuleGrid()->resetFilter();
         while ($this->catalogRuleIndex->getCatalogRuleGrid()->isFirstRowVisible()) {
             $this->catalogRuleIndex->getCatalogRuleGrid()->openFirstRow();
             $this->catalogRuleNew->getFormPageActions()->delete();
diff --git a/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/TestStep/DeleteAllTermsEntityStep.php b/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/TestStep/DeleteAllTermsEntityStep.php
index f57baf78acc59aed8fce6d8dfae84cc00ce924ed..3599882b174c192c6f0638b491a86937e7e39c8c 100644
--- a/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/TestStep/DeleteAllTermsEntityStep.php
+++ b/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/TestStep/DeleteAllTermsEntityStep.php
@@ -52,6 +52,7 @@ class DeleteAllTermsEntityStep implements TestStepInterface
     public function run()
     {
         $this->agreementIndex->open();
+        $this->agreementIndex->getAgreementGridBlock()->resetFilter();
         while ($this->agreementIndex->getAgreementGridBlock()->isFirstRowVisible()) {
             $this->agreementIndex->getAgreementGridBlock()->openFirstRow();
             $this->agreementNew->getPageActionsBlock()->delete();
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/Block/Adminhtml/Block/CmsGrid.php b/dev/tests/functional/tests/app/Magento/Cms/Test/Block/Adminhtml/Block/CmsGrid.php
index df52dfb3a70cb31a819d4cb0aa9f95248b82536e..99fe29e6517c8fe34fb3a6bc2e4113d5ff161955 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/Block/Adminhtml/Block/CmsGrid.php
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/Block/Adminhtml/Block/CmsGrid.php
@@ -20,25 +20,23 @@ class CmsGrid extends Grid
      */
     protected $filters = [
         'title' => [
-            'selector' => '#title',
+            'selector' => '[name="params[filters][title]"]',
         ],
         'identifier' => [
-            'selector' => '#identifier',
+            'selector' => '[name="params[filters][identifier]"]',
         ],
         'is_active' => [
-            'selector' => '#is_active',
+            'selector' => '[name="params[filters][is_active]"]',
             'input' => 'select',
         ],
         'creation_time_from' => [
-            'selector' => '(//span[.="Created"]/following::input[contains(@placeholder,"From")])[1]',
-            'strategy' => 'xpath',
+            'selector' => '[name="params[filters][creation_time][from]"]',
         ],
         'update_time_from' => [
-            'selector' => '(//span[.="Created"]/following::input[contains(@placeholder,"From")])[2]',
-            'strategy' => 'xpath',
+            'selector' => '[name="params[filters][update_time][from]"]',
         ],
         'store_id' => [
-            'selector' => 'label[for="store_id"] + div > select',
+            'selector' => '[name="params[filters][store_id]"]',
             'input' => 'selectstore'
         ],
     ];
@@ -48,19 +46,19 @@ class CmsGrid extends Grid
      *
      * @var string
      */
-    protected $searchButton = '.action-apply';
+    protected $searchButton = '[data-action="grid-filter-apply"]';
 
     /**
      * Locator value for 'Reset' button.
      *
      * @var string
      */
-    protected $resetButton = '.action-reset';
+    protected $resetButton = '[data-action="grid-filter-reset"]';
 
     /**
      * Locator value for link in action column.
      *
      * @var string
      */
-    protected $editLink = 'td[data-part="body.row.cell"]';
+    protected $editLink = '.action-menu-item';
 }
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/Block/Adminhtml/Page/Grid.php b/dev/tests/functional/tests/app/Magento/Cms/Test/Block/Adminhtml/Page/Grid.php
index b58dfde4c16cb99902cfcb46a600a58cb00436b3..b111912748e06fee7328c8dc50c3e8baea2a0f36 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/Block/Adminhtml/Page/Grid.php
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/Block/Adminhtml/Page/Grid.php
@@ -19,21 +19,21 @@ class Grid extends ParentGrid
      *
      * @var string
      */
-    protected $searchButton = '.action.primary.action-apply';
+    protected $searchButton = '[data-action="grid-filter-apply"]';
 
     /**
      * Locator value for 'Reset' button.
      *
      * @var string
      */
-    protected $resetButton = '.action.secondary.action-reset';
+    protected $resetButton = '[data-action="grid-filter-reset"]';
 
     /**
      * Locator value for link in action column.
      *
      * @var string
      */
-    protected $editLink = 'td[data-part="body.row.cell"]';
+    protected $editLink = '[data-action="grid-row-edit"]';
 
     /**
      * 'Preview' cms page link.
@@ -49,7 +49,7 @@ class Grid extends ParentGrid
      */
     protected $filters = [
         'title' => [
-            'selector' => '#title',
+            'selector' => '[name="params[filters][title]"]',
         ],
     ];
 
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/Page/Adminhtml/CmsBlockIndex.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/Page/Adminhtml/CmsBlockIndex.xml
index b62397be96d8a79f01c43bb426b4d8c9a521e79b..7f0434e5c657330fc233047676a40e399944d953 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/Page/Adminhtml/CmsBlockIndex.xml
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/Page/Adminhtml/CmsBlockIndex.xml
@@ -6,9 +6,9 @@
  */
  -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/pages.xsd">
-    <page name="CmsBlockIndex" area="Adminhtml" mca="cms/block" module="Magento_Cms">
-        <block name="messagesBlock" class="Magento\Backend\Test\Block\Messages" locator="#messages" strategy="css selector" />
+    <page name="CmsBlockIndex" area="Adminhtml" mca="cms/block/index" module="Magento_Cms">
+        <block name="messagesBlock" class="Magento\Backend\Test\Block\Messages" locator=".messages .message" strategy="css selector" />
         <block name="gridPageActions" class="Magento\Backend\Test\Block\GridPageActions" locator=".page-main-actions" strategy="css selector" />
-        <block name="cmsBlockGrid" class="Magento\Cms\Test\Block\Adminhtml\Block\CmsGrid" locator=".grid" strategy="css selector" />
+        <block name="cmsBlockGrid" class="Magento\Cms\Test\Block\Adminhtml\Block\CmsGrid" locator=".admin__data-grid-wrap" strategy="css selector" />
     </page>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/Page/Adminhtml/CmsPageIndex.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/Page/Adminhtml/CmsPageIndex.xml
index 6c567cc3013ddba21ed268b8e4f537502a69fa06..44247cb0b215791070dcc32cf16d3d632a3c00b2 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/Page/Adminhtml/CmsPageIndex.xml
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/Page/Adminhtml/CmsPageIndex.xml
@@ -8,7 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/pages.xsd">
     <page name="CmsPageIndex" area="Adminhtml" mca="cms/page/index" module="Magento_Cms">
         <block name="pageActionsBlock" class="Magento\Backend\Test\Block\GridPageActions" locator=".page-main-actions" strategy="css selector" />
-        <block name="cmsPageGridBlock" class="Magento\Cms\Test\Block\Adminhtml\Page\Grid" locator=".grid" strategy="css selector" />
+        <block name="cmsPageGridBlock" class="Magento\Cms\Test\Block\Adminhtml\Page\Grid" locator=".admin__data-grid-wrap" strategy="css selector" />
         <block name="messagesBlock" class="Magento\Backend\Test\Block\Messages" locator=".messages .message" strategy="css selector" />
     </page>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Block/Adminhtml/System/Currency/MainPageActions.php b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Block/Adminhtml/System/Currency/MainPageActions.php
deleted file mode 100644
index 14f7bf7af1bbeb49f34f4d68fe6e2bfa046039cd..0000000000000000000000000000000000000000
--- a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Block/Adminhtml/System/Currency/MainPageActions.php
+++ /dev/null
@@ -1,33 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-namespace Magento\CurrencySymbol\Test\Block\Adminhtml\System\Currency;
-
-use Magento\Backend\Test\Block\PageActions;
-
-/**
- * Class MainPageActions
- * Main page actions on the SystemCurrencyIndex page
- */
-class MainPageActions extends PageActions
-{
-    /**
-     * "Save Currency Rates" button locator
-     *
-     * @var string
-     */
-    protected $saveCurrentRate = '[data-ui-id="page-actions-toolbar-save-button"]';
-
-    /**
-     * Save Currency Rates
-     *
-     * @return void
-     */
-    public function saveCurrentRate()
-    {
-        $this->_rootElement->find($this->saveCurrentRate)->click();
-    }
-}
diff --git a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Block/Adminhtml/System/Currency/Rate/CurrencyRateForm.php b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Block/Adminhtml/System/Currency/Rate/CurrencyRateForm.php
new file mode 100644
index 0000000000000000000000000000000000000000..d5d1c887a484c6d4c46a641cacb4213f5d4e4a58
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Block/Adminhtml/System/Currency/Rate/CurrencyRateForm.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CurrencySymbol\Test\Block\Adminhtml\System\Currency\Rate;
+
+use Magento\Mtf\Block\Form;
+use Magento\Mtf\Fixture\FixtureInterface;
+use Magento\Mtf\Client\Element\SimpleElement;
+
+/**
+ * Currency Rate form.
+ */
+class CurrencyRateForm extends Form
+{
+    /**
+     * Fill currency rate form.
+     *
+     * @param FixtureInterface $fixture
+     * @param SimpleElement|null $element
+     * @return $this
+     */
+    public function fill(FixtureInterface $fixture, SimpleElement $element = null)
+    {
+        /** @var \Magento\Directory\Test\Fixture\CurrencyRate $fixture */
+        $this->placeholders['currency_from'] = $fixture->getCurrencyFrom();
+        $this->placeholders['currency_to'] = $fixture->getCurrencyTo();
+        $this->applyPlaceholders();
+
+        return parent::fill($fixture, $element);
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Block/Adminhtml/System/Currency/Rate/CurrencyRateForm.xml b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Block/Adminhtml/System/Currency/Rate/CurrencyRateForm.xml
new file mode 100644
index 0000000000000000000000000000000000000000..4ffc8f05740d4454c14ded3bdc171699a7d93c1c
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Block/Adminhtml/System/Currency/Rate/CurrencyRateForm.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<mapping strict="0">
+    <wrapper>rate</wrapper>
+    <fields>
+        <rate>
+            <selector>input[name="rate[%currency_from%][%currency_to%]"]</selector>
+        </rate>
+    </fields>
+</mapping>
diff --git a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Block/Adminhtml/System/Currency/Rate/FormPageActions.php b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Block/Adminhtml/System/Currency/Rate/FormPageActions.php
new file mode 100644
index 0000000000000000000000000000000000000000..3c911026ad68cfce9ae4fd9f86caa607863ebe96
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Block/Adminhtml/System/Currency/Rate/FormPageActions.php
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CurrencySymbol\Test\Block\Adminhtml\System\Currency\Rate;
+
+use Magento\Backend\Test\Block\FormPageActions as ParentFormPageActions;
+
+/**
+ * Form page actions on the SystemCurrencyIndex page.
+ */
+class FormPageActions extends ParentFormPageActions
+{
+    /**
+     * "Save Currency Rates" button locator.
+     *
+     * @var string
+     */
+    protected $saveButton = '.save';
+}
diff --git a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Block/Adminhtml/System/Currency/GridPageActions.php b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Block/Adminhtml/System/Currency/Rate/GridPageActions.php
similarity index 68%
rename from dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Block/Adminhtml/System/Currency/GridPageActions.php
rename to dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Block/Adminhtml/System/Currency/Rate/GridPageActions.php
index f50f9a58386a4aa4ccada29a5115324aad6e4e57..ee7d3fcc6411632c646c08eaec8ab6ee8aa0d904 100644
--- a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Block/Adminhtml/System/Currency/GridPageActions.php
+++ b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Block/Adminhtml/System/Currency/Rate/GridPageActions.php
@@ -4,10 +4,9 @@
  * See COPYING.txt for license details.
  */
 
-namespace Magento\CurrencySymbol\Test\Block\Adminhtml\System\Currency;
+namespace Magento\CurrencySymbol\Test\Block\Adminhtml\System\Currency\Rate;
 
 use Magento\Backend\Test\Block\PageActions;
-use Magento\Backend\Test\Block\Messages;
 
 /**
  * Grid page actions on the SystemCurrencyIndex page.
@@ -47,21 +46,5 @@ class GridPageActions extends PageActions
                 return $message->isVisible() ? true : null;
             }
         );
-        if ($this->getMessageBlock()->isVisibleMessage('warning')) {
-            throw new \Exception($this->getMessageBlock()->getWarningMessages());
-        }
-    }
-
-    /**
-     * Get message block.
-     *
-     * @return Messages
-     */
-    protected function getMessageBlock()
-    {
-        return $this->blockFactory->create(
-            'Magento\Backend\Test\Block\Messages',
-            ['element' => $this->_rootElement->find($this->message)]
-        );
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Page/Adminhtml/SystemCurrencyIndex.xml b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Page/Adminhtml/SystemCurrencyIndex.xml
index 2ab90fb8688ebec958d8c4d8f30b9c643370e1db..efcc314043ecb2c455c908f3bc051697e7a85d42 100644
--- a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Page/Adminhtml/SystemCurrencyIndex.xml
+++ b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Page/Adminhtml/SystemCurrencyIndex.xml
@@ -7,7 +7,9 @@
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/pages.xsd">
     <page name="SystemCurrencyIndex" area="Adminhtml" mca="admin/system_currency/index" module="Magento_CurrencySymbol">
-        <block name="gridPageActions" class="Magento\CurrencySymbol\Test\Block\Adminhtml\System\Currency\GridPageActions" locator=".grid-actions" strategy="css selector"/>
-        <block name="mainPageActions" class="Magento\CurrencySymbol\Test\Block\Adminhtml\System\Currency\MainPageActions" locator=".page-main-actions" strategy="css selector"/>
+        <block name="gridPageActions" class="Magento\CurrencySymbol\Test\Block\Adminhtml\System\Currency\Rate\GridPageActions" locator=".grid-actions" strategy="css selector"/>
+        <block name="formPageActions" class="Magento\CurrencySymbol\Test\Block\Adminhtml\System\Currency\Rate\FormPageActions" locator=".page-main-actions" strategy="css selector"/>
+        <block name="currencyRateForm" class="Magento\CurrencySymbol\Test\Block\Adminhtml\System\Currency\Rate\CurrencyRateForm" locator="#rate-form" strategy="css selector"/>
+        <block name="messagesBlock" class="Magento\Backend\Test\Block\Messages" locator="#messages" strategy="css selector"/>
     </page>
-</config>
\ No newline at end of file
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Repository/ConfigData.xml b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Repository/ConfigData.xml
index 1d7fabcdeb20a6b5c12d4fd33bb4e929bf7066bb..17373832ad976111b47b2f57bbcf04f48f9b54a4 100644
--- a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Repository/ConfigData.xml
+++ b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Repository/ConfigData.xml
@@ -137,5 +137,27 @@
                 <item name="value" xsi:type="string">USD</item>
             </field>
         </dataset>
+
+        <dataset name="config_currency_symbols_usd_and_eur">
+            <field name="currency/options/allow" xsi:type="array">
+                <item name="scope" xsi:type="string">currency</item>
+                <item name="scope_id" xsi:type="number">1</item>
+                <item name="value" xsi:type="array">
+                    <item name="US Dollar" xsi:type="string">USD</item>
+                    <item name="Euro" xsi:type="string">EUR</item>
+                </item>
+            </field>
+        </dataset>
+
+        <dataset name="config_currency_symbols_usd_and_gbp">
+            <field name="currency/options/allow" xsi:type="array">
+                <item name="scope" xsi:type="string">currency</item>
+                <item name="scope_id" xsi:type="number">1</item>
+                <item name="value" xsi:type="array">
+                    <item name="US Dollar" xsi:type="string">USD</item>
+                    <item name="British Pound Sterling" xsi:type="string">GBP</item>
+                </item>
+            </field>
+        </dataset>
     </repository>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/AbstractCurrencySymbolEntityTest.php b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/AbstractCurrencySymbolEntityTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..157b6dae2e1a1be571d2e7cbd7b3adcbbed1981e
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/AbstractCurrencySymbolEntityTest.php
@@ -0,0 +1,101 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CurrencySymbol\Test\TestCase;
+
+use Magento\Mtf\Fixture\FixtureFactory;
+use Magento\Mtf\TestCase\Injectable;
+use Magento\Catalog\Test\Fixture\CatalogProductSimple;
+use Magento\CurrencySymbol\Test\Page\Adminhtml\SystemCurrencyIndex;
+use Magento\CurrencySymbol\Test\Page\Adminhtml\SystemCurrencySymbolIndex;
+
+/**
+ * Abstract class for currency symbol tests.
+ */
+abstract class AbstractCurrencySymbolEntityTest extends Injectable
+{
+    /**
+     * System Currency Symbol grid page.
+     *
+     * @var SystemCurrencySymbolIndex
+     */
+    protected $currencySymbolIndex;
+
+    /**
+     * System currency index page.
+     *
+     * @var SystemCurrencyIndex
+     */
+    protected $currencyIndex;
+
+    /**
+     * Fixture Factory.
+     *
+     * @var FixtureFactory
+     */
+    protected $fixtureFactory;
+
+    /**
+     * Create simple product and inject pages.
+     *
+     * @param SystemCurrencySymbolIndex $currencySymbolIndex
+     * @param SystemCurrencyIndex $currencyIndex
+     * @param FixtureFactory $fixtureFactory
+     * @return array
+     */
+    public function __inject(
+        SystemCurrencySymbolIndex $currencySymbolIndex,
+        SystemCurrencyIndex $currencyIndex,
+        FixtureFactory $fixtureFactory
+    ) {
+        $this->currencySymbolIndex = $currencySymbolIndex;
+        $this->currencyIndex = $currencyIndex;
+        $this->fixtureFactory = $fixtureFactory;
+        $product = $this->fixtureFactory->createByCode(
+            'catalogProductSimple',
+            ['dataSet' => 'product_with_category']
+        );
+        $product->persist();
+
+        return ['product' => $product];
+    }
+
+    /**
+     * Import currency rates.
+     *
+     * @param string $configData
+     * @return void
+     * @throws \Exception
+     */
+    protected function importCurrencyRate($configData)
+    {
+        $this->objectManager->getInstance()->create(
+            'Magento\Config\Test\TestStep\SetupConfigurationStep',
+            ['configData' => $configData]
+        )->run();
+
+        // Import Exchange Rates for currencies
+        $this->currencyIndex->open();
+        $this->currencyIndex->getGridPageActions()->clickImportButton();
+        if ($this->currencyIndex->getMessagesBlock()->isVisibleMessage('warning')) {
+            throw new \Exception($this->currencyIndex->getMessagesBlock()->getWarningMessages());
+        }
+        $this->currencyIndex->getFormPageActions()->save();
+    }
+
+    /**
+     * Disabling currency which has been added.
+     *
+     * @return void
+     */
+    public function tearDown()
+    {
+        $this->objectManager->getInstance()->create(
+            'Magento\Config\Test\TestStep\SetupConfigurationStep',
+            ['configData' => 'config_currency_symbols_usd']
+        )->run();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/EditCurrencySymbolEntityTest.php b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/EditCurrencySymbolEntityTest.php
index 5d2cc6badaa78bc22e0cec669393579f8e72e42f..c1597a1fbc4e6be9be827097c659276072d8c6ab 100644
--- a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/EditCurrencySymbolEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/EditCurrencySymbolEntityTest.php
@@ -6,12 +6,8 @@
 
 namespace Magento\CurrencySymbol\Test\TestCase;
 
-use Magento\Mtf\TestCase\Injectable;
-use Magento\Mtf\Fixture\FixtureFactory;
 use Magento\Catalog\Test\Fixture\CatalogProductSimple;
 use Magento\CurrencySymbol\Test\Fixture\CurrencySymbolEntity;
-use Magento\CurrencySymbol\Test\Page\Adminhtml\SystemCurrencyIndex;
-use Magento\CurrencySymbol\Test\Page\Adminhtml\SystemCurrencySymbolIndex;
 
 /**
  * Preconditions:
@@ -27,53 +23,13 @@ use Magento\CurrencySymbol\Test\Page\Adminhtml\SystemCurrencySymbolIndex;
  * @group Currency_(PS)
  * @ZephyrId MAGETWO-26600
  */
-class EditCurrencySymbolEntityTest extends Injectable
+class EditCurrencySymbolEntityTest extends AbstractCurrencySymbolEntityTest
 {
     /* tags */
     const MVP = 'no';
     const DOMAIN = 'PS';
     /* end tags */
 
-    /**
-     * System Currency Symbol grid page.
-     *
-     * @var SystemCurrencySymbolIndex
-     */
-    protected $currencySymbolIndex;
-
-    /**
-     * System currency index page.
-     *
-     * @var SystemCurrencyIndex
-     */
-    protected $currencyIndex;
-
-    /**
-     * Create simple product and inject pages.
-     *
-     * @param SystemCurrencySymbolIndex $currencySymbolIndex
-     * @param SystemCurrencyIndex $currencyIndex,
-     * @param FixtureFactory $fixtureFactory
-     * @return array
-     */
-    public function __inject(
-        SystemCurrencySymbolIndex $currencySymbolIndex,
-        SystemCurrencyIndex $currencyIndex,
-        FixtureFactory $fixtureFactory
-    ) {
-        $this->currencySymbolIndex = $currencySymbolIndex;
-        $this->currencyIndex = $currencyIndex;
-
-        /**@var CatalogProductSimple $catalogProductSimple */
-        $product = $fixtureFactory->createByCode(
-            'catalogProductSimple',
-            ['dataSet' => 'product_with_category']
-        );
-        $product->persist();
-
-        return ['product' => $product];
-    }
-
     /**
      * Edit Currency Symbol Entity test.
      *
@@ -91,36 +47,4 @@ class EditCurrencySymbolEntityTest extends Injectable
         $this->currencySymbolIndex->getCurrencySymbolForm()->fill($currencySymbol);
         $this->currencySymbolIndex->getPageActions()->save();
     }
-
-    /**
-     * Import currency rates.
-     *
-     * @param string $configData
-     * @return void
-     */
-    protected function importCurrencyRate($configData)
-    {
-        $this->objectManager->getInstance()->create(
-            'Magento\Config\Test\TestStep\SetupConfigurationStep',
-            ['configData' => $configData]
-        )->run();
-
-        // Import Exchange Rates for currencies
-        $this->currencyIndex->open();
-        $this->currencyIndex->getGridPageActions()->clickImportButton();
-        $this->currencyIndex->getMainPageActions()->saveCurrentRate();
-    }
-
-    /**
-     * Disabling currency which has been added.
-     *
-     * @return void
-     */
-    public function tearDown()
-    {
-        $this->objectManager->getInstance()->create(
-            'Magento\Config\Test\TestStep\SetupConfigurationStep',
-            ['configData' => 'config_currency_symbols_usd']
-        )->run();
-    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/ResetCurrencySymbolEntityTest.php b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/ResetCurrencySymbolEntityTest.php
index f64c407f6aefffb4f76ccf351282c38556b079ca..96537d399ce8770887994dd6a6b7f9268f3e40f4 100644
--- a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/ResetCurrencySymbolEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/ResetCurrencySymbolEntityTest.php
@@ -6,12 +6,8 @@
 
 namespace Magento\CurrencySymbol\Test\TestCase;
 
-use Magento\Mtf\TestCase\Injectable;
-use Magento\Mtf\Fixture\FixtureFactory;
 use Magento\Catalog\Test\Fixture\CatalogProductSimple;
 use Magento\CurrencySymbol\Test\Fixture\CurrencySymbolEntity;
-use Magento\CurrencySymbol\Test\Page\Adminhtml\SystemCurrencyIndex;
-use Magento\CurrencySymbol\Test\Page\Adminhtml\SystemCurrencySymbolIndex;
 
 /**
  * Preconditions:
@@ -28,77 +24,13 @@ use Magento\CurrencySymbol\Test\Page\Adminhtml\SystemCurrencySymbolIndex;
  * @group Currency_(PS)
  * @ZephyrId MAGETWO-26638
  */
-class ResetCurrencySymbolEntityTest extends Injectable
+class ResetCurrencySymbolEntityTest extends AbstractCurrencySymbolEntityTest
 {
     /* tags */
     const MVP = 'no';
     const DOMAIN = 'PS';
     /* end tags */
 
-    /**
-     * System currency symbol grid page.
-     *
-     * @var SystemCurrencySymbolIndex
-     */
-    protected $currencySymbolIndex;
-
-    /**
-     * System currency index page.
-     *
-     * @var SystemCurrencyIndex
-     */
-    protected $currencyIndex;
-
-    /**
-     * Currency symbol entity fixture.
-     *
-     * @var CurrencySymbolEntity
-     */
-    protected $currencySymbolDefault;
-
-    /**
-     * Fixture Factory.
-     *
-     * @var FixtureFactory
-     */
-    protected $fixtureFactory;
-
-    /**
-     * Prepare data. Create simple product.
-     *
-     * @param FixtureFactory $fixtureFactory
-     * @return array
-     */
-    public function __prepare(FixtureFactory $fixtureFactory)
-    {
-        $this->fixtureFactory = $fixtureFactory;
-        $product = $this->fixtureFactory->createByCode(
-            'catalogProductSimple',
-            ['dataSet' => 'product_with_category']
-        );
-        $product->persist();
-
-        return ['product' => $product];
-    }
-
-    /**
-     * Injection data.
-     *
-     * @param SystemCurrencySymbolIndex $currencySymbolIndex
-     * @param SystemCurrencyIndex $currencyIndex
-     * @param CurrencySymbolEntity $currencySymbolDefault
-     * @return array
-     */
-    public function __inject(
-        SystemCurrencySymbolIndex $currencySymbolIndex,
-        SystemCurrencyIndex $currencyIndex,
-        CurrencySymbolEntity $currencySymbolDefault
-    ) {
-        $this->currencySymbolIndex = $currencySymbolIndex;
-        $this->currencyIndex = $currencyIndex;
-        $this->currencySymbolDefault = $currencySymbolDefault;
-    }
-
     /**
      * Reset Currency Symbol Entity test.
      *
@@ -135,36 +67,4 @@ class ResetCurrencySymbolEntityTest extends Injectable
             )
         ];
     }
-
-    /**
-     * Import currency rates.
-     *
-     * @param string $configData
-     * @return void
-     */
-    protected function importCurrencyRate($configData)
-    {
-        $this->objectManager->getInstance()->create(
-            'Magento\Config\Test\TestStep\SetupConfigurationStep',
-            ['configData' => $configData]
-        )->run();
-
-        // Import Exchange Rates for currencies
-        $this->currencyIndex->open();
-        $this->currencyIndex->getGridPageActions()->clickImportButton();
-        $this->currencyIndex->getMainPageActions()->saveCurrentRate();
-    }
-
-    /**
-     * Disabling currency which has been added.
-     *
-     * @return void
-     */
-    public function tearDown()
-    {
-        $this->objectManager->getInstance()->create(
-            'Magento\Config\Test\TestStep\SetupConfigurationStep',
-            ['configData' => 'config_currency_symbols_usd']
-        )->run();
-    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/CustomerForm.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/CustomerForm.xml
index d8722814679701ed50ae1f70c49025d042738519..bc70891ffa44c1c7dc73bdc6469b37fcd113c886 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/CustomerForm.xml
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/CustomerForm.xml
@@ -8,9 +8,9 @@
 <tabs>
     <account_information>
         <class>\Magento\Backend\Test\Block\Widget\Tab</class>
-        <selector>#tab_account</selector>
+        <selector>#tab_customer</selector>
         <strategy>css selector</strategy>
-        <wrapper>account</wrapper>
+        <wrapper>data[customer]</wrapper>
         <fields>
             <website_id>
                 <input>select</input>
@@ -28,7 +28,7 @@
     </account_information>
     <addresses>
         <class>\Magento\Customer\Test\Block\Adminhtml\Edit\Tab\Addresses</class>
-        <selector>#tab_customer_address</selector>
+        <selector>#tab_address</selector>
         <strategy>css selector</strategy>
     </addresses>
 </tabs>
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/Tab/Addresses.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/Tab/Addresses.xml
index efef4933c1b7421defaf380157ce9b53cf53e66e..b50ddc0ff54a605085e89611fd4e168a93fe35be 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/Tab/Addresses.xml
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/Tab/Addresses.xml
@@ -70,11 +70,11 @@
             <strategy>css selector</strategy>
         </vat_id>
         <default_billing>
-            <selector>#address_list [aria-selected="true"] [name^="account"][name$="[default_billing]"]</selector>
+            <selector>.ui-state-active [name$="[default_billing]"]</selector>
             <input>checkbox</input>
         </default_billing>
         <default_shipping>
-            <selector>#address_list [aria-selected="true"] [name^="account"][name$="[default_shipping]"]</selector>
+            <selector>.ui-state-active [name$="[default_shipping]"]</selector>
             <input>checkbox</input>
         </default_shipping>
     </fields>
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/Customer/Curl.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/Customer/Curl.php
index 67d98b313afe2c576d620daed3c0dfd392d40315..fb1030c3143f16e5496bd47354f74826ed2c457c 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/Customer/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/Customer/Curl.php
@@ -34,6 +34,10 @@ class Curl extends AbstractCurl implements CustomerInterface
             'United States' => 'US',
             'United Kingdom' => 'GB'
         ],
+        'gender' => [
+            'Male' => 1,
+            'Female' => 2,
+        ],
         'region_id' => [
             'California' => 12,
             'New York' => 43,
@@ -47,14 +51,15 @@ class Curl extends AbstractCurl implements CustomerInterface
      * @var array
      */
     protected $curlMapping = [
-        'account' => [
+        'customer' => [
             'group_id',
             'firstname',
             'lastname',
             'email',
             'dob',
             'taxvat',
-            'gender'
+            'gender',
+            'entity_id',
         ]
     ];
 
@@ -77,12 +82,11 @@ class Curl extends AbstractCurl implements CustomerInterface
      */
     public function persist(FixtureInterface $customer = null)
     {
-        $address = [];
-        $result = [];
         /** @var Customer $customer */
-        $url = $_ENV['app_frontend_url'] . 'customer/account/createpost/?nocookie=true';
         $data = $customer->getData();
         $data['group_id'] = $this->getCustomerGroup($customer);
+        $address = [];
+        $url = $_ENV['app_frontend_url'] . 'customer/account/createpost/?nocookie=true';
 
         if ($customer->hasData('address')) {
             $address = $customer->getAddress();
@@ -98,15 +102,14 @@ class Curl extends AbstractCurl implements CustomerInterface
             throw new \Exception("Customer entity creating  by curl handler was not successful! Response: $response");
         }
 
-        $result['id'] = $this->getCustomerId($customer->getEmail());
-        $data['customer_id'] = $result['id'];
+        $data['entity_id'] = $this->getCustomerId($customer->getEmail());
 
         if (!empty($address)) {
             $data['address'] = $address;
         }
         $this->updateCustomer($data);
 
-        return $result;
+        return ['id' => $data['entity_id']];
     }
 
     /**
@@ -167,19 +170,19 @@ class Curl extends AbstractCurl implements CustomerInterface
         }
         unset($data['password'], $data['password_confirmation']);
 
-        $curlData = $this->replaceMappingData(array_merge($curlData, $data));
+        $curlData = $this->replaceMappingData(array_replace_recursive($curlData, $data));
         if (!empty($data['address'])) {
             $curlData = $this->prepareAddressData($curlData);
         }
 
-        $url = $_ENV['app_backend_url'] . 'customer/index/save/id/' . $data['customer_id'];
+        $url = $_ENV['app_backend_url'] . 'customer/index/save/id/' . $curlData['customer']['entity_id'];
         $curl = new BackendDecorator(new CurlTransport(), $this->_configuration);
         $curl->write(CurlInterface::POST, $url, '1.0', [], $curlData);
         $response = $curl->read();
         $curl->close();
 
         if (!strpos($response, 'data-ui-id="messages-message-success"')) {
-            $this->_eventManager->dispatchEvent(['curl_failed', [$response]]);
+            $this->_eventManager->dispatchEvent(['curl_failed'], [$response]);
             throw new \Exception('Failed to update customer!');
         }
     }
@@ -200,7 +203,6 @@ class Curl extends AbstractCurl implements CustomerInterface
                 $curlData['address'][$key]['street'] = [];
                 $curlData['address'][$key]['street'][] = $street;
             }
-            $newKey = 'new_' . ($key);
             if (isset($curlData['address'][$key]['default_billing'])) {
                 $value = $curlData['address'][$key]['default_billing'] === 'Yes' ? 'true' : 'false';
                 $curlData['address'][$key]['default_billing'] = $value;
@@ -209,9 +211,7 @@ class Curl extends AbstractCurl implements CustomerInterface
                 $value = $curlData['address'][$key]['default_shipping'] === 'Yes' ? 'true' : 'false';
                 $curlData['address'][$key]['default_shipping'] = $value;
             }
-            $curlData['account']['customer_address'][$newKey] = $curlData['address'][$key];
         }
-        unset($curlData['address']);
 
         return $curlData;
     }
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountCreate.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountCreate.xml
index 783fa1ad4e1b476da685d85db7e08281163d7256..57cf9a355142c53bce686233fd8ccbf588296f45 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountCreate.xml
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountCreate.xml
@@ -6,8 +6,8 @@
  */
  -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/pages.xsd">
-  <page name="CustomerAccountCreate" mca="customer/account/create" module="Magento_Customer">
-    <block name="registerForm" class="Magento\Customer\Test\Block\Form\Register" locator="#form-validate" strategy="css selector"/>
-    <block name="messagesBlock" class="Magento\Backend\Test\Block\Messages" locator=".page.messages" strategy="css selector"/>
-  </page>
+    <page name="CustomerAccountCreate" mca="customer/account/create" module="Magento_Customer">
+        <block name="registerForm" class="Magento\Customer\Test\Block\Form\Register" locator="#form-validate[novalidate='novalidate']" strategy="css selector" />
+        <block name="messagesBlock" class="Magento\Backend\Test\Block\Messages" locator=".page.messages" strategy="css selector" />
+    </page>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Directory/Test/Constraint/AssertCurrencyRateAppliedOnCatalogPage.php b/dev/tests/functional/tests/app/Magento/Directory/Test/Constraint/AssertCurrencyRateAppliedOnCatalogPage.php
new file mode 100644
index 0000000000000000000000000000000000000000..05cd0245e1a759d6162a5dca748479844cb551c8
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Directory/Test/Constraint/AssertCurrencyRateAppliedOnCatalogPage.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Directory\Test\Constraint;
+
+use Magento\Cms\Test\Page\CmsIndex;
+use Magento\Mtf\Constraint\AbstractConstraint;
+use Magento\Catalog\Test\Fixture\CatalogProductSimple;
+use Magento\Catalog\Test\Page\Category\CatalogCategoryView;
+use Magento\CurrencySymbol\Test\Fixture\CurrencySymbolEntity;
+
+/**
+ * Assert currency rate applied on catalog page.
+ */
+class AssertCurrencyRateAppliedOnCatalogPage extends AbstractConstraint
+{
+    /**
+     * Assert currency rate applied on catalog page.
+     *
+     * @param CmsIndex $cmsIndex
+     * @param CatalogCategoryView $catalogCategoryView
+     * @param CatalogProductSimple $product
+     * @param CurrencySymbolEntity $currencySymbol
+     * @param string $basePrice
+     * @param string $convertedPrice
+     * @return void
+     */
+    public function processAssert(
+        CmsIndex $cmsIndex,
+        CatalogCategoryView $catalogCategoryView,
+        CatalogProductSimple $product,
+        CurrencySymbolEntity $currencySymbol,
+        $basePrice,
+        $convertedPrice
+    ) {
+        $categoryName = $product->getCategoryIds()[0];
+        $cmsIndex->open();
+        $cmsIndex->getTopmenu()->selectCategoryByName($categoryName);
+        $priceBlock = $catalogCategoryView->getListProductBlock()->getProductItem($product)->getPriceBlock();
+        $actualPrice = $priceBlock->getPrice('');
+
+        \PHPUnit_Framework_Assert::assertEquals(
+            $basePrice,
+            $actualPrice,
+            'Wrong price is displayed on Category page.'
+        );
+
+        $cmsIndex->getCurrencyBlock()->switchCurrency($currencySymbol);
+        $cmsIndex->getTopmenu()->selectCategoryByName($categoryName);
+        $actualPrice = $priceBlock->getPrice('');
+
+        \PHPUnit_Framework_Assert::assertEquals(
+            $convertedPrice,
+            $actualPrice,
+            'Wrong price is displayed on Category page.'
+        );
+    }
+
+    /**
+     * Returns a string representation of successful assertion.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return "Currency rate has been applied correctly on Catalog page.";
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Directory/Test/Constraint/AssertCurrencyRateSuccessSaveMessage.php b/dev/tests/functional/tests/app/Magento/Directory/Test/Constraint/AssertCurrencyRateSuccessSaveMessage.php
new file mode 100644
index 0000000000000000000000000000000000000000..3a9f7e82a3943e73ece72d72fbefb3bc2e720ca5
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Directory/Test/Constraint/AssertCurrencyRateSuccessSaveMessage.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Directory\Test\Constraint;
+
+use Magento\Mtf\Constraint\AbstractConstraint;
+use Magento\CurrencySymbol\Test\Page\Adminhtml\SystemCurrencyIndex;
+
+/**
+ * Assert that success message is displayed.
+ */
+class AssertCurrencyRateSuccessSaveMessage extends AbstractConstraint
+{
+    const SUCCESS_MESSAGE = 'All valid rates have been saved.';
+
+    /**
+     * Assert that success message is displayed after currency rate saved.
+     *
+     * @param SystemCurrencyIndex $currencyIndexPage
+     * @return void
+     */
+    public function processAssert(SystemCurrencyIndex $currencyIndexPage)
+    {
+        $actualMessage = $currencyIndexPage->getMessagesBlock()->getSuccessMessages();
+        \PHPUnit_Framework_Assert::assertEquals(
+            self::SUCCESS_MESSAGE,
+            $actualMessage,
+            'Wrong success message is displayed.'
+            . "\nExpected: " . self::SUCCESS_MESSAGE
+            . "\nActual: " . $actualMessage
+        );
+    }
+
+    /**
+     * Returns a string representation of successful assertion.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Currency rate success create message is present.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Directory/Test/Fixture/CurrencyRate.xml b/dev/tests/functional/tests/app/Magento/Directory/Test/Fixture/CurrencyRate.xml
new file mode 100644
index 0000000000000000000000000000000000000000..70fcf15c962980ade05464ff3e6a8cebb9b66c85
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Directory/Test/Fixture/CurrencyRate.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+ -->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+    <fixture name="currencyRate" module="Magento_Directory" type="flat" entity_type="directory_currency_rate" collection="Magento\Directory\Model\Resource\Currency" identifier="" repository_class="Magento\Directory\Test\Repository\CurrencyRate" handler_interface="Magento\Directory\Test\Handler\CurrencyRate\CurrencyRateInterface" class="Magento\Directory\Test\Fixture\CurrencyRate">
+        <dataset name="default">
+            <field name="currency_from" xsi:type="string">USD</field>
+            <field name="currency_to" xsi:type="string">EUR</field>
+            <field name="rate" xsi:type="number">0.8</field>
+        </dataset>
+
+        <field name="currency_from" is_required="1" />
+        <field name="currency_to" is_required="1" />
+        <field name="rate" is_required="1" />
+    </fixture>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Directory/Test/Handler/CurrencyRate/Curl.php b/dev/tests/functional/tests/app/Magento/Directory/Test/Handler/CurrencyRate/Curl.php
new file mode 100644
index 0000000000000000000000000000000000000000..cc6fbf9895588b3ae58c5dd75779c97e54c6a7ce
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Directory/Test/Handler/CurrencyRate/Curl.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Directory\Test\Handler\CurrencyRate;
+
+use Magento\Mtf\Fixture\FixtureInterface;
+use Magento\Mtf\Handler\Curl as AbstractCurl;
+use Magento\Mtf\Util\Protocol\CurlInterface;
+use Magento\Mtf\Util\Protocol\CurlTransport;
+use Magento\Mtf\Util\Protocol\CurlTransport\BackendDecorator;
+
+/**
+ * Curl handler for setting currency rates.
+ */
+class Curl extends AbstractCurl implements CurrencyRateInterface
+{
+    /**
+     * Post request for setting currency rate.
+     *
+     * @param FixtureInterface $fixture [optional]
+     * @return mixed|string
+     * @throws \Exception
+     */
+    public function persist(FixtureInterface $fixture = null)
+    {
+        $data = $this->prepareData($fixture);
+
+        $url = $_ENV['app_backend_url'] . 'admin/system_currency/saveRates/';
+        $curl = new BackendDecorator(new CurlTransport(), $this->_configuration);
+        $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("Currency rates setting by curl handler was not successful! Response:\n" . $response);
+        }
+    }
+
+    /**
+     * Prepare data for POST request.
+     *
+     * @param FixtureInterface $fixture
+     * @return array
+     */
+    protected function prepareData(FixtureInterface $fixture)
+    {
+        $result = [];
+        $data = $fixture->getData();
+        $result['rate'][$data['currency_from']][$data['currency_to']] = $data['rate'];
+
+        return $result;
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Directory/Test/Handler/CurrencyRate/CurrencyRateInterface.php b/dev/tests/functional/tests/app/Magento/Directory/Test/Handler/CurrencyRate/CurrencyRateInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..99cc0f552b190d49268024a33dfa0501e97f8cc7
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Directory/Test/Handler/CurrencyRate/CurrencyRateInterface.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Directory\Test\Handler\CurrencyRate;
+
+use Magento\Mtf\Handler\HandlerInterface;
+
+/**
+ * Interface CurrencyRateInterface
+ */
+interface CurrencyRateInterface extends HandlerInterface
+{
+    //
+}
diff --git a/dev/tests/functional/tests/app/Magento/Directory/Test/Repository/CurrencyRate.xml b/dev/tests/functional/tests/app/Magento/Directory/Test/Repository/CurrencyRate.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c1b6dc96e3cbb79862eb959f0325f551cb12acf2
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Directory/Test/Repository/CurrencyRate.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/Magento/Mtf/Repository/etc/repository.xsd">
+    <repository class="Magento\Directory\Test\Repository\CurrencyRate">
+        <dataset name="usd_chf_rate_0_9">
+            <field name="currency_from" xsi:type="string">USD</field>
+            <field name="currency_to" xsi:type="string">CHF</field>
+            <field name="rate" xsi:type="number">0.9</field>
+        </dataset>
+
+        <dataset name="usd_gbp_rate_0_6">
+            <field name="currency_from" xsi:type="string">USD</field>
+            <field name="currency_to" xsi:type="string">GBP</field>
+            <field name="rate" xsi:type="number">0.6</field>
+        </dataset>
+    </repository>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Directory/Test/TestCase/CreateCurrencyRateTest.php b/dev/tests/functional/tests/app/Magento/Directory/Test/TestCase/CreateCurrencyRateTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..04aa6c4ca73d61e4ef01e61ac9929d9a225d2b59
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Directory/Test/TestCase/CreateCurrencyRateTest.php
@@ -0,0 +1,87 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Directory\Test\TestCase;
+
+use Magento\Config\Test\Fixture\ConfigData;
+use Magento\Mtf\TestCase\Injectable;
+use Magento\Directory\Test\Fixture\CurrencyRate;
+use Magento\Catalog\Test\Fixture\CatalogProductSimple;
+use Magento\CurrencySymbol\Test\Page\Adminhtml\SystemCurrencyIndex;
+
+/**
+ * Preconditions:
+ * 1. Create Simple product and assign it to the category.
+ * 2. Configure allowed Currencies Options.
+ *
+ * Steps:
+ * 1. Login to backend.
+ * 2. Go to Stores > Currency > Currency Rates.
+ * 3. Fill currency rate according to dataSet.
+ * 4. Click on 'Save Currency Rates' button.
+ * 5. Perform assertions.
+ *
+ * @group Localization_(PS)
+ * @ZephyrId MAGETWO-12427, MAGETWO-36824
+ */
+class CreateCurrencyRateTest extends Injectable
+{
+    /* tags */
+    const TEST_TYPE = 'acceptance_test';
+    const DOMAIN = 'PS';
+    /* end tags */
+
+    /**
+     * Currency rate index page.
+     *
+     * @var SystemCurrencyIndex
+     */
+    protected $currencyIndexPage;
+
+    /**
+     * Inject data.
+     *
+     * @param SystemCurrencyIndex $currencyIndexPage
+     * @return void
+     */
+    public function __inject(SystemCurrencyIndex $currencyIndexPage)
+    {
+        $this->currencyIndexPage = $currencyIndexPage;
+    }
+
+    /**
+     * Create currency rate test.
+     *
+     * @param CurrencyRate $currencyRate
+     * @param CatalogProductSimple $product
+     * @param $config
+     * @return void
+     */
+    public function test(CurrencyRate $currencyRate, CatalogProductSimple $product, ConfigData $config)
+    {
+        // Preconditions:
+        $product->persist();
+        $config->persist();
+
+        // Steps:
+        $this->currencyIndexPage->open();
+        $this->currencyIndexPage->getCurrencyRateForm()->fill($currencyRate);
+        $this->currencyIndexPage->getFormPageActions()->save();
+    }
+
+    /**
+     * Reset currency config to default values.
+     *
+     * @return void
+     */
+    public function tearDown()
+    {
+        $this->objectManager->create(
+            'Magento\Config\Test\TestStep\SetupConfigurationStep',
+            ['configData' => 'config_currency_symbols_usd']
+        )->run();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Directory/Test/TestCase/CreateCurrencyRateTest.xml b/dev/tests/functional/tests/app/Magento/Directory/Test/TestCase/CreateCurrencyRateTest.xml
new file mode 100644
index 0000000000000000000000000000000000000000..561f9307ff07f058b79e7873e4e7ed15ceb67632
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Directory/Test/TestCase/CreateCurrencyRateTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+ -->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
+    <testCase name="Magento\Directory\Test\TestCase\CreateCurrencyRateTest">
+        <variation name="CreateCurrencyRateTestVariation1">
+            <data name="currencyRate/data/currency_from" xsi:type="string">USD</data>
+            <data name="currencyRate/data/currency_to" xsi:type="string">EUR</data>
+            <data name="currencyRate/data/rate" xsi:type="number">0.8</data>
+            <data name="currencySymbol/dataSet" xsi:type="string">currency_symbols_eur</data>
+            <data name="product/dataSet" xsi:type="string">simple_10_dollar</data>
+            <data name="config/dataSet" xsi:type="string">config_currency_symbols_usd_and_eur</data>
+            <data name="basePrice" xsi:type="string">$10.00</data>
+            <data name="convertedPrice" xsi:type="string">€8.00</data>
+            <data name="tag" xsi:type="string">test_type:acceptance_test</data>
+            <constraint name="Magento\Directory\Test\Constraint\AssertCurrencyRateSuccessSaveMessage"/>
+            <constraint name="Magento\Directory\Test\Constraint\AssertCurrencyRateAppliedOnCatalogPage"/>
+        </variation>
+    </testCase>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Directory/Test/etc/curl/di.xml b/dev/tests/functional/tests/app/Magento/Directory/Test/etc/curl/di.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0962d9ed807d9206fb6e31b641e4fa133588097c
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Directory/Test/etc/curl/di.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
+    <preference for="\Magento\Directory\Test\Handler\CurrencyRate\CurrencyRateInterface" type="\Magento\Directory\Test\Handler\CurrencyRate\Curl" />
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/LinkRow.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/LinkRow.php
index 64d1aab3f990b7d1a043a6cce9bd2bc7bd890403..774f85d7772f4f9fdd76ca895448e8045d0a2c1c 100644
--- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/LinkRow.php
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/LinkRow.php
@@ -3,6 +3,7 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
+
 namespace Magento\Downloadable\Test\Block\Adminhtml\Catalog\Product\Edit\Tab\Downloadable;
 
 use Magento\Mtf\Block\Form;
@@ -19,7 +20,7 @@ class LinkRow extends Form
      *
      * @var string
      */
-    protected $deleteButton = '.action-remove';
+    protected $deleteButton = '.action-delete';
 
     /**
      * Fill item link
diff --git a/dev/tests/functional/tests/app/Magento/GiftMessage/Test/Block/Adminhtml/Order/Create/Items/ItemProduct.php b/dev/tests/functional/tests/app/Magento/GiftMessage/Test/Block/Adminhtml/Order/Create/Items/ItemProduct.php
index 3627d161b35ab583e5f5c7ab4a1c919d473c2c6c..77d38c0eb97743553753d2f5d1ae8ba9aa75bbeb 100644
--- a/dev/tests/functional/tests/app/Magento/GiftMessage/Test/Block/Adminhtml/Order/Create/Items/ItemProduct.php
+++ b/dev/tests/functional/tests/app/Magento/GiftMessage/Test/Block/Adminhtml/Order/Create/Items/ItemProduct.php
@@ -29,11 +29,11 @@ class ItemProduct extends \Magento\Sales\Test\Block\Adminhtml\Order\Create\Items
     protected $giftMessageForm = './/*[@role="dialog"][*[@id="gift_options_configure"]]';
 
     /**
-     * Magento varienLoader.js loader.
+     * Magento loader.
      *
      * @var string
      */
-    protected $loadingMask = '//*[@id="loading-mask"]/*[@id="loading_mask_loader"]';
+    protected $loader = '[data-role="loader"]';
 
     /**
      * Fill GiftMessage form.
@@ -58,10 +58,11 @@ class ItemProduct extends \Magento\Sales\Test\Block\Adminhtml\Order\Create\Items
             ['element' => $this->browser->find($this->giftMessageForm, Locator::SELECTOR_XPATH)]
         );
         $giftMessageForm->fill($giftMessage);
-        $loadingMask = $this->browser->find($this->loadingMask, Locator::SELECTOR_XPATH);
+        $loader = $this->loader;
         $this->browser->waitUntil(
-            function () use ($loadingMask) {
-                return !$loadingMask->isVisible() ? true : null;
+            function () use ($browser, $loader) {
+                $element = $this->browser->find($loader);
+                return $element->isVisible() == false ? true : null;
             }
         );
     }
diff --git a/dev/tests/functional/tests/app/Magento/GiftMessage/Test/etc/testcase.xml b/dev/tests/functional/tests/app/Magento/GiftMessage/Test/etc/testcase.xml
index 3ce7af8e5be7e87a8a7173565d2b67e0740afa88..de5469059a9b89883c6210b648f0783b8af43fd8 100644
--- a/dev/tests/functional/tests/app/Magento/GiftMessage/Test/etc/testcase.xml
+++ b/dev/tests/functional/tests/app/Magento/GiftMessage/Test/etc/testcase.xml
@@ -22,15 +22,9 @@
         <step name="placeOrder" module="Magento_Checkout" />
     </scenario>
     <scenario name="CreateGiftMessageOnBackendTest" firstStep="setupConfiguration">
-        <step name="setupConfiguration" module="Magento_Config" next="createProducts">
-            <item name="configData" value="cashondelivery, enable_gift_messages" />
-        </step>
+        <step name="setupConfiguration" module="Magento_Config" next="createProducts" />
         <step name="createProducts" module="Magento_Catalog" next="createCustomer" />
-        <step name="createCustomer" module="Magento_Customer" next="openSalesOrders">
-            <item name="customer">
-                <item name="dataSet" value="johndoe_with_addresses" />
-            </item>
-        </step>
+        <step name="createCustomer" module="Magento_Customer" next="openSalesOrders" />
         <step name="openSalesOrders" module="Magento_Sales" next="createNewOrder" />
         <step name="createNewOrder" module="Magento_Sales" next="selectCustomerOrder" />
         <step name="selectCustomerOrder" module="Magento_Sales" next="selectStore" />
diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Fixture/GroupedProduct/CheckoutData.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Fixture/GroupedProduct/CheckoutData.php
index 5c45ad254c0b02f4444547e1b95ebba7fedf2727..2871ec912db01ef8020b14699f62d95c6f7299ac 100644
--- a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Fixture/GroupedProduct/CheckoutData.php
+++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Fixture/GroupedProduct/CheckoutData.php
@@ -57,39 +57,6 @@ class CheckoutData extends \Magento\Catalog\Test\Fixture\CatalogProductSimple\Ch
                     ],
                 ],
             ],
-            'three_simple_products_default_qty' => [
-                'options' => [
-                    [
-                        'name' => 'product_key_0',
-                        'qty' => 17,
-                    ],
-                    [
-                        'name' => 'product_key_1',
-                        'qty' => 36
-                    ],
-                    [
-                        'name' => 'product_key_2',
-                        'qty' => 20
-                    ],
-                ],
-                'cartItem' => [
-                    'price' => [
-                        'product_key_0' => 560,
-                        'product_key_1' => 40,
-                        'product_key_2' => 100,
-                    ],
-                    'qty' => [
-                        'product_key_0' => 17,
-                        'product_key_1' => 36,
-                        'product_key_2' => 20,
-                    ],
-                    'subtotal' => [
-                        'product_key_0' => 9520.00,
-                        'product_key_1' => 1440.00,
-                        'product_key_2' => 2000.00,
-                    ],
-                ],
-            ],
         ];
         return isset($presets[$name]) ? $presets[$name] : null;
     }
diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Repository/GroupedProduct.xml b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Repository/GroupedProduct.xml
index fbf4305699a447b37e9a8d1bd756caec8f1f569e..cd0bc02b3df4ccab18c34b1876eef98e775af553 100644
--- a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Repository/GroupedProduct.xml
+++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Repository/GroupedProduct.xml
@@ -117,34 +117,5 @@
                 <item name="preset" xsi:type="string">three_simple_products</item>
             </field>
         </dataset>
-
-        <dataset name="three_simple_products_default_qty">
-            <field name="name" xsi:type="string">Grouped product %isolation%</field>
-            <field name="sku" xsi:type="string">grouped_product_%isolation%</field>
-            <field name="category_ids" xsi:type="array">
-                <item name="presets" xsi:type="string">default</item>
-            </field>
-            <field name="associated" xsi:type="array">
-                <item name="preset" xsi:type="string">three_simple_products</item>
-            </field>
-            <field name="status" xsi:type="string">Product online</field>
-            <field name="visibility" xsi:type="string">Catalog, Search</field>
-            <field name="tax_class_id" xsi:type="array">
-                <item name="dataSet" xsi:type="string">taxable_goods</item>
-            </field>
-            <field name="url_key" xsi:type="string">test-grouped-product-%isolation%</field>
-            <field name="quantity_and_stock_status" xsi:type="array">
-                <item name="is_in_stock" xsi:type="string">In Stock</item>
-            </field>
-            <field name="website_ids" xsi:type="array">
-                <item name="0" xsi:type="string">Main Website</item>
-            </field>
-            <field name="attribute_set_id" xsi:type="array">
-                <item name="dataSet" xsi:type="string">default</item>
-            </field>
-            <field name="checkout_data" xsi:type="array">
-                <item name="preset" xsi:type="string">three_simple_products_default_qty</item>
-            </field>
-        </dataset>
     </repository>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/Block/Navigation.php b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/Block/Navigation.php
index 41376ef7a3735d1af8d8dd8531397518f7f5b0a9..4dfa6dd2122c10aa6a7344210cd47d10985551c0 100644
--- a/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/Block/Navigation.php
+++ b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/Block/Navigation.php
@@ -3,13 +3,14 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
+
 namespace Magento\LayeredNavigation\Test\Block;
 
 use Magento\Mtf\Block\Block;
 use Magento\Mtf\Client\Locator;
 
 /**
- * Catalog layered navigation view block
+ * Catalog layered navigation view block.
  */
 class Navigation extends Block
 {
@@ -20,20 +21,6 @@ class Navigation extends Block
      */
     protected $clearAll = '.action.clear';
 
-    /**
-     * Price range.
-     *
-     * @var string
-     */
-    protected $priceRange = "[href$='?price=%s']";
-
-    /**
-     * Attribute option.
-     *
-     * @var string
-     */
-    protected $attributeOption = "//a[contains(text(), '%s')]";
-
     /**
      * Attribute option title selector.
      *
@@ -42,11 +29,11 @@ class Navigation extends Block
     protected $optionTitle = '.filter-options-title';
 
     /**
-     * Attribute option content selector.
+     * Filter link locator.
      *
      * @var string
      */
-    protected $optionContent = '.filter-options-content';
+    protected $filterLink = './/dt[contains(text(),"%s")]/following-sibling::dd//a';
 
     /**
      * Click on 'Clear All' link.
@@ -58,28 +45,6 @@ class Navigation extends Block
         $this->_rootElement->find($this->clearAll, locator::SELECTOR_CSS)->click();
     }
 
-    /**
-     * Select product price range.
-     *
-     * @param string $range
-     * @return void
-     */
-    public function selectPriceRange($range)
-    {
-        $this->_rootElement->find(sprintf($this->priceRange, $range))->click();
-    }
-
-    /**
-     * Select attribute option.
-     *
-     * @param string $optionName
-     * @return void
-     */
-    public function selectAttributeOption($optionName)
-    {
-        $this->_rootElement->find(sprintf($this->attributeOption, $optionName), Locator::SELECTOR_XPATH)->click();
-    }
-
     /**
      * Get array of available filters.
      *
@@ -94,4 +59,25 @@ class Navigation extends Block
         }
         return $data;
     }
+
+    /**
+     * Click filter link.
+     *
+     * @param string $filter
+     * @param string $linkPattern
+     * @return void
+     * @throws \Exception
+     */
+    public function clickFilterLink($filter, $linkPattern)
+    {
+        $links = $this->_rootElement->getElements(sprintf($this->filterLink, $filter), Locator::SELECTOR_XPATH);
+
+        foreach ($links as $link) {
+            if (preg_match($linkPattern, trim($link->getText()))) {
+                $link->click();
+                return;
+            }
+        }
+        throw new \Exception("Can't find {$filter} filter link by pattern: {$linkPattern}");
+    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/Constraint/AssertFilterProductList.php b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/Constraint/AssertFilterProductList.php
new file mode 100644
index 0000000000000000000000000000000000000000..e2b384a26611026f3c353fd7d8f7185ecab99143
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/Constraint/AssertFilterProductList.php
@@ -0,0 +1,90 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\LayeredNavigation\Test\Constraint;
+
+use Magento\Catalog\Test\Fixture\Category;
+use Magento\Catalog\Test\Page\Category\CatalogCategoryView;
+use Magento\Cms\Test\Page\CmsIndex;
+use Magento\Mtf\Constraint\AbstractConstraint;
+
+/**
+ * Check whether products can be filtered in the Frontend via layered navigation.
+ */
+class AssertFilterProductList extends AbstractConstraint
+{
+    /**
+     * Available products list.
+     *
+     * @var array
+     */
+    protected $products;
+
+    /**
+     * Assertion that filtered product list via layered navigation are displayed correctly.
+     *
+     * @param Category $category
+     * @param CmsIndex $cmsIndex
+     * @param CatalogCategoryView $catalogCategoryView
+     * @param array $layeredNavigation
+     * @return void
+     */
+    public function processAssert(
+        Category $category,
+        CmsIndex $cmsIndex,
+        CatalogCategoryView $catalogCategoryView,
+        array $layeredNavigation
+    ) {
+        $this->products = $category->getDataFieldConfig('category_products')['source']->getProducts();
+        $cmsIndex->open();
+        $cmsIndex->getTopmenu()->selectCategoryByName($category->getName());
+
+        foreach ($layeredNavigation as $filters) {
+            foreach ($filters as $filter) {
+                $catalogCategoryView->getLayeredNavigationBlock()->clickFilterLink(
+                    $filter['title'],
+                    $filter['linkPattern']
+                );
+
+                $productNames = $this->getProductNames($filter['products']);
+                sort($productNames);
+                $pageProductNames = $catalogCategoryView->getListProductBlock()->getProductNames();
+                sort($pageProductNames);
+                \PHPUnit_Framework_Assert::assertEquals($productNames, $pageProductNames);
+            }
+            $catalogCategoryView->getLayeredNavigationBlock()->clearAll();
+        }
+    }
+
+    /**
+     * Get product names list by keys.
+     *
+     * @param string $productKeys
+     * @return array
+     */
+    protected function getProductNames($productKeys)
+    {
+        $keys = array_map('trim', explode(',', $productKeys));
+        $productNames = [];
+
+        foreach ($keys as $key) {
+            $key = str_replace('product_', '', $key);
+            $productNames[] = $this->products[$key]->getName();
+        }
+
+        return $productNames;
+    }
+
+    /**
+     * Returns a string representation of the object.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Filtered product list via layered navigation are displayed correctly.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/Page/Category/CatalogCategoryView.xml b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/Page/Category/CatalogCategoryView.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c3b68e9dd74ccab2655d9d8f307cb4c634e93dfd
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/Page/Category/CatalogCategoryView.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+ -->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/pages.xsd">
+    <page name="CatalogCategoryView" area="Category" mca="catalog/category/view" module="Magento_Catalog">
+        <block name="layeredNavigationBlock" class="Magento\LayeredNavigation\Test\Block\Navigation" locator=".block.filter" strategy="css selector"/>
+    </page>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/Repository/ConfigData.xml b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/Repository/ConfigData.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2005dd8bf0cef056edf502e01fd9554e68cb8e23
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/Repository/ConfigData.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/Magento/Mtf/Repository/etc/repository.xsd">
+    <repository class="Magento\Config\Test\Repository\ConfigData">
+        <dataset name="layered_navigation_manual_range_10">
+            <field name="catalog/layered_navigation/display_product_count" xsi:type="array">
+                <item name="scope" xsi:type="string">default</item>
+                <item name="scope_id" xsi:type="number">0</item>
+                <item name="value" label="Yes" xsi:type="string">1</item>
+            </field>
+            <field name="catalog/layered_navigation/price_range_calculation" xsi:type="array">
+                <item name="scope" xsi:type="string">default</item>
+                <item name="scope_id" xsi:type="number">0</item>
+                <item name="value" label="Manual" xsi:type="string">manual</item>
+            </field>
+            <field name="catalog/layered_navigation/price_range_step" xsi:type="array">
+                <item name="scope" xsi:type="string">default</item>
+                <item name="scope_id" xsi:type="number">0</item>
+                <item name="value" xsi:type="string">10</item>
+            </field>
+            <field name="catalog/layered_navigation/price_range_max_intervals" xsi:type="array">
+                <item name="scope" xsi:type="string">default</item>
+                <item name="scope_id" xsi:type="number">0</item>
+                <item name="value" xsi:type="string">10</item>
+            </field>
+        </dataset>
+        <dataset name="layered_navigation_manual_range_10_rollback">
+            <field name="catalog/layered_navigation/display_product_count" xsi:type="array">
+                <item name="scope" xsi:type="string">default</item>
+                <item name="scope_id" xsi:type="number">0</item>
+                <item name="value" label="Yes" xsi:type="string">1</item>
+            </field>
+            <field name="catalog/layered_navigation/price_range_calculation" xsi:type="array">
+                <item name="scope" xsi:type="string">default</item>
+                <item name="scope_id" xsi:type="number">0</item>
+                <item name="value" label="Automatic (equalize price ranges)" xsi:type="string">auto</item>
+            </field>
+        </dataset>
+    </repository>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/TestCase/FilterProductListTest.php b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/TestCase/FilterProductListTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..dea532e69cf26dfe81ce7bb3fa281bf26a077dd8
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/TestCase/FilterProductListTest.php
@@ -0,0 +1,73 @@
+<?php
+
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\LayeredNavigation\Test\TestCase;
+
+use Magento\Catalog\Test\Fixture\CatalogProductSimple;
+use Magento\Catalog\Test\Fixture\Category;
+use Magento\Mtf\TestCase\Injectable;
+
+/**
+ * Preconditions:
+ * 1. Setup Layered Navigation configuration.
+ *
+ * Steps:
+ * 1. Create category.
+ * 2. Create product with created category.
+ * 3. Perform all assertions.
+ *
+ * @group Layered_Navigation_(MX)
+ * @ZephyrId MAGETWO-12419
+ */
+class FilterProductListTest extends Injectable
+{
+    /* tags */
+    const DOMAIN = 'MX';
+    const TEST_TYPE = 'acceptance_test';
+    /* end tags */
+
+    /**
+     * Configuration setting.
+     *
+     * @var string
+     */
+    protected $configData;
+
+    /**
+     * Filtering product in the Frontend via layered navigation.
+     *
+     * @param string $configData
+     * @param Category $category
+     * @return array
+     */
+    public function test($configData, Category $category)
+    {
+        $this->configData = $configData;
+
+        // Preconditions
+        $this->objectManager->create(
+            'Magento\Config\Test\TestStep\SetupConfigurationStep',
+            ['configData' => $this->configData]
+        )->run();
+
+        // Steps
+        $category->persist();
+    }
+
+    /**
+     * Clean data after running test.
+     *
+     * @return void
+     */
+    public function tearDown()
+    {
+        $this->objectManager->create(
+            'Magento\Config\Test\TestStep\SetupConfigurationStep',
+            ['configData' => $this->configData, 'rollback' => true]
+        )->run();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/TestCase/FilterProductListTest.xml b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/TestCase/FilterProductListTest.xml
new file mode 100644
index 0000000000000000000000000000000000000000..4cfbc8d6397ff7d52133d0a2c70d129c06825b01
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/TestCase/FilterProductListTest.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+ -->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
+    <testCase name="Magento\LayeredNavigation\Test\TestCase\FilterProductListTest">
+        <variation name="FilterProductListTestVariation1">
+            <data name="configData" xsi:type="string">layered_navigation_manual_range_10</data>
+            <data name="category/dataSet" xsi:type="string">default_anchor_subcategory</data>
+            <data name="category/data/category_products/dataSet" xsi:type="string">catalogProductSimple::product_20_dollar, configurableProduct::filterable_two_options_with_zero_price</data>
+            <data name="layeredNavigation" xsi:type="array">
+                <item name="filters_0" xsi:type="array">
+                    <item name="0" xsi:type="array">
+                        <item name="title" xsi:type="string">Price</item>
+                        <item name="linkPattern" xsi:type="string">`^.+10\.00 - .+19\.99 1$`m</item>
+                        <item name="products" xsi:type="string">product_1</item>
+                    </item>
+                </item>
+                <item name="filters_1" xsi:type="array">
+                    <item name="0" xsi:type="array">
+                        <item name="title" xsi:type="string">attribute_dropdown</item>
+                        <item name="linkPattern" xsi:type="string">`^option_0_[0-9]+ 1$`m</item>
+                        <item name="products" xsi:type="string">product_1</item>
+                    </item>
+                </item>
+            </data>
+            <data name="tag" xsi:type="string">test_type:acceptance_test</data>
+            <constraint name="Magento\Catalog\Test\Constraint\AssertCategoryForAssignedProducts" />
+            <constraint name="Magento\LayeredNavigation\Test\Constraint\AssertFilterProductList" />
+        </variation>
+    </testCase>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Edit/CustomerForm.xml b/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Edit/CustomerForm.xml
index c7a99a1c233ca0d32fb2e2703edf7b4c7f502484..32892c7138a7989b8d85d8c1092b80464054946c 100644
--- a/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Edit/CustomerForm.xml
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Edit/CustomerForm.xml
@@ -8,7 +8,7 @@
 <tabs>
     <product_reviews>
         <class>\Magento\Review\Test\Block\Adminhtml\Customer\Edit\Tab\Reviews</class>
-        <selector>#tab_reviews</selector>
+        <selector>#tab_block_reviews</selector>
         <strategy>css selector</strategy>
     </product_reviews>
 </tabs>
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create/Coupons.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create/Coupons.php
index e118bac1958fb0b3c9d0906bdafe181e157a9a7b..0a350725839b9e8833b90dda8003c051b0c7293c 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create/Coupons.php
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create/Coupons.php
@@ -7,7 +7,7 @@
 namespace Magento\Sales\Test\Block\Adminhtml\Order\Create;
 
 use Magento\Backend\Test\Block\Widget\Form;
-use Magento\SalesRule\Test\Fixture\SalesRuleInjectable;
+use Magento\SalesRule\Test\Fixture\SalesRule;
 use Magento\Mtf\Client\Locator;
 
 /**
@@ -32,10 +32,10 @@ class Coupons extends Form
     /**
      * Enter discount code and click apply button.
      *
-     * @param SalesRuleInjectable $code
+     * @param SalesRule $code
      * @return void
      */
-    public function applyCouponCode(SalesRuleInjectable $code)
+    public function applyCouponCode(SalesRule $code)
     {
         $this->_rootElement->find($this->couponCode)->setValue($code->getCouponCode());
         $this->_rootElement->find($this->applyButton, Locator::SELECTOR_XPATH)->click();
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Fixture/OrderInjectable/CouponCode.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Fixture/OrderInjectable/CouponCode.php
index b3d081c56d4c759fe4728523de1732c42f1477d0..0a28aff4f63e99585c420f30ca03fcd9031e1a4e 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/Fixture/OrderInjectable/CouponCode.php
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Fixture/OrderInjectable/CouponCode.php
@@ -6,7 +6,7 @@
 
 namespace Magento\Sales\Test\Fixture\OrderInjectable;
 
-use Magento\SalesRule\Test\Fixture\SalesRuleInjectable;
+use Magento\SalesRule\Test\Fixture\SalesRule;
 use Magento\Mtf\Fixture\FixtureFactory;
 use Magento\Mtf\Fixture\DataSource;
 
@@ -24,12 +24,12 @@ class CouponCode extends DataSource
     public function __construct(FixtureFactory $fixtureFactory, array $data, array $params = [])
     {
         $this->params = $params;
-        if (isset($data['value']) && $data['value'] instanceof SalesRuleInjectable) {
+        if (isset($data['value']) && $data['value'] instanceof SalesRule) {
             $this->data = $data['value'];
             return;
         }
         if (isset($data['dataSet'])) {
-            $salesRule = $fixtureFactory->createByCode('salesRuleInjectable', ['dataSet' => $data['dataSet']]);
+            $salesRule = $fixtureFactory->createByCode('salesRule', ['dataSet' => $data['dataSet']]);
             $salesRule->persist();
             $this->data = $salesRule;
         }
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Handler/OrderInjectable/Curl.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Handler/OrderInjectable/Curl.php
index e98f4ba0afff567f479384c0c7eaecef6543505d..7d993cb5f0094f6f9c9982314b44c83240402f88 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/Handler/OrderInjectable/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Handler/OrderInjectable/Curl.php
@@ -11,7 +11,7 @@ use Magento\ConfigurableProduct\Test\Fixture\ConfigurableProduct;
 use Magento\Customer\Test\Fixture\Customer;
 use Magento\Downloadable\Test\Fixture\DownloadableProduct;
 use Magento\Sales\Test\Fixture\OrderInjectable;
-use Magento\SalesRule\Test\Fixture\SalesRuleInjectable;
+use Magento\SalesRule\Test\Fixture\SalesRule;
 use Magento\Mtf\Fixture\FixtureInterface;
 use Magento\Mtf\Handler\Curl as AbstractCurl;
 use Magento\Mtf\Util\Protocol\CurlInterface;
@@ -111,10 +111,10 @@ class Curl extends AbstractCurl implements OrderInjectableInterface
     /**
      * Prepare coupon data.
      *
-     * @param SalesRuleInjectable $data
+     * @param SalesRule $data
      * @return array
      */
-    protected function prepareCouponCode(SalesRuleInjectable $data)
+    protected function prepareCouponCode(SalesRule $data)
     {
         return ['order' => ['coupon' => ['code' => $data->getCouponCode()]]];
     }
diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Constraint/AssertCartPriceRuleApplying.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Constraint/AssertCartPriceRuleApplying.php
index 1b573901d93ca029d529bf6c812e436b43d0ee05..a9307ce8132134ef2b9fde5dd5aa3e2f43aaffdd 100644
--- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Constraint/AssertCartPriceRuleApplying.php
+++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Constraint/AssertCartPriceRuleApplying.php
@@ -15,7 +15,7 @@ use Magento\Customer\Test\Fixture\Address;
 use Magento\Customer\Test\Fixture\Customer;
 use Magento\Customer\Test\Page\CustomerAccountLogin;
 use Magento\Customer\Test\Page\CustomerAccountLogout;
-use Magento\SalesRule\Test\Fixture\SalesRuleInjectable;
+use Magento\SalesRule\Test\Fixture\SalesRule;
 use Magento\Mtf\Constraint\AbstractConstraint;
 
 /**
@@ -121,8 +121,8 @@ abstract class AssertCartPriceRuleApplying extends AbstractConstraint
      * @param CatalogCategoryView $catalogCategoryView
      * @param CatalogProductView $catalogProductView
      * @param Customer $customer
-     * @param SalesRuleInjectable $salesRule
-     * @param SalesRuleInjectable $salesRuleOrigin
+     * @param SalesRule $salesRule
+     * @param SalesRule $salesRuleOrigin
      * @param array $productQuantity
      * @param CatalogProductSimple $productForSalesRule1
      * @param CatalogProductSimple $productForSalesRule2
@@ -141,8 +141,8 @@ abstract class AssertCartPriceRuleApplying extends AbstractConstraint
         CatalogCategoryView $catalogCategoryView,
         CatalogProductView $catalogProductView,
         Customer $customer,
-        SalesRuleInjectable $salesRule,
-        SalesRuleInjectable $salesRuleOrigin,
+        SalesRule $salesRule,
+        SalesRule $salesRuleOrigin,
         array $productQuantity,
         CatalogProductSimple $productForSalesRule1,
         CatalogProductSimple $productForSalesRule2 = null,
diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Constraint/AssertCartPriceRuleForm.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Constraint/AssertCartPriceRuleForm.php
index ccd77f877ced270b43d7bcc9f2081422676f0b58..d8a6445267051487c7f813a13dc62be1c8fd6981 100644
--- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Constraint/AssertCartPriceRuleForm.php
+++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Constraint/AssertCartPriceRuleForm.php
@@ -6,7 +6,7 @@
 
 namespace Magento\SalesRule\Test\Constraint;
 
-use Magento\SalesRule\Test\Fixture\SalesRuleInjectable;
+use Magento\SalesRule\Test\Fixture\SalesRule;
 use Magento\SalesRule\Test\Page\Adminhtml\PromoQuoteEdit;
 use Magento\SalesRule\Test\Page\Adminhtml\PromoQuoteIndex;
 use Magento\Mtf\Constraint\AbstractConstraint;
@@ -34,15 +34,15 @@ class AssertCartPriceRuleForm extends AbstractConstraint
      *
      * @param PromoQuoteIndex $promoQuoteIndex
      * @param PromoQuoteEdit $promoQuoteEdit
-     * @param SalesRuleInjectable $salesRule
-     * @param SalesRuleInjectable $salesRuleOrigin
+     * @param SalesRule $salesRule
+     * @param SalesRule $salesRuleOrigin
      * @return void
      */
     public function processAssert(
         PromoQuoteIndex $promoQuoteIndex,
         PromoQuoteEdit $promoQuoteEdit,
-        SalesRuleInjectable $salesRule,
-        SalesRuleInjectable $salesRuleOrigin = null
+        SalesRule $salesRule,
+        SalesRule $salesRuleOrigin = null
     ) {
         $filter = [
             'name' => $salesRule->hasData('name') ? $salesRule->getName() : $salesRuleOrigin->getName(),
diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Constraint/AssertCartPriceRuleIsNotPresentedInGrid.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Constraint/AssertCartPriceRuleIsNotPresentedInGrid.php
index 4c2fd8856a08fdd1af69c5594124fef9443166f4..a0914721420c86595f74dd6b16a487175e935d74 100644
--- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Constraint/AssertCartPriceRuleIsNotPresentedInGrid.php
+++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Constraint/AssertCartPriceRuleIsNotPresentedInGrid.php
@@ -6,7 +6,7 @@
 
 namespace Magento\SalesRule\Test\Constraint;
 
-use Magento\SalesRule\Test\Fixture\SalesRuleInjectable;
+use Magento\SalesRule\Test\Fixture\SalesRule;
 use Magento\SalesRule\Test\Page\Adminhtml\PromoQuoteIndex;
 use Magento\Mtf\Constraint\AbstractConstraint;
 
@@ -19,10 +19,10 @@ class AssertCartPriceRuleIsNotPresentedInGrid extends AbstractConstraint
      * Assert that sales rule is not present in cart price rules grid.
      *
      * @param PromoQuoteIndex $promoQuoteIndex
-     * @param SalesRuleInjectable $salesRule
+     * @param SalesRule $salesRule
      * @return void
      */
-    public function processAssert(PromoQuoteIndex $promoQuoteIndex, SalesRuleInjectable $salesRule)
+    public function processAssert(PromoQuoteIndex $promoQuoteIndex, SalesRule $salesRule)
     {
         \PHPUnit_Framework_Assert::assertFalse(
             $promoQuoteIndex->getPromoQuoteGrid()->isRowVisible(['name' => $salesRule->getName()]),
diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Fixture/SalesRuleInjectable.xml b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Fixture/SalesRule.xml
similarity index 90%
rename from dev/tests/functional/tests/app/Magento/SalesRule/Test/Fixture/SalesRuleInjectable.xml
rename to dev/tests/functional/tests/app/Magento/SalesRule/Test/Fixture/SalesRule.xml
index 25f432794e8432456a08e315988cfe84f60525fb..9008a93b8a36b6f82c5115afc176f113495742bc 100644
--- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Fixture/SalesRuleInjectable.xml
+++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Fixture/SalesRule.xml
@@ -6,7 +6,7 @@
  */
  -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
-    <fixture name="salesRuleInjectable" module="Magento_SalesRule" type="flat" entity_type="salesrule" collection="Magento\SalesRule\Model\Resource\Rule\Collection" repository_class="Magento\SalesRule\Test\Repository\SalesRuleInjectable" handler_interface="Magento\SalesRule\Test\Handler\SalesRuleInjectable\SalesRuleInjectableInterface" class="Magento\SalesRule\Test\Fixture\SalesRuleInjectable">
+    <fixture name="salesRule" module="Magento_SalesRule" type="flat" entity_type="salesrule" collection="Magento\SalesRule\Model\Resource\Rule\Collection" repository_class="Magento\SalesRule\Test\Repository\SalesRule" handler_interface="Magento\SalesRule\Test\Handler\SalesRule\SalesRuleInterface" class="Magento\SalesRule\Test\Fixture\SalesRule">
         <dataset name="default">
             <field name="name" xsi:type="string">Default price rule %isolation%</field>
             <field name="is_active" xsi:type="string">Active</field>
@@ -36,7 +36,7 @@
         <field name="is_active" group="rule_information">
             <default_value xsi:type="string">Active</default_value>
         </field>
-        <field name="conditions_serialized" group="conditions" source="Magento\SalesRule\Test\Fixture\SalesRuleInjectable\ConditionsSerialized" />
+        <field name="conditions_serialized" group="conditions" source="Magento\SalesRule\Test\Fixture\SalesRule\ConditionsSerialized" />
         <field name="actions_serialized" group="actions" />
         <field name="stop_rules_processing" group="actions">
             <default_value xsi:type="string">1</default_value>
diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Fixture/SalesRuleInjectable/ConditionsSerialized.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Fixture/SalesRule/ConditionsSerialized.php
similarity index 94%
rename from dev/tests/functional/tests/app/Magento/SalesRule/Test/Fixture/SalesRuleInjectable/ConditionsSerialized.php
rename to dev/tests/functional/tests/app/Magento/SalesRule/Test/Fixture/SalesRule/ConditionsSerialized.php
index 4d9c65cff5333e179f7dc06f72f857f5da9baf54..d323abf4b46bd36de6a57e976c5bf1f7c8fa384d 100644
--- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Fixture/SalesRuleInjectable/ConditionsSerialized.php
+++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Fixture/SalesRule/ConditionsSerialized.php
@@ -4,7 +4,7 @@
  * See COPYING.txt for license details.
  */
 
-namespace Magento\SalesRule\Test\Fixture\SalesRuleInjectable;
+namespace Magento\SalesRule\Test\Fixture\SalesRule;
 
 use Magento\Mtf\Fixture\DataSource;
 
diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Handler/SalesRuleInjectable/Curl.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Handler/SalesRule/Curl.php
similarity index 97%
rename from dev/tests/functional/tests/app/Magento/SalesRule/Test/Handler/SalesRuleInjectable/Curl.php
rename to dev/tests/functional/tests/app/Magento/SalesRule/Test/Handler/SalesRule/Curl.php
index 2543ccdf8197195b9cdbdc2bdb6444ef5903a784..d1c4bdee2f717d441fa26222e1eeea5045072894 100644
--- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Handler/SalesRuleInjectable/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Handler/SalesRule/Curl.php
@@ -4,7 +4,7 @@
  * See COPYING.txt for license details.
  */
 
-namespace Magento\SalesRule\Test\Handler\SalesRuleInjectable;
+namespace Magento\SalesRule\Test\Handler\SalesRule;
 
 use Magento\Backend\Test\Handler\Conditions;
 use Magento\Mtf\Fixture\FixtureInterface;
@@ -15,7 +15,7 @@ use Magento\Mtf\Util\Protocol\CurlTransport\BackendDecorator;
 /**
  * Curl handler for creating sales rule.
  */
-class Curl extends Conditions implements SalesRuleInjectableInterface
+class Curl extends Conditions implements SalesRuleInterface
 {
     /**
      * Map of type parameter.
diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Handler/SalesRuleInjectable/SalesRuleInjectableInterface.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Handler/SalesRule/SalesRuleInterface.php
similarity index 61%
rename from dev/tests/functional/tests/app/Magento/SalesRule/Test/Handler/SalesRuleInjectable/SalesRuleInjectableInterface.php
rename to dev/tests/functional/tests/app/Magento/SalesRule/Test/Handler/SalesRule/SalesRuleInterface.php
index 0a9c2598e8c49b16841c1efd0fda60e4d1d1d248..d638e854cf27339db2118d4ea9c9f5980ce3139b 100644
--- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Handler/SalesRuleInjectable/SalesRuleInjectableInterface.php
+++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Handler/SalesRule/SalesRuleInterface.php
@@ -4,14 +4,14 @@
  * See COPYING.txt for license details.
  */
 
-namespace Magento\SalesRule\Test\Handler\SalesRuleInjectable;
+namespace Magento\SalesRule\Test\Handler\SalesRule;
 
 use Magento\Mtf\Handler\HandlerInterface;
 
 /**
  * Interface SalesRuleInterface.
  */
-interface SalesRuleInjectableInterface extends HandlerInterface
+interface SalesRuleInterface extends HandlerInterface
 {
     //
 }
diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Repository/SalesRuleInjectable.xml b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Repository/SalesRule.xml
similarity index 99%
rename from dev/tests/functional/tests/app/Magento/SalesRule/Test/Repository/SalesRuleInjectable.xml
rename to dev/tests/functional/tests/app/Magento/SalesRule/Test/Repository/SalesRule.xml
index 02d81f565a253de17ec04662a14bf162c330b256..897aa57c1bf7ff47a3b61b9d51e4b8782966a8ee 100644
--- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Repository/SalesRuleInjectable.xml
+++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Repository/SalesRule.xml
@@ -6,7 +6,7 @@
  */
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/Magento/Mtf/Repository/etc/repository.xsd">
-    <repository class="Magento\SalesRule\Test\Repository\SalesRuleInjectable">
+    <repository class="Magento\SalesRule\Test\Repository\SalesRule">
         <dataset name="active_sales_rule_with_percent_price_discount_coupon">
             <field name="name" xsi:type="string">Shopping Cart Price Rule with Specific Coupon %isolation%</field>
             <field name="description" xsi:type="string">Description for Cart Price Rule</field>
diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/CreateSalesRuleEntityTest.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/CreateSalesRuleEntityTest.php
index 24bafea36fbe42b87673f83accf39b5a70ddc666..e82c3e9bcc2c216a1185d1cb3c77f0ac9d5d6124 100644
--- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/CreateSalesRuleEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/CreateSalesRuleEntityTest.php
@@ -6,7 +6,7 @@
 
 namespace Magento\SalesRule\Test\TestCase;
 
-use Magento\SalesRule\Test\Fixture\SalesRuleInjectable;
+use Magento\SalesRule\Test\Fixture\SalesRule;
 use Magento\SalesRule\Test\Page\Adminhtml\PromoQuoteEdit;
 use Magento\SalesRule\Test\Page\Adminhtml\PromoQuoteIndex;
 use Magento\SalesRule\Test\Page\Adminhtml\PromoQuoteNew;
@@ -115,10 +115,10 @@ class CreateSalesRuleEntityTest extends Injectable
     /**
      * Create Sales Rule Entity.
      *
-     * @param SalesRuleInjectable $salesRule
+     * @param SalesRule $salesRule
      * @return void
      */
-    public function testCreateSalesRule(SalesRuleInjectable $salesRule)
+    public function testCreateSalesRule(SalesRule $salesRule)
     {
         // Preconditions
         $this->salesRuleName = $salesRule->getName();
diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/DeleteSalesRuleEntityTest.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/DeleteSalesRuleEntityTest.php
index 49f3e7655790d8cf6ec4842d2861cc55692e5a72..3dcf7ad8e3a6df646e81ade107440b57c8587887 100644
--- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/DeleteSalesRuleEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/DeleteSalesRuleEntityTest.php
@@ -6,7 +6,7 @@
 
 namespace Magento\SalesRule\Test\TestCase;
 
-use Magento\SalesRule\Test\Fixture\SalesRuleInjectable;
+use Magento\SalesRule\Test\Fixture\SalesRule;
 use Magento\SalesRule\Test\Page\Adminhtml\PromoQuoteEdit;
 use Magento\SalesRule\Test\Page\Adminhtml\PromoQuoteIndex;
 use Magento\Mtf\TestCase\Injectable;
@@ -63,10 +63,10 @@ class DeleteSalesRuleEntityTest extends Injectable
     /**
      * Delete Sales Rule Entity.
      *
-     * @param SalesRuleInjectable $salesRule
+     * @param SalesRule $salesRule
      * @return void
      */
-    public function testDeleteSalesRule(SalesRuleInjectable $salesRule)
+    public function testDeleteSalesRule(SalesRule $salesRule)
     {
         // Preconditions
         $salesRule->persist();
diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/UpdateSalesRuleEntityTest.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/UpdateSalesRuleEntityTest.php
index ed72d923f05b1911611a38244d9f5e2b79c5d669..93e0e862805255e0f86bb8ccd131382acc2c280f 100644
--- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/UpdateSalesRuleEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/UpdateSalesRuleEntityTest.php
@@ -6,7 +6,7 @@
 
 namespace Magento\SalesRule\Test\TestCase;
 
-use Magento\SalesRule\Test\Fixture\SalesRuleInjectable;
+use Magento\SalesRule\Test\Fixture\SalesRule;
 use Magento\SalesRule\Test\Page\Adminhtml\PromoQuoteEdit;
 use Magento\SalesRule\Test\Page\Adminhtml\PromoQuoteIndex;
 use Magento\Mtf\Fixture\FixtureFactory;
@@ -92,13 +92,13 @@ class UpdateSalesRuleEntityTest extends Injectable
     /**
      * Update Sales Rule Entity.
      *
-     * @param SalesRuleInjectable $salesRule
-     * @param SalesRuleInjectable $salesRuleOrigin
+     * @param SalesRule $salesRule
+     * @param SalesRule $salesRuleOrigin
      * @return void
      */
     public function testUpdateSalesRule(
-        SalesRuleInjectable $salesRule,
-        SalesRuleInjectable $salesRuleOrigin
+        SalesRule $salesRule,
+        SalesRule $salesRuleOrigin
     ) {
         // Preconditions
         $salesRuleOrigin->persist();
diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestStep/ApplySalesRuleOnBackendStep.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestStep/ApplySalesRuleOnBackendStep.php
index 7e193a4d0ab1cc570bbbebad6dedda8c57946c6d..709e2c1644b71675224dc3941c2e4d7a1bc3ff7e 100644
--- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestStep/ApplySalesRuleOnBackendStep.php
+++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestStep/ApplySalesRuleOnBackendStep.php
@@ -7,7 +7,7 @@
 namespace Magento\SalesRule\Test\TestStep;
 
 use Magento\Sales\Test\Page\Adminhtml\OrderCreateIndex;
-use Magento\SalesRule\Test\Fixture\SalesRuleInjectable;
+use Magento\SalesRule\Test\Fixture\SalesRule;
 use Magento\Mtf\TestStep\TestStepInterface;
 
 /**
@@ -25,16 +25,16 @@ class ApplySalesRuleOnBackendStep implements TestStepInterface
     /**
      * SalesRule fixture.
      *
-     * @var SalesRuleInjectable
+     * @var SalesRule
      */
     protected $salesRule;
 
     /**
      * @constructor
      * @param OrderCreateIndex $orderCreateIndex
-     * @param SalesRuleInjectable $salesRule
+     * @param SalesRule $salesRule
      */
-    public function __construct(OrderCreateIndex $orderCreateIndex, SalesRuleInjectable $salesRule = null)
+    public function __construct(OrderCreateIndex $orderCreateIndex, SalesRule $salesRule = null)
     {
         $this->orderCreateIndex = $orderCreateIndex;
         $this->salesRule = $salesRule;
diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestStep/ApplySalesRuleOnFrontendStep.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestStep/ApplySalesRuleOnFrontendStep.php
index 6bff54ec11dee9b17a78f52478fff86e8652457d..49fedf0d5d16dd7b214105d42fb4cab24e55aaa8 100644
--- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestStep/ApplySalesRuleOnFrontendStep.php
+++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestStep/ApplySalesRuleOnFrontendStep.php
@@ -7,7 +7,7 @@
 namespace Magento\SalesRule\Test\TestStep;
 
 use Magento\Checkout\Test\Page\CheckoutCart;
-use Magento\SalesRule\Test\Fixture\SalesRuleInjectable;
+use Magento\SalesRule\Test\Fixture\SalesRule;
 use Magento\Mtf\TestStep\TestStepInterface;
 
 /**
@@ -25,16 +25,16 @@ class ApplySalesRuleOnFrontendStep implements TestStepInterface
     /**
      * SalesRule fixture.
      *
-     * @var SalesRuleInjectable
+     * @var SalesRule
      */
     protected $salesRule;
 
     /**
      * @constructor
      * @param CheckoutCart $checkoutCart
-     * @param SalesRuleInjectable $salesRule
+     * @param SalesRule $salesRule
      */
-    public function __construct(CheckoutCart $checkoutCart, SalesRuleInjectable $salesRule = null)
+    public function __construct(CheckoutCart $checkoutCart, SalesRule $salesRule = null)
     {
         $this->checkoutCart = $checkoutCart;
         $this->salesRule = $salesRule;
diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestStep/CreateSalesRuleStep.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestStep/CreateSalesRuleStep.php
index c458bed8659ad8e8b3d2d381a1601ecfade3e163..bda908faf26778fa05dfb90b4dac909a3d6d4902 100644
--- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestStep/CreateSalesRuleStep.php
+++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestStep/CreateSalesRuleStep.php
@@ -51,7 +51,7 @@ class CreateSalesRuleStep implements TestStepInterface
         $result['salesRule'] = null;
         if ($this->salesRule !== null) {
             $salesRule = $this->fixtureFactory->createByCode(
-                'salesRuleInjectable',
+                'salesRule',
                 ['dataSet' => $this->salesRule]
             );
             $salesRule->persist();
diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestStep/DeleteAllSalesRuleStep.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestStep/DeleteAllSalesRuleStep.php
index 0141a0506fd6e926987234027c894c7462c01245..98bf51e84f7c37fa0c7cf86af5024e0f7ceefe72 100644
--- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestStep/DeleteAllSalesRuleStep.php
+++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestStep/DeleteAllSalesRuleStep.php
@@ -50,6 +50,7 @@ class DeleteAllSalesRuleStep implements TestStepInterface
     public function run()
     {
         $this->promoQuoteIndex->open();
+        $this->promoQuoteIndex->getPromoQuoteGrid()->resetFilter();
         while ($this->promoQuoteIndex->getPromoQuoteGrid()->isFirstRowVisible()) {
             $this->promoQuoteIndex->getPromoQuoteGrid()->openFirstRow();
             $this->promoQuoteEdit->getFormPageActions()->delete();
diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/etc/curl/di.xml b/dev/tests/functional/tests/app/Magento/SalesRule/Test/etc/curl/di.xml
index 2591249e9e02850c5123b9c66a0652a7bd5cfa00..3416929d0ab44031cbb7bef4b0d3ac7628cf9139 100644
--- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/etc/curl/di.xml
+++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/etc/curl/di.xml
@@ -6,5 +6,5 @@
  */
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
-    <preference for="Magento\SalesRule\Test\Handler\SalesRuleInjectable\SalesRuleInjectableInterface" type="\Magento\SalesRule\Test\Handler\SalesRuleInjectable\Curl" />
+    <preference for="Magento\SalesRule\Test\Handler\SalesRule\SalesRuleInterface" type="\Magento\SalesRule\Test\Handler\SalesRule\Curl" />
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRuleApplying.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRuleApplying.php
index b5631910c0d44a00f93df89cc540b56734348c1a..51476690a8897b2f9b745dc46fbab9c4a12a1955 100644
--- a/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRuleApplying.php
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRuleApplying.php
@@ -11,15 +11,12 @@ use Magento\Catalog\Test\Page\Product\CatalogProductView;
 use Magento\Checkout\Test\Page\CheckoutCart;
 use Magento\Customer\Test\Fixture\Address;
 use Magento\Customer\Test\Fixture\Customer;
-use Magento\Customer\Test\Page\CustomerAccountLogin;
-use Magento\Customer\Test\Page\CustomerAccountLogout;
 use Magento\Tax\Test\Fixture\TaxRule;
 use Magento\Mtf\Client\BrowserInterface;
 use Magento\Mtf\Constraint\AbstractConstraint;
 use Magento\Mtf\Fixture\FixtureFactory;
 
 /**
- * Class AssertTaxRuleApplying
  * Abstract class for implementing assert applying
  */
 abstract class AssertTaxRuleApplying extends AbstractConstraint
@@ -82,8 +79,6 @@ abstract class AssertTaxRuleApplying extends AbstractConstraint
      *
      * @param FixtureFactory $fixtureFactory
      * @param TaxRule $taxRule
-     * @param CustomerAccountLogin $customerAccountLogin
-     * @param CustomerAccountLogout $customerAccountLogout
      * @param Customer $customer
      * @param CatalogProductView $catalogProductView
      * @param CheckoutCart $checkoutCart
@@ -92,14 +87,10 @@ abstract class AssertTaxRuleApplying extends AbstractConstraint
      * @param BrowserInterface $browser
      * @param TaxRule $initialTaxRule
      * @return void
-     *
-     * @SuppressWarnings(PHPMD.ExcessiveParameterList)
      */
     public function processAssert(
         FixtureFactory $fixtureFactory,
         TaxRule $taxRule,
-        CustomerAccountLogin $customerAccountLogin,
-        CustomerAccountLogout $customerAccountLogout,
         Customer $customer,
         CatalogProductView $catalogProductView,
         CheckoutCart $checkoutCart,
@@ -134,9 +125,10 @@ abstract class AssertTaxRuleApplying extends AbstractConstraint
         );
         $this->productSimple->persist();
         // Customer login
-        $customerAccountLogout->open();
-        $customerAccountLogin->open();
-        $customerAccountLogin->getLoginBlock()->login($customer);
+        $this->objectManager->create(
+            'Magento\Customer\Test\TestStep\LoginCustomerOnFrontendStep',
+            ['customer' => $customer]
+        )->run();
         // Clearing shopping cart and adding product to shopping cart
         $checkoutCart->open()->getCartBlock()->clearShoppingCart();
         $browser->open($_ENV['app_frontend_url'] . $this->productSimple->getUrlKey() . '.html');
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxCalculationTest.php b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxCalculationTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..ddfd3ab0508cc3a90986eada1db016a526ba921e
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxCalculationTest.php
@@ -0,0 +1,75 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Tax\Test\TestCase;
+
+use Magento\Mtf\TestCase\Scenario;
+use Magento\Mtf\ObjectManager;
+
+/**
+ * Steps:
+ * 1. Log in as default admin user.
+ * 2. Go to Stores > Taxes > Tax Rules.
+ * 3. Click 'Add New Tax Rule' button.
+ * 4. Assign default rates to rule.
+ * 5. Save Tax Rate.
+ * 6. Go to Products > Catalog.
+ * 7. Add new product.
+ * 8. Fill data according to dataset.
+ * 9. Save product.
+ * 10. Go to Stores > Configuration.
+ * 11. Fill Tax configuration according to data set.
+ * 12. Save tax configuration.
+ * 13. Perform all assertions.
+ *
+ * @group Tax_(CS)
+ * @ZephyrId MAGETWO-27809
+ */
+class TaxCalculationTest extends Scenario
+{
+    /* tags */
+    const MVP = 'yes';
+    const DOMAIN = 'CS';
+    /* end tags */
+
+    /**
+     * Skip failed tests.
+     *
+     * @return void
+     */
+    public static function setUpBeforeClass()
+    {
+        self::markTestIncomplete("Epic: MAGETWO-30073");
+    }
+
+    /**
+     * Runs tax calculation test.
+     *
+     * @return void
+     */
+    public function test()
+    {
+        $this->executeScenario();
+    }
+
+    /**
+     * Tear down after each test.
+     *
+     * @return void
+     */
+    public function tearDown()
+    {
+        $this->objectManager->create('\Magento\Tax\Test\TestStep\DeleteAllTaxRulesStep')->run();
+        $this->objectManager->create('\Magento\SalesRule\Test\TestStep\DeleteAllSalesRuleStep')->run();
+        $this->objectManager->create('\Magento\CatalogRule\Test\TestStep\DeleteAllCatalogRulesStep')->run();
+
+        // TODO: Move set default configuration to "tearDownAfterClass" method after fix bug MAGETWO-29331
+        $this->objectManager->create(
+            'Magento\Config\Test\TestStep\SetupConfigurationStep',
+            ['configData' => 'default_tax_configuration']
+        )->run();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxCalculationTest.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxCalculationTest.xml
new file mode 100644
index 0000000000000000000000000000000000000000..9891afcdf2d0fa727302f3c047f08bea83beb05f
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxCalculationTest.xml
@@ -0,0 +1,301 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+ -->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
+    <testCase name="Magento\Tax\Test\TestCase\TaxCalculationTest">
+        <variation name="TaxCalculationTestVariation1">
+            <data name="description" xsi:type="string">Simple product tier price with sales rule, customer tax equals store tax and catalog price including tax</data>
+            <data name="configData" xsi:type="string">row_cat_incl_ship_excl_after_disc_on_excl, display_excluding_including_tax</data>
+            <data name="product" xsi:type="string">catalogProductSimple::simple_with_tier_price_and_category</data>
+            <data name="salesRule" xsi:type="string">active_sales_rule_for_all_groups_no_coupon</data>
+            <data name="catalogRule" xsi:type="string">-</data>
+            <data name="taxRule" xsi:type="string">customer_equals_store_rate</data>
+            <data name="customer/dataSet" xsi:type="string">johndoe_unique</data>
+            <data name="qty" xsi:type="string">3</data>
+            <data name="prices/category_price_excl_tax" xsi:type="string">277.14</data>
+            <data name="prices/category_price_incl_tax" xsi:type="string">300.00</data>
+            <data name="prices/product_view_price_excl_tax" xsi:type="string">277.14</data>
+            <data name="prices/product_view_price_incl_tax" xsi:type="string">300.00</data>
+            <data name="prices/cart_item_price_excl_tax" xsi:type="string">13.86</data>
+            <data name="prices/cart_item_price_incl_tax" xsi:type="string">15.00</data>
+            <data name="prices/cart_item_subtotal_excl_tax" xsi:type="string">41.57</data>
+            <data name="prices/cart_item_subtotal_incl_tax" xsi:type="string">45.00</data>
+            <data name="prices/subtotal_excl_tax" xsi:type="string">41.57</data>
+            <data name="prices/subtotal_incl_tax" xsi:type="string">45.00</data>
+            <data name="prices/discount" xsi:type="string">20.79</data>
+            <data name="prices/shipping_excl_tax" xsi:type="string">15.00</data>
+            <data name="prices/shipping_incl_tax" xsi:type="string">16.24</data>
+            <data name="prices/tax" xsi:type="string">3.09</data>
+            <data name="prices/grand_total_excl_tax" xsi:type="string">37.36</data>
+            <data name="prices/grand_total_incl_tax" xsi:type="string">40.45</data>
+            <constraint name="Magento\Tax\Test\Constraint\AssertTaxRuleIsAppliedToAllPricesExcludingIncludingTax" />
+            <constraint name="Magento\Tax\Test\Constraint\AssertTaxCalculationAfterCheckoutExcludingIncludingTax" />
+            <constraint name="Magento\Tax\Test\Constraint\AssertOrderTaxOnBackendExcludingIncludingTax" />
+        </variation>
+        <variation name="TaxCalculationTestVariation2">
+            <data name="description" xsi:type="string">Simple product group price with sales rule, customer tax greater than store tax and catalog price excluding tax</data>
+            <data name="configData" xsi:type="string">row_cat_excl_ship_incl_before_disc_on_incl, display_excluding_including_tax</data>
+            <data name="product" xsi:type="string">catalogProductSimple::simple_with_group_price_and_category</data>
+            <data name="salesRule" xsi:type="string">active_sales_rule_for_all_groups_no_coupon</data>
+            <data name="catalogRule" xsi:type="string">-</data>
+            <data name="taxRule" xsi:type="string">customer_greater_store_rate</data>
+            <data name="customer/dataSet" xsi:type="string">johndoe_unique</data>
+            <data name="qty" xsi:type="string">3</data>
+            <data name="prices/category_price_excl_tax" xsi:type="string">90.99</data>
+            <data name="prices/category_price_incl_tax" xsi:type="string">98.61</data>
+            <data name="prices/product_view_price_excl_tax" xsi:type="string">90.99</data>
+            <data name="prices/product_view_price_incl_tax" xsi:type="string">98.61</data>
+            <data name="prices/cart_item_price_excl_tax" xsi:type="string">90.99</data>
+            <data name="prices/cart_item_price_incl_tax" xsi:type="string">98.61</data>
+            <data name="prices/cart_item_subtotal_excl_tax" xsi:type="string">272.97</data>
+            <data name="prices/cart_item_subtotal_incl_tax" xsi:type="string">295.83</data>
+            <data name="prices/subtotal_excl_tax" xsi:type="string">272.97</data>
+            <data name="prices/subtotal_incl_tax" xsi:type="string">295.83</data>
+            <data name="prices/discount" xsi:type="string">147.92</data>
+            <data name="prices/shipping_excl_tax" xsi:type="string">13.86</data>
+            <data name="prices/shipping_incl_tax" xsi:type="string">15.02</data>
+            <data name="prices/tax" xsi:type="string">24.02</data>
+            <data name="prices/grand_total_excl_tax" xsi:type="string">138.91</data>
+            <data name="prices/grand_total_incl_tax" xsi:type="string">162.93</data>
+            <constraint name="Magento\Tax\Test\Constraint\AssertTaxRuleIsAppliedToAllPricesExcludingIncludingTax" />
+            <constraint name="Magento\Tax\Test\Constraint\AssertTaxCalculationAfterCheckoutExcludingIncludingTax" />
+            <constraint name="Magento\Tax\Test\Constraint\AssertOrderTaxOnBackendExcludingIncludingTax" />
+        </variation>
+        <variation name="TaxCalculationTestVariation3">
+            <data name="description" xsi:type="string">Simple product group price with sales rule, customer tax less than store tax and catalog price excluding tax</data>
+            <data name="configData" xsi:type="string">total_cat_excl_ship_incl_after_disc_on_excl, display_excluding_including_tax</data>
+            <data name="product" xsi:type="string">catalogProductSimple::simple_with_group_price_and_category</data>
+            <data name="salesRule" xsi:type="string">active_sales_rule_for_all_groups_no_coupon</data>
+            <data name="catalogRule" xsi:type="string">-</data>
+            <data name="taxRule" xsi:type="string">customer_less_store_rate</data>
+            <data name="customer/dataSet" xsi:type="string">johndoe_unique</data>
+            <data name="qty" xsi:type="string">3</data>
+            <data name="prices/category_price_excl_tax" xsi:type="string">90.99</data>
+            <data name="prices/category_price_incl_tax" xsi:type="string">98.50</data>
+            <data name="prices/product_view_price_excl_tax" xsi:type="string">90.99</data>
+            <data name="prices/product_view_price_incl_tax" xsi:type="string">98.50</data>
+            <data name="prices/cart_item_price_excl_tax" xsi:type="string">90.99</data>
+            <data name="prices/cart_item_price_incl_tax" xsi:type="string">98.50</data>
+            <data name="prices/cart_item_subtotal_excl_tax" xsi:type="string">272.97</data>
+            <data name="prices/cart_item_subtotal_incl_tax" xsi:type="string">295.49</data>
+            <data name="prices/subtotal_excl_tax" xsi:type="string">272.97</data>
+            <data name="prices/subtotal_incl_tax" xsi:type="string">295.49</data>
+            <data name="prices/discount" xsi:type="string">136.49</data>
+            <data name="prices/shipping_excl_tax" xsi:type="string">13.84</data>
+            <data name="prices/shipping_incl_tax" xsi:type="string">14.98</data>
+            <data name="prices/tax" xsi:type="string">12.40</data>
+            <data name="prices/grand_total_excl_tax" xsi:type="string">150.32</data>
+            <data name="prices/grand_total_incl_tax" xsi:type="string">162.72</data>
+            <constraint name="Magento\Tax\Test\Constraint\AssertTaxRuleIsAppliedToAllPricesExcludingIncludingTax" />
+            <constraint name="Magento\Tax\Test\Constraint\AssertTaxCalculationAfterCheckoutExcludingIncludingTax" />
+            <constraint name="Magento\Tax\Test\Constraint\AssertOrderTaxOnBackendExcludingIncludingTax" />
+        </variation>
+        <variation name="TaxCalculationTestVariation4">
+            <data name="description" xsi:type="string">Simple product special price with sales rule, customer tax less than store tax and catalog price including tax</data>
+            <data name="configData" xsi:type="string">row_cat_incl_ship_excl_before_disc_on_incl, display_excluding_including_tax</data>
+            <data name="product" xsi:type="string">catalogProductSimple::product_with_special_price_and_category</data>
+            <data name="salesRule" xsi:type="string">active_sales_rule_for_all_groups_no_coupon</data>
+            <data name="catalogRule" xsi:type="string">-</data>
+            <data name="taxRule" xsi:type="string">customer_less_store_rate</data>
+            <data name="customer/dataSet" xsi:type="string">johndoe_unique</data>
+            <data name="qty" xsi:type="string">3</data>
+            <data name="prices/category_price_excl_tax" xsi:type="string">83.05</data>
+            <data name="prices/category_price_incl_tax" xsi:type="string">89.90</data>
+            <data name="prices/product_view_price_excl_tax" xsi:type="string">83.05</data>
+            <data name="prices/product_view_price_incl_tax" xsi:type="string">89.90</data>
+            <data name="prices/cart_item_price_excl_tax" xsi:type="string">83.05</data>
+            <data name="prices/cart_item_price_incl_tax" xsi:type="string">89.90</data>
+            <data name="prices/cart_item_subtotal_excl_tax" xsi:type="string">249.15</data>
+            <data name="prices/cart_item_subtotal_incl_tax" xsi:type="string">269.70</data>
+            <data name="prices/subtotal_excl_tax" xsi:type="string">249.15</data>
+            <data name="prices/subtotal_incl_tax" xsi:type="string">269.70</data>
+            <data name="prices/discount" xsi:type="string">134.85</data>
+            <data name="prices/shipping_excl_tax" xsi:type="string">15.00</data>
+            <data name="prices/shipping_incl_tax" xsi:type="string">16.24</data>
+            <data name="prices/tax" xsi:type="string">21.79</data>
+            <data name="prices/grand_total_excl_tax" xsi:type="string">129.30</data>
+            <data name="prices/grand_total_incl_tax" xsi:type="string">151.09</data>
+            <constraint name="Magento\Tax\Test\Constraint\AssertTaxRuleIsAppliedToAllPricesExcludingIncludingTax" />
+            <constraint name="Magento\Tax\Test\Constraint\AssertTaxCalculationAfterCheckoutExcludingIncludingTax" />
+            <constraint name="Magento\Tax\Test\Constraint\AssertOrderTaxOnBackendExcludingIncludingTax" />
+        </variation>
+        <variation name="TaxCalculationTestVariation5">
+            <data name="description" xsi:type="string">Simple product tier price with sales rule, customer tax less than store tax and catalog price including tax</data>
+            <data name="configData" xsi:type="string">unit_cat_incl_ship_incl_before_disc_on_incl, display_excluding_including_tax</data>
+            <data name="product" xsi:type="string">catalogProductSimple::simple_with_tier_price_and_category</data>
+            <data name="salesRule" xsi:type="string">active_sales_rule_for_all_groups_no_coupon</data>
+            <data name="catalogRule" xsi:type="string">-</data>
+            <data name="taxRule" xsi:type="string">customer_less_store_rate</data>
+            <data name="customer/dataSet" xsi:type="string">johndoe_unique</data>
+            <data name="qty" xsi:type="string">3</data>
+            <data name="prices/category_price_excl_tax" xsi:type="string">276.81</data>
+            <data name="prices/category_price_incl_tax" xsi:type="string">299.65</data>
+            <data name="prices/product_view_price_excl_tax" xsi:type="string">276.81</data>
+            <data name="prices/product_view_price_incl_tax" xsi:type="string">299.65</data>
+            <data name="prices/cart_item_price_excl_tax" xsi:type="string">13.84</data>
+            <data name="prices/cart_item_price_incl_tax" xsi:type="string">14.98</data>
+            <data name="prices/cart_item_subtotal_excl_tax" xsi:type="string">41.52</data>
+            <data name="prices/cart_item_subtotal_incl_tax" xsi:type="string">44.94</data>
+            <data name="prices/subtotal_excl_tax" xsi:type="string">41.52</data>
+            <data name="prices/subtotal_incl_tax" xsi:type="string">44.94</data>
+            <data name="prices/discount" xsi:type="string">22.47</data>
+            <data name="prices/shipping_excl_tax" xsi:type="string">13.84</data>
+            <data name="prices/shipping_incl_tax" xsi:type="string">14.98</data>
+            <data name="prices/tax" xsi:type="string">4.56</data>
+            <data name="prices/grand_total_excl_tax" xsi:type="string">32.89</data>
+            <data name="prices/grand_total_incl_tax" xsi:type="string">37.45</data>
+            <constraint name="Magento\Tax\Test\Constraint\AssertTaxRuleIsAppliedToAllPricesExcludingIncludingTax" />
+            <constraint name="Magento\Tax\Test\Constraint\AssertTaxCalculationAfterCheckoutExcludingIncludingTax" />
+            <constraint name="Magento\Tax\Test\Constraint\AssertOrderTaxOnBackendExcludingIncludingTax" />
+        </variation>
+        <variation name="TaxCalculationTestVariation6">
+            <data name="description" xsi:type="string">Simple product special price with sales rule, customer tax equals store tax and catalog price excluding tax</data>
+            <data name="configData" xsi:type="string">total_cat_excl_ship_incl_before_disc_on_incl, display_excluding_including_tax</data>
+            <data name="product" xsi:type="string">catalogProductSimple::product_with_special_price_and_category</data>
+            <data name="salesRule" xsi:type="string">active_sales_rule_for_all_groups_no_coupon</data>
+            <data name="catalogRule" xsi:type="string">-</data>
+            <data name="taxRule" xsi:type="string">customer_equals_store_rate</data>
+            <data name="customer/dataSet" xsi:type="string">johndoe_unique</data>
+            <data name="qty" xsi:type="string">3</data>
+            <data name="prices/category_price_excl_tax" xsi:type="string">90.00</data>
+            <data name="prices/category_price_incl_tax" xsi:type="string">97.43</data>
+            <data name="prices/product_view_price_excl_tax" xsi:type="string">90.00</data>
+            <data name="prices/product_view_price_incl_tax" xsi:type="string">97.43</data>
+            <data name="prices/cart_item_price_excl_tax" xsi:type="string">90.00</data>
+            <data name="prices/cart_item_price_incl_tax" xsi:type="string">97.43</data>
+            <data name="prices/cart_item_subtotal_excl_tax" xsi:type="string">270.00</data>
+            <data name="prices/cart_item_subtotal_incl_tax" xsi:type="string">292.28</data>
+            <data name="prices/subtotal_excl_tax" xsi:type="string">270.00</data>
+            <data name="prices/subtotal_incl_tax" xsi:type="string">292.28</data>
+            <data name="prices/discount" xsi:type="string">146.15</data>
+            <data name="prices/shipping_excl_tax" xsi:type="string">13.86</data>
+            <data name="prices/shipping_incl_tax" xsi:type="string">15.00</data>
+            <data name="prices/tax" xsi:type="string">23.42</data>
+            <data name="prices/grand_total_excl_tax" xsi:type="string">137.71</data>
+            <data name="prices/grand_total_incl_tax" xsi:type="string">161.13</data>
+            <constraint name="Magento\Tax\Test\Constraint\AssertTaxRuleIsAppliedToAllPricesExcludingIncludingTax" />
+            <constraint name="Magento\Tax\Test\Constraint\AssertTaxCalculationAfterCheckoutExcludingIncludingTax" />
+            <constraint name="Magento\Tax\Test\Constraint\AssertOrderTaxOnBackendExcludingIncludingTax" />
+        </variation>
+        <variation name="TaxCalculationTestVariation7">
+            <data name="description" xsi:type="string">Simple product group price with sales rule, customer tax equals store tax and catalog price excluding tax</data>
+            <data name="configData" xsi:type="string">unit_cat_excl_ship_excl_after_disc_on_excl, display_excluding_including_tax</data>
+            <data name="product" xsi:type="string">catalogProductSimple::simple_with_group_price_and_category</data>
+            <data name="salesRule" xsi:type="string">active_sales_rule_for_all_groups_no_coupon</data>
+            <data name="catalogRule" xsi:type="string">-</data>
+            <data name="taxRule" xsi:type="string">customer_equals_store_rate</data>
+            <data name="customer/dataSet" xsi:type="string">johndoe_unique</data>
+            <data name="qty" xsi:type="string">3</data>
+            <data name="prices/category_price_excl_tax" xsi:type="string">90.99</data>
+            <data name="prices/category_price_incl_tax" xsi:type="string">98.50</data>
+            <data name="prices/product_view_price_excl_tax" xsi:type="string">90.99</data>
+            <data name="prices/product_view_price_incl_tax" xsi:type="string">98.50</data>
+            <data name="prices/cart_item_price_excl_tax" xsi:type="string">90.99</data>
+            <data name="prices/cart_item_price_incl_tax" xsi:type="string">98.50</data>
+            <data name="prices/cart_item_subtotal_excl_tax" xsi:type="string">272.97</data>
+            <data name="prices/cart_item_subtotal_incl_tax" xsi:type="string">295.50</data>
+            <data name="prices/subtotal_excl_tax" xsi:type="string">272.97</data>
+            <data name="prices/subtotal_incl_tax" xsi:type="string">295.50</data>
+            <data name="prices/discount" xsi:type="string">136.49</data>
+            <data name="prices/shipping_excl_tax" xsi:type="string">15.00</data>
+            <data name="prices/shipping_incl_tax" xsi:type="string">16.24</data>
+            <data name="prices/tax" xsi:type="string">12.49</data>
+            <data name="prices/grand_total_excl_tax" xsi:type="string">151.48</data>
+            <data name="prices/grand_total_incl_tax" xsi:type="string">163.97</data>
+            <constraint name="Magento\Tax\Test\Constraint\AssertTaxRuleIsAppliedToAllPricesExcludingIncludingTax" />
+            <constraint name="Magento\Tax\Test\Constraint\AssertTaxCalculationAfterCheckoutExcludingIncludingTax" />
+            <constraint name="Magento\Tax\Test\Constraint\AssertOrderTaxOnBackendExcludingIncludingTax" />
+        </variation>
+        <variation name="TaxCalculationTestVariation8">
+            <data name="description" xsi:type="string">Simple product special price with sales rule, customer tax greater than store tax and catalog price including tax</data>
+            <data name="configData" xsi:type="string">total_cat_incl_ship_excl_before_disc_on_excl, display_excluding_including_tax</data>
+            <data name="product" xsi:type="string">catalogProductSimple::simple_with_group_price_and_category</data>
+            <data name="salesRule" xsi:type="string">active_sales_rule_for_all_groups_no_coupon</data>
+            <data name="catalogRule" xsi:type="string">-</data>
+            <data name="taxRule" xsi:type="string">customer_greater_store_rate</data>
+            <data name="customer/dataSet" xsi:type="string">johndoe_unique</data>
+            <data name="qty" xsi:type="string">3</data>
+            <data name="prices/category_price_excl_tax" xsi:type="string">84.06</data>
+            <data name="prices/category_price_incl_tax" xsi:type="string">91.10</data>
+            <data name="prices/product_view_price_excl_tax" xsi:type="string">84.06</data>
+            <data name="prices/product_view_price_incl_tax" xsi:type="string">91.10</data>
+            <data name="prices/cart_item_price_excl_tax" xsi:type="string">84.06</data>
+            <data name="prices/cart_item_price_incl_tax" xsi:type="string">91.10</data>
+            <data name="prices/cart_item_subtotal_excl_tax" xsi:type="string">252.18</data>
+            <data name="prices/cart_item_subtotal_incl_tax" xsi:type="string">273.30</data>
+            <data name="prices/subtotal_excl_tax" xsi:type="string">252.18</data>
+            <data name="prices/subtotal_incl_tax" xsi:type="string">273.30</data>
+            <data name="prices/discount" xsi:type="string">126.09</data>
+            <data name="prices/shipping_excl_tax" xsi:type="string">15.00</data>
+            <data name="prices/shipping_incl_tax" xsi:type="string">16.26</data>
+            <data name="prices/tax" xsi:type="string">22.38</data>
+            <data name="prices/grand_total_excl_tax" xsi:type="string">141.09</data>
+            <data name="prices/grand_total_incl_tax" xsi:type="string">163.47</data>
+            <constraint name="Magento\Tax\Test\Constraint\AssertTaxRuleIsAppliedToAllPricesExcludingIncludingTax" />
+            <constraint name="Magento\Tax\Test\Constraint\AssertTaxCalculationAfterCheckoutExcludingIncludingTax" />
+            <constraint name="Magento\Tax\Test\Constraint\AssertOrderTaxOnBackendExcludingIncludingTax" />
+        </variation>
+        <variation name="TaxCalculationTestVariation9">
+            <data name="description" xsi:type="string">Simple product tier price with sales rule, customer tax greater than store tax and catalog price excluding tax</data>
+            <data name="configData" xsi:type="string">total_cat_excl_ship_incl_after_disc_on_incl, display_excluding_including_tax</data>
+            <data name="product" xsi:type="string">catalogProductSimple::simple_with_tier_price_and_category</data>
+            <data name="salesRule" xsi:type="string">active_sales_rule_for_all_groups_no_coupon</data>
+            <data name="catalogRule" xsi:type="string">-</data>
+            <data name="taxRule" xsi:type="string">customer_greater_store_rate</data>
+            <data name="customer/dataSet" xsi:type="string">johndoe_unique</data>
+            <data name="qty" xsi:type="string">3</data>
+            <data name="prices/category_price_excl_tax" xsi:type="string">300.00</data>
+            <data name="prices/category_price_incl_tax" xsi:type="string">325.13</data>
+            <data name="prices/product_view_price_excl_tax" xsi:type="string">300.00</data>
+            <data name="prices/product_view_price_incl_tax" xsi:type="string">325.13</data>
+            <data name="prices/cart_item_price_excl_tax" xsi:type="string">15.00</data>
+            <data name="prices/cart_item_price_incl_tax" xsi:type="string">16.26</data>
+            <data name="prices/cart_item_subtotal_excl_tax" xsi:type="string">45.00</data>
+            <data name="prices/cart_item_subtotal_incl_tax" xsi:type="string">48.77</data>
+            <data name="prices/subtotal_excl_tax" xsi:type="string">45.00</data>
+            <data name="prices/subtotal_incl_tax" xsi:type="string">48.77</data>
+            <data name="prices/discount" xsi:type="string">24.39</data>
+            <data name="prices/shipping_excl_tax" xsi:type="string">13.86</data>
+            <data name="prices/shipping_incl_tax" xsi:type="string">15.02</data>
+            <data name="prices/tax" xsi:type="string">2.89</data>
+            <data name="prices/grand_total_excl_tax" xsi:type="string">34.47</data>
+            <data name="prices/grand_total_incl_tax" xsi:type="string">37.36</data>
+            <constraint name="Magento\Tax\Test\Constraint\AssertTaxRuleIsAppliedToAllPricesExcludingIncludingTax" />
+            <constraint name="Magento\Tax\Test\Constraint\AssertTaxCalculationAfterCheckoutExcludingIncludingTax" />
+            <constraint name="Magento\Tax\Test\Constraint\AssertOrderTaxOnBackendExcludingIncludingTax" />
+        </variation>
+        <variation name="TaxCalculationTestVariation10">
+            <data name="description" xsi:type="string">Simple product special price with sales rule, customer tax greater than store tax and catalog price excluding tax</data>
+            <data name="configData" xsi:type="string">unit_cat_excl_ship_incl_after_disc_on_excl, display_excluding_including_tax</data>
+            <data name="product" xsi:type="string">catalogProductSimple::product_with_special_price_and_category</data>
+            <data name="salesRule" xsi:type="string">active_sales_rule_for_all_groups_no_coupon</data>
+            <data name="catalogRule" xsi:type="string">-</data>
+            <data name="taxRule" xsi:type="string">customer_greater_store_rate</data>
+            <data name="customer/dataSet" xsi:type="string">johndoe_unique</data>
+            <data name="qty" xsi:type="string">3</data>
+            <data name="prices/category_price_excl_tax" xsi:type="string">90.00</data>
+            <data name="prices/category_price_incl_tax" xsi:type="string">97.54</data>
+            <data name="prices/product_view_price_excl_tax" xsi:type="string">90.00</data>
+            <data name="prices/product_view_price_incl_tax" xsi:type="string">97.54</data>
+            <data name="prices/cart_item_price_excl_tax" xsi:type="string">90.00</data>
+            <data name="prices/cart_item_price_incl_tax" xsi:type="string">97.54</data>
+            <data name="prices/cart_item_subtotal_excl_tax" xsi:type="string">270.00</data>
+            <data name="prices/cart_item_subtotal_incl_tax" xsi:type="string">292.62</data>
+            <data name="prices/subtotal_excl_tax" xsi:type="string">270.00</data>
+            <data name="prices/subtotal_incl_tax" xsi:type="string">292.62</data>
+            <data name="prices/discount" xsi:type="string">135.00</data>
+            <data name="prices/shipping_excl_tax" xsi:type="string">13.86</data>
+            <data name="prices/shipping_incl_tax" xsi:type="string">15.02</data>
+            <data name="prices/tax" xsi:type="string">12.47</data>
+            <data name="prices/grand_total_excl_tax" xsi:type="string">148.86</data>
+            <data name="prices/grand_total_incl_tax" xsi:type="string">161.33</data>
+            <constraint name="Magento\Tax\Test\Constraint\AssertTaxRuleIsAppliedToAllPricesExcludingIncludingTax" />
+            <constraint name="Magento\Tax\Test\Constraint\AssertTaxCalculationAfterCheckoutExcludingIncludingTax" />
+            <constraint name="Magento\Tax\Test\Constraint\AssertOrderTaxOnBackendExcludingIncludingTax" />
+        </variation>
+    </testCase>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxWithCrossBorderTest.php b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxWithCrossBorderTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..b67edd7a4c1787025b0b0b45b126f3c3996427e4
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxWithCrossBorderTest.php
@@ -0,0 +1,160 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Tax\Test\TestCase;
+
+use Magento\Catalog\Test\Fixture\CatalogProductSimple;
+use Magento\CatalogRule\Test\Fixture\CatalogRule;
+use Magento\Customer\Test\Fixture\Customer;
+use Magento\SalesRule\Test\Fixture\SalesRule;
+use Magento\Mtf\Fixture\FixtureFactory;
+use Magento\Mtf\TestCase\Injectable;
+
+/**
+ * Steps:
+ * 1. Log in as default admin user.
+ * 2. Go to Stores > Taxes > Tax Rules.
+ * 3. Click 'Add New Tax Rule' button.
+ * 4. Assign 3 different rates for different addresses
+ * 5. Save Tax Rate.
+ * 6. Go to Products > Catalog.
+ * 7. Add new product.
+ * 8. Fill data according to dataset.
+ * 9. Save product.
+ * 10. Go to Stores > Configuration.
+ * 11. Fill Tax configuration according to data set.
+ * 12. Save tax configuration.
+ * 13. Register two customers on front end that will match two different rates
+ * 14. Login with each customer and verify prices
+ *
+ * @group Tax_(CS)
+ * @ZephyrId MAGETWO-29052
+ */
+class TaxWithCrossBorderTest extends Injectable
+{
+    /* tags */
+    const MVP = 'yes';
+    const DOMAIN = 'CS';
+    /* end tags */
+
+    /**
+     * Fixture SalesRule.
+     *
+     * @var SalesRule
+     */
+    protected $salesRule;
+
+    /**
+     * Fixture CatalogRule.
+     *
+     * @var CatalogRule
+     */
+    protected $catalogRule;
+
+    /**
+     * Fixture factory.
+     *
+     * @var FixtureFactory
+     */
+    protected $fixtureFactory;
+
+    /**
+     * Prepare data.
+     *
+     * @param FixtureFactory $fixtureFactory
+     * @return array
+     */
+    public function __prepare(FixtureFactory $fixtureFactory)
+    {
+        $this->fixtureFactory = $fixtureFactory;
+
+        return ['customers' => $this->createCustomers()];
+    }
+
+    /**
+     * Injection data.
+     *
+     * @return void
+     */
+    public function __inject()
+    {
+        // TODO: Move test set up to "__prepare" method after fix bug MAGETWO-29331
+        $taxRule = $this->fixtureFactory->createByCode('taxRule', ['dataSet' => 'cross_border_tax_rule']);
+        $taxRule->persist();
+    }
+
+    /**
+     * Create customers.
+     *
+     * @return array $customers
+     */
+    protected function createCustomers()
+    {
+        $customersData = ['johndoe_unique_TX', 'johndoe_unique'];
+        $customers = [];
+        foreach ($customersData as $customerData) {
+            $customer = $this->fixtureFactory->createByCode('customer', ['dataSet' => $customerData]);
+            $customer->persist();
+            $customers[] = $customer;
+        }
+        return $customers;
+    }
+
+    /**
+     * Test product prices with tax.
+     *
+     * @param CatalogProductSimple $product
+     * @param string $configData
+     * @param SalesRule $salesRule [optional]
+     * @param CatalogRule $catalogRule [optional]
+     * @return void
+     */
+    public function test(
+        CatalogProductSimple $product,
+        $configData,
+        SalesRule $salesRule = null,
+        CatalogRule $catalogRule = null
+    ) {
+        //Preconditions
+        if ($salesRule !== null) {
+            $salesRule->persist();
+            $this->salesRule = $salesRule;
+        }
+        if ($catalogRule !== null) {
+            $catalogRule->persist();
+            $this->catalogRule = $catalogRule;
+        }
+        $this->objectManager->create(
+            'Magento\Config\Test\TestStep\SetupConfigurationStep',
+            ['configData' => $configData]
+        )->run();
+        $product->persist();
+    }
+
+    /**
+     * Tear down after test.
+     *
+     * @return void
+     */
+    public function tearDown()
+    {
+        if (isset($this->salesRule)) {
+            $this->objectManager->create('Magento\SalesRule\Test\TestStep\DeleteAllSalesRuleStep')->run();
+            $this->salesRule = null;
+        }
+        if (isset($this->catalogRule)) {
+            $this->objectManager->create('\Magento\CatalogRule\Test\TestStep\DeleteAllCatalogRulesStep')->run();
+            $this->catalogRule = null;
+        }
+
+        // TODO: Move set default configuration to "tearDownAfterClass" method after fix bug MAGETWO-29331
+        $this->objectManager->create('Magento\Tax\Test\TestStep\DeleteAllTaxRulesStep')->run();
+        $this->objectManager->create(
+            'Magento\Config\Test\TestStep\SetupConfigurationStep',
+            ['configData' => 'default_tax_configuration']
+        )->run();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxWithCrossBorderTest.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxWithCrossBorderTest.xml
new file mode 100644
index 0000000000000000000000000000000000000000..82218491cf409382415251e998b235429a4364c5
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxWithCrossBorderTest.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+ -->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
+    <testCase name="Magento\Tax\Test\TestCase\TaxWithCrossBorderTest">
+        <variation name="TaxWithCrossBorderTestVariation1">
+            <data name="product/dataSet" xsi:type="string">with_one_custom_option_and_category</data>
+            <data name="configData" xsi:type="string">cross_border_enabled_price_incl_tax, display_excluding_including_tax</data>
+            <constraint name="Magento\Tax\Test\Constraint\AssertTaxWithCrossBorderApplied" />
+        </variation>
+        <variation name="TaxWithCrossBorderTestVariation2">
+            <data name="product/dataSet" xsi:type="string">product_with_category</data>
+            <data name="salesRule/dataSet" xsi:type="string">cart_rule</data>
+            <data name="configData" xsi:type="string">cross_border_enabled_price_incl_tax, display_excluding_including_tax</data>
+            <constraint name="Magento\Tax\Test\Constraint\AssertTaxWithCrossBorderApplied" />
+        </variation>
+        <variation name="TaxWithCrossBorderTestVariation3">
+            <data name="product/dataSet" xsi:type="string">product_with_category</data>
+            <data name="catalogRule/dataSet" xsi:type="string">catalog_price_rule_priority_0</data>
+            <data name="configData" xsi:type="string">cross_border_enabled_price_incl_tax, display_excluding_including_tax</data>
+            <constraint name="Magento\Tax\Test\Constraint\AssertTaxWithCrossBorderApplied" />
+        </variation>
+        <variation name="TaxWithCrossBorderTestVariation4">
+            <data name="product/dataSet" xsi:type="string">product_with_special_price_and_category</data>
+            <data name="configData" xsi:type="string">cross_border_enabled_price_incl_tax, display_excluding_including_tax</data>
+            <constraint name="Magento\Tax\Test\Constraint\AssertTaxWithCrossBorderApplied" />
+        </variation>
+        <variation name="TaxWithCrossBorderTestVariation5">
+            <data name="product/dataSet" xsi:type="string">product_with_category</data>
+            <data name="configData" xsi:type="string">cross_border_enabled_price_excl_tax, display_excluding_including_tax</data>
+            <constraint name="Magento\Tax\Test\Constraint\AssertTaxWithCrossBorderNotApplied" />
+        </variation>
+    </testCase>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestStep/DeleteAllTaxRulesStep.php b/dev/tests/functional/tests/app/Magento/Tax/Test/TestStep/DeleteAllTaxRulesStep.php
index 69b0cb8e48754397a8a3d56873fcc721f7e6269a..d24b2ca4c4de8cd5cb362704b3c78c2ad4905fb4 100644
--- a/dev/tests/functional/tests/app/Magento/Tax/Test/TestStep/DeleteAllTaxRulesStep.php
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestStep/DeleteAllTaxRulesStep.php
@@ -51,6 +51,7 @@ class DeleteAllTaxRulesStep implements TestStepInterface
     public function run()
     {
         $this->taxRuleIndexPage->open();
+        $this->taxRuleIndexPage->getTaxRuleGrid()->resetFilter();
         while ($this->taxRuleIndexPage->getTaxRuleGrid()->isFirstRowVisible()) {
             $this->taxRuleIndexPage->getTaxRuleGrid()->openFirstRow();
             $this->taxRuleNewPage->getFormPageActions()->delete();
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/etc/testcase.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/etc/testcase.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c47afe1a6a889a0df215473b24539396e0ff8b77
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/etc/testcase.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/Magento/Mtf/TestCase/etc/testcase.xsd">
+    <scenario name="TaxCalculationTest" firstStep="setupConfiguration">
+        <step name="setupConfiguration" module="Magento_Config" next="createSalesRule" />
+        <step name="createSalesRule" module="Magento_SalesRule" next="createCatalogRule" />
+        <step name="createCatalogRule" module="Magento_CatalogRule" next="createTaxRule" />
+        <step name="createTaxRule" module="Magento_Tax" next="createProduct" />
+        <step name="createProduct" module="Magento_Catalog" next="createCustomer" />
+        <step name="createCustomer" module="Magento_Customer" next="loginCustomerOnFrontend" />
+        <step name="loginCustomerOnFrontend" module="Magento_Customer" />
+    </scenario>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Ups/Test/Repository/ConfigData.xml b/dev/tests/functional/tests/app/Magento/Ups/Test/Repository/ConfigData.xml
index 5351224a4f52e4bc04b92617f30d0190b5963fb3..f6c7bd8341526c7fa4e6f48a79f020fb5830b2b8 100644
--- a/dev/tests/functional/tests/app/Magento/Ups/Test/Repository/ConfigData.xml
+++ b/dev/tests/functional/tests/app/Magento/Ups/Test/Repository/ConfigData.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" ?>
 <!--
 /**
  * Copyright © 2015 Magento. All rights reserved.
diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/Block/Adminhtml/Edit/CustomerForm.xml b/dev/tests/functional/tests/app/Magento/Wishlist/Test/Block/Adminhtml/Edit/CustomerForm.xml
index c00338cd02750df3c73fca736d49307814d8e286..d6a8abbf78b151df64f7fee7e5dcd34d1674c15a 100644
--- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/Block/Adminhtml/Edit/CustomerForm.xml
+++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/Block/Adminhtml/Edit/CustomerForm.xml
@@ -8,7 +8,7 @@
 <tabs>
     <wishlist>
         <class>\Magento\Wishlist\Test\Block\Adminhtml\Customer\Edit\Tab\Wishlist</class>
-        <selector>#tab_wishlist</selector>
+        <selector>#tab_block_wishlist</selector>
         <strategy>css selector</strategy>
     </wishlist>
 </tabs>
diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductsToCartFromCustomerWishlistOnFrontendTest.xml b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductsToCartFromCustomerWishlistOnFrontendTest.xml
index 1cf13be71e2cd00324fbc5303d2a6bd31230fa33..d88f6d3054641ffa76b70d4b5593bcd59f3aede1 100644
--- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductsToCartFromCustomerWishlistOnFrontendTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductsToCartFromCustomerWishlistOnFrontendTest.xml
@@ -27,7 +27,7 @@
             <constraint name="Magento\Wishlist\Test\Constraint\AssertWishlistIsEmpty" />
         </variation>
         <variation name="AddProductsToCartFromCustomerWishlistOnFrontendTestVariation4">
-            <data name="products" xsi:type="string">groupedProduct::three_simple_products_default_qty</data>
+            <data name="products" xsi:type="string">groupedProduct::three_simple_products</data>
             <data name="qty" xsi:type="string">-</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertProductQtyInShoppingCart" />
             <constraint name="Magento\Wishlist\Test\Constraint\AssertProductsIsAbsentInWishlist" />
diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ShareWishlistEntityTest.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ShareWishlistEntityTest.php
index cce7949f993f63e0312573a558e50510fee1fc84..2b96619bcae14f8186d73bd61782a213238bd33e 100644
--- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ShareWishlistEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ShareWishlistEntityTest.php
@@ -11,34 +11,26 @@ use Magento\Catalog\Test\Page\Product\CatalogProductView;
 use Magento\Cms\Test\Page\CmsIndex;
 use Magento\Customer\Test\Fixture\Customer;
 use Magento\Customer\Test\Page\CustomerAccountIndex;
-use Magento\Customer\Test\Page\CustomerAccountLogin;
-use Magento\Customer\Test\Page\CustomerAccountLogout;
 use Magento\Wishlist\Test\Page\WishlistIndex;
 use Magento\Wishlist\Test\Page\WishlistShare;
 use Magento\Mtf\Client\BrowserInterface;
 use Magento\Mtf\TestCase\Injectable;
 
 /**
- * Test Creation for ShareWishlistEntity
- *
- * Test Flow:
- *
  * Preconditions:
- * 1. Create Customer Account
- * 2. Create product
+ * 1. Create Customer Account.
+ * 2. Create product.
  *
  * Steps:
- * 1. Login to frontend as a Customer
- * 2. Add product to Wish List
- * 3. Click "Share Wish List" button
- * 4. Fill in all data according to data set
- * 5. Click "Share Wishlist" button
- * 6. Perform all assertions
+ * 1. Login to frontend as a Customer.
+ * 2. Add product to Wish List.
+ * 3. Click "Share Wish List" button.
+ * 4. Fill in all data according to data set.
+ * 5. Click "Share Wishlist" button.
+ * 6. Perform all assertions.
  *
  * @group Wishlist_(CS)
  * @ZephyrId MAGETWO-23394
- *
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
 class ShareWishlistEntityTest extends Injectable
 {
@@ -49,56 +41,42 @@ class ShareWishlistEntityTest extends Injectable
     /* end tags */
 
     /**
-     * Cms index page
+     * Cms index page.
      *
      * @var CmsIndex
      */
     protected $cmsIndex;
 
     /**
-     * Customer login page
-     *
-     * @var CustomerAccountLogin
-     */
-    protected $customerAccountLogin;
-
-    /**
-     * Customer account index page
+     * Customer account index page.
      *
      * @var CustomerAccountIndex
      */
     protected $customerAccountIndex;
 
     /**
-     * Product view page
+     * Product view page.
      *
      * @var CatalogProductView
      */
     protected $catalogProductView;
 
     /**
-     * Page CustomerAccountLogout
-     *
-     * @var CustomerAccountLogout
-     */
-    protected $customerAccountLogout;
-
-    /**
-     * Wishlist index page
+     * Wishlist index page.
      *
      * @var WishlistIndex
      */
     protected $wishlistIndex;
 
     /**
-     * Wishlist share page
+     * Wishlist share page.
      *
      * @var WishlistShare
      */
     protected $wishlistShare;
 
     /**
-     * Prepare data
+     * Prepare data.
      *
      * @param Customer $customer
      * @param CatalogProductSimple $product
@@ -118,12 +96,10 @@ class ShareWishlistEntityTest extends Injectable
     }
 
     /**
-     * Injection data
+     * Inject pages.
      *
      * @param CmsIndex $cmsIndex
-     * @param CustomerAccountLogin $customerAccountLogin
      * @param CustomerAccountIndex $customerAccountIndex
-     * @param CustomerAccountLogout $customerAccountLogout
      * @param CatalogProductView $catalogProductView
      * @param WishlistIndex $wishlistIndex
      * @param WishlistShare $wishlistShare
@@ -131,24 +107,20 @@ class ShareWishlistEntityTest extends Injectable
      */
     public function __inject(
         CmsIndex $cmsIndex,
-        CustomerAccountLogin $customerAccountLogin,
         CustomerAccountIndex $customerAccountIndex,
-        CustomerAccountLogout $customerAccountLogout,
         CatalogProductView $catalogProductView,
         WishlistIndex $wishlistIndex,
         WishlistShare $wishlistShare
     ) {
         $this->cmsIndex = $cmsIndex;
-        $this->customerAccountLogin = $customerAccountLogin;
         $this->customerAccountIndex = $customerAccountIndex;
-        $this->customerAccountLogout = $customerAccountLogout;
         $this->catalogProductView = $catalogProductView;
         $this->wishlistIndex = $wishlistIndex;
         $this->wishlistShare = $wishlistShare;
     }
 
     /**
-     * Share wish list
+     * Share wish list.
      *
      * @param BrowserInterface $browser
      * @param Customer $customer
@@ -174,27 +146,16 @@ class ShareWishlistEntityTest extends Injectable
     }
 
     /**
-     * Login customer
+     * Login customer.
      *
      * @param Customer $customer
      * @return void
      */
     protected function loginCustomer(Customer $customer)
     {
-        $this->cmsIndex->open();
-        if (!$this->cmsIndex->getLinksBlock()->isLinkVisible('Log Out')) {
-            $this->cmsIndex->getLinksBlock()->openLink("Log In");
-            $this->customerAccountLogin->getLoginBlock()->login($customer);
-        }
-    }
-
-    /**
-     * Log out after test
-     *
-     * @return void
-     */
-    public function tearDown()
-    {
-        $this->customerAccountLogout->open();
+        $this->objectManager->create(
+            'Magento\Customer\Test\TestStep\LoginCustomerOnFrontendStep',
+            ['customer' => $customer]
+        )->run();
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ShareWishlistEntityTest.xml b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ShareWishlistEntityTest.xml
index 59dccc42d293c1a3a1259565da59e9408c390de5..8dd654cf89bbd1065185ba2a345c5fe44f3cf65f 100644
--- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ShareWishlistEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ShareWishlistEntityTest.xml
@@ -6,11 +6,11 @@
  */
  -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
-  <testCase name="Magento\Wishlist\Test\TestCase\ShareWishlistEntityTest">
-    <variation name="ShareWishlistEntityTestVariation1">
-      <data name="sharingInfo/emails" xsi:type="string">JohnDoe123456789@example.com,JohnDoe987654321@example.com,JohnDoe123456abc@example.com</data>
-      <data name="sharingInfo/message" xsi:type="string">Sharing message.</data>
-      <constraint name="Magento\Wishlist\Test\Constraint\AssertWishlistShareMessage"/>
-    </variation>
-  </testCase>
+    <testCase name="Magento\Wishlist\Test\TestCase\ShareWishlistEntityTest">
+        <variation name="ShareWishlistEntityTestVariation1">
+            <data name="sharingInfo/emails" xsi:type="string">JohnDoe123456789@example.com,JohnDoe987654321@example.com,JohnDoe123456abc@example.com</data>
+            <data name="sharingInfo/message" xsi:type="string">Sharing message.</data>
+            <constraint name="Magento\Wishlist\Test\Constraint\AssertWishlistShareMessage" />
+        </variation>
+    </testCase>
 </config>
diff --git a/dev/tests/functional/utils/config/ee_modules.yml.dist b/dev/tests/functional/utils/config/ee_modules.yml.dist
deleted file mode 100644
index 33bd56450a7a26ceb8241a97495dbc1c23675c6e..0000000000000000000000000000000000000000
--- a/dev/tests/functional/utils/config/ee_modules.yml.dist
+++ /dev/null
@@ -1,5 +0,0 @@
-# Copyright © 2015 Magento. All rights reserved.
-# See COPYING.txt for license details.
-- Magento_Backend
-- Magento_Catalog
-- Magento_Customer
\ No newline at end of file
diff --git a/dev/tests/functional/utils/config/generator_config.yml.dist b/dev/tests/functional/utils/config/generator_config.yml.dist
deleted file mode 100644
index 14dffd2306b796de983017366d6b6b26e2f863e9..0000000000000000000000000000000000000000
--- a/dev/tests/functional/utils/config/generator_config.yml.dist
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright © 2015 Magento. All rights reserved.
-# See COPYING.txt for license details.
-# Generator running options, in case "generate_specified_modules" is set to "yes" then specified file is used
-generate_specified_modules: no
-specified_modules: dev\tests\functional\utils\config\ee_modules.yml.dist
-
-# Fallback path configurations
-tests_fallback:
-    1:
-        path: tests/app
-
-# Handler priority configuration
-handler_fallback:
-    1: Curl
-    2: Direct
-    3: Ui
\ No newline at end of file
diff --git a/dev/tests/integration/etc/install-config-mysql.php.dist b/dev/tests/integration/etc/install-config-mysql.php.dist
index 0d8fb591eb14454b4d3c46045e3606ab6e47dea3..3cbe5eed4e976da6ad88238ad9a60a7fdb42c999 100644
--- a/dev/tests/integration/etc/install-config-mysql.php.dist
+++ b/dev/tests/integration/etc/install-config-mysql.php.dist
@@ -5,15 +5,15 @@
  */
 
 return [
-    'db_host' => 'localhost',
-    'db_user' => 'root',
-    'db_password' => '',
-    'db_name' => 'magento_integration_tests',
-    'db_prefix' => '',
-    'backend_frontname' => 'backend',
-    'admin_user' => \Magento\TestFramework\Bootstrap::ADMIN_NAME,
-    'admin_password' => \Magento\TestFramework\Bootstrap::ADMIN_PASSWORD,
-    'admin_email' => \Magento\TestFramework\Bootstrap::ADMIN_EMAIL,
-    'admin_firstname' => \Magento\TestFramework\Bootstrap::ADMIN_FIRSTNAME,
-    'admin_lastname' => \Magento\TestFramework\Bootstrap::ADMIN_LASTNAME,
+    'db-host' => 'localhost',
+    'db-user' => 'root',
+    'db-password' => '',
+    'db-name' => 'magento_integration_tests',
+    'db-prefix' => '',
+    'backend-frontname' => 'backend',
+    'admin-user' => \Magento\TestFramework\Bootstrap::ADMIN_NAME,
+    'admin-password' => \Magento\TestFramework\Bootstrap::ADMIN_PASSWORD,
+    'admin-email' => \Magento\TestFramework\Bootstrap::ADMIN_EMAIL,
+    'admin-firstname' => \Magento\TestFramework\Bootstrap::ADMIN_FIRSTNAME,
+    'admin-lastname' => \Magento\TestFramework\Bootstrap::ADMIN_LASTNAME,
 ];
diff --git a/dev/tests/integration/etc/install-config-mysql.travis.php.dist b/dev/tests/integration/etc/install-config-mysql.travis.php.dist
index a0e25fd80384beb21201843bca7e59a435a26c34..ac8eeb0bbbaccc5b2604d3a0e925c384afec1049 100644
--- a/dev/tests/integration/etc/install-config-mysql.travis.php.dist
+++ b/dev/tests/integration/etc/install-config-mysql.travis.php.dist
@@ -5,15 +5,15 @@
  */
 
 return [
-    'db_host' => '127.0.0.1',
-    'db_user' => 'travis',
-    'db_password' => '',
-    'db_name' => 'magento_integration_tests',
-    'db_prefix' => 'travis_',
-    'backend_frontname' => 'backend',
-    'admin_user' => \Magento\TestFramework\Bootstrap::ADMIN_NAME,
-    'admin_password' => \Magento\TestFramework\Bootstrap::ADMIN_PASSWORD,
-    'admin_email' => \Magento\TestFramework\Bootstrap::ADMIN_EMAIL,
-    'admin_firstname' => \Magento\TestFramework\Bootstrap::ADMIN_FIRSTNAME,
-    'admin_lastname' => \Magento\TestFramework\Bootstrap::ADMIN_LASTNAME,
+    'db-host' => '127.0.0.1',
+    'db-user' => 'travis',
+    'db-password' => '',
+    'db-name' => 'magento_integration_tests',
+    'db-prefix' => 'travis_',
+    'backend-frontname' => 'backend',
+    'admin-user' => \Magento\TestFramework\Bootstrap::ADMIN_NAME,
+    'admin-password' => \Magento\TestFramework\Bootstrap::ADMIN_PASSWORD,
+    'admin-email' => \Magento\TestFramework\Bootstrap::ADMIN_EMAIL,
+    'admin-firstname' => \Magento\TestFramework\Bootstrap::ADMIN_FIRSTNAME,
+    'admin-lastname' => \Magento\TestFramework\Bootstrap::ADMIN_LASTNAME,
 ];
diff --git a/dev/tests/integration/framework/Magento/TestFramework/Annotation/ConfigFixture.php b/dev/tests/integration/framework/Magento/TestFramework/Annotation/ConfigFixture.php
index 9854602a507fcc0045fcc2f5be86a85f96073b0d..3809d7f293849488c696e4631c03e6ed34e0de02 100644
--- a/dev/tests/integration/framework/Magento/TestFramework/Annotation/ConfigFixture.php
+++ b/dev/tests/integration/framework/Magento/TestFramework/Annotation/ConfigFixture.php
@@ -9,6 +9,8 @@
  */
 namespace Magento\TestFramework\Annotation;
 
+use Magento\Framework\App\Config\ScopeConfigInterface;
+
 class ConfigFixture
 {
     /**
@@ -73,7 +75,7 @@ class ConfigFixture
                 )->setValue(
                     $configPath,
                     $value,
-                    \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT
+                    ScopeConfigInterface::SCOPE_TYPE_DEFAULT
                 );
             }
         } else {
diff --git a/dev/tests/integration/framework/Magento/TestFramework/Application.php b/dev/tests/integration/framework/Magento/TestFramework/Application.php
index 4d13da77e94c5767525784e06200107926193c3c..2ff3a1003e44f0d3d982e9aa6f01753fc7ca80c7 100644
--- a/dev/tests/integration/framework/Magento/TestFramework/Application.php
+++ b/dev/tests/integration/framework/Magento/TestFramework/Application.php
@@ -172,10 +172,10 @@ class Application
                 $dbName = $dbInfo['dbname'];
             } else {
                 $installConfig = $this->getInstallConfig();
-                $host = $installConfig['db_host'];
-                $user = $installConfig['db_user'];
-                $password = $installConfig['db_password'];
-                $dbName = $installConfig['db_name'];
+                $host = $installConfig['db-host'];
+                $user = $installConfig['db-user'];
+                $password = $installConfig['db-password'];
+                $dbName = $installConfig['db-name'];
             }
             $this->_db = new Db\Mysql(
                 $host,
@@ -379,7 +379,7 @@ class Application
          * @see \Magento\Setup\Mvc\Bootstrap\InitParamListener::BOOTSTRAP_PARAM
          */
         $this->_shell->execute(
-            'php -f %s setup:uninstall -n --magento_init_params=%s',
+            'php -f %s setup:uninstall -n --magento-init-params=%s',
             [BP . '/bin/magento', $this->getInitParamsQuery()]
         );
     }
@@ -466,7 +466,7 @@ class Application
          * Literal value is used instead of constant, because autoloader is not integrated with Magento Setup app
          * @see \Magento\Setup\Mvc\Bootstrap\InitParamListener::BOOTSTRAP_PARAM
          */
-        $params['magento_init_params'] = $this->getInitParamsQuery();
+        $params['magento-init-params'] = $this->getInitParamsQuery();
         $result = [];
         foreach ($params as $key => $value) {
             if (!empty($value)) {
diff --git a/dev/tests/integration/framework/bootstrap.php b/dev/tests/integration/framework/bootstrap.php
index 41453aa0becc0e2d32513736f2cb99ddc60e8854..b71bb17d945ccd42f693ed57588116e05c474dbb 100644
--- a/dev/tests/integration/framework/bootstrap.php
+++ b/dev/tests/integration/framework/bootstrap.php
@@ -8,6 +8,11 @@ use Magento\Framework\Autoload\AutoloaderRegistry;
 require_once __DIR__ . '/../../../../app/bootstrap.php';
 require_once __DIR__ . '/autoload.php';
 
+$updateAppBootstrap = __DIR__ . '/../../../../update/app/bootstrap.php';
+if (file_exists($updateAppBootstrap)) {
+    require_once $updateAppBootstrap;
+}
+
 $testsBaseDir = dirname(__DIR__);
 $testsTmpDir = "{$testsBaseDir}/tmp";
 $magentoBaseDir = realpath("{$testsBaseDir}/../../../");
diff --git a/dev/tests/integration/phpunit.xml.dist b/dev/tests/integration/phpunit.xml.dist
index 7a9e365c8f15056e5060cd27827720e2d18d2fce..bd6cbffb247d64f6617eef5fc9c8ebaebb753b7e 100644
--- a/dev/tests/integration/phpunit.xml.dist
+++ b/dev/tests/integration/phpunit.xml.dist
@@ -18,6 +18,7 @@
         </testsuite>
         <testsuite name="Magento Integration Tests">
             <directory suffix="Test.php">testsuite</directory>
+            <directory suffix="Test.php">../../../update/dev/tests/integration/testsuite</directory>
             <exclude>testsuite/Magento/Test/Integrity</exclude>
             <exclude>testsuite/Magento/MemoryUsageTest.php</exclude>
         </testsuite>
@@ -27,6 +28,7 @@
         <whitelist addUncoveredFilesFromWhiteList="true">
             <directory suffix=".php">../../../app/code/Magento</directory>
             <directory suffix=".php">../../../lib/internal/Magento</directory>
+            <directory suffix=".php">../../../update/app/code</directory>
         </whitelist>
     </filter>
     <!-- PHP INI settings and constants definition -->
diff --git a/dev/tests/integration/testsuite/Magento/Backend/Block/_files/menu/expected.txt b/dev/tests/integration/testsuite/Magento/Backend/Block/_files/menu/expected.txt
index fc890c803aae34f8ca74f4c00a541415b426034a..dc07065f7be1e4b2db53584c769bb52abb79de21 100644
--- a/dev/tests/integration/testsuite/Magento/Backend/Block/_files/menu/expected.txt
+++ b/dev/tests/integration/testsuite/Magento/Backend/Block/_files/menu/expected.txt
@@ -1 +1 @@
-<ul id="nav" role="menubar" ><li  data-ui-id="magento-backend-system"  class="item-system  parent last level-0" id="magento-backend-system" aria-haspopup="true" role="menu-item"><a href="#"  onclick="return false;" class=""><span>System</span></a><div class="submenu" aria-labelledby="magento-backend-system"><ul role="menu" ><li  data-ui-id="magento-backend-system-report"  class="item-system-report  parent  level-1" role="menu-item"><strong class="submenu-group-title" role="presentation"><span>Report</span></strong><div class="submenu"><ul role="menu" ><li  data-ui-id="magento-backend-system-report-private-sales"  class="item-system-report-private-sales    level-2" role="menu-item"><a href="#"  onclick="return false;" class=""><span>Private Sales</span></a></li><li  data-ui-id="magento-backend-system-report-magento-invite-general"  class="item-system-report-magento-invite-general    level-2" role="menu-item"><a href="#"  onclick="return false;" class=""><span>Invite</span></a></li><li  data-ui-id="magento-backend-system-report-magento-invite-customer"  class="item-system-report-magento-invite-customer    level-2" role="menu-item"><a href="#"  onclick="return false;" class=""><span>Invited Customers</span></a></li></ul></div></li></ul></div></li></ul>
\ No newline at end of file
+<ul id="nav" role="menubar" ><li  data-ui-id="magento-backend-system"  class="item-system  parent last level-0" id="magento-backend-system" aria-haspopup="true" role="menu-item"><a href="#"  onclick="return false;" class=""><span>System</span></a><div class="submenu" aria-labelledby="magento-backend-system"><ul role="menu" ><div class="submenu"><ul role="menu" ><li  data-ui-id="magento-backend-system-report-private-sales"  class="item-system-report-private-sales    level-2" role="menu-item"><a href="#"  onclick="return false;" class=""><span>Private Sales</span></a></li><li  data-ui-id="magento-backend-system-report-magento-invite-general"  class="item-system-report-magento-invite-general    level-2" role="menu-item"><a href="#"  onclick="return false;" class=""><span>Invite</span></a></li><li  data-ui-id="magento-backend-system-report-magento-invite-customer"  class="item-system-report-magento-invite-customer    level-2" role="menu-item"><a href="#"  onclick="return false;" class=""><span>Invited Customers</span></a></li></ul></div></ul></div></li></ul>
\ No newline at end of file
diff --git a/dev/tests/integration/testsuite/Magento/Backend/Model/Locale/ResolverTest.php b/dev/tests/integration/testsuite/Magento/Backend/Model/Locale/ResolverTest.php
index 09c21758cba336cbd15982d610875cbc0aa19117..c0cc101fd36bfe94dd5dcc19481d81d14b926132 100644
--- a/dev/tests/integration/testsuite/Magento/Backend/Model/Locale/ResolverTest.php
+++ b/dev/tests/integration/testsuite/Magento/Backend/Model/Locale/ResolverTest.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\Backend\Model\Locale;
 
+use Magento\Framework\Locale\Resolver;
+
 /**
  * @magentoAppArea adminhtml
  */
@@ -28,7 +30,7 @@ class ResolverTest extends \PHPUnit_Framework_TestCase
      */
     public function testSetLocaleWithDefaultLocale()
     {
-        $this->_checkSetLocale(\Magento\Framework\Locale\ResolverInterface::DEFAULT_LOCALE);
+        $this->_checkSetLocale(Resolver::DEFAULT_LOCALE);
     }
 
     /**
diff --git a/dev/tests/integration/testsuite/Magento/Customer/_files/etc/data_object.xml b/dev/tests/integration/testsuite/Magento/Catalog/_files/etc/service_data_attributes.xml
similarity index 63%
rename from dev/tests/integration/testsuite/Magento/Customer/_files/etc/data_object.xml
rename to dev/tests/integration/testsuite/Magento/Catalog/_files/etc/service_data_attributes.xml
index a75fa2a653213ade29aa7ea81e8482e752ed9210..93cf7bfb484a6de773ab318549385ad2436f2fa4 100644
--- a/dev/tests/integration/testsuite/Magento/Customer/_files/etc/data_object.xml
+++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/etc/service_data_attributes.xml
@@ -5,22 +5,22 @@
  * See COPYING.txt for license details.
  */
 -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../lib/internal/Magento/Framework/Api/etc/data_object.xsd">
-    <custom_attributes for="Magento\Tax\Api\Data\TaxRateInterface">
-    </custom_attributes>
-    <custom_attributes for="Magento\Catalog\Api\Data\ProductInterface">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../lib/internal/Magento/Framework/Api/etc/service_data_attributes.xsd">
+    <extension_attributes for="Magento\Tax\Api\Data\TaxRateInterface">
+    </extension_attributes>
+    <extension_attributes for="Magento\Catalog\Api\Data\ProductInterface">
         <attribute code="stock_item" type="Magento\CatalogInventory\Service\Data\V1\StockItem" />
-    </custom_attributes>
-    <custom_attributes for="Magento\Catalog\Api\Data\CategoryInterface">
+    </extension_attributes>
+    <extension_attributes for="Magento\Catalog\Api\Data\CategoryInterface">
         <attribute code="category_attribute_1" type="Magento\Catalog\Api\Data\CategoryAttributeType1" />
         <attribute code="category_attribute_2" type="Magento\Catalog\Api\Data\CategoryAttributeType2" />
-    </custom_attributes>
-    <custom_attributes for="Magento\Customer\Api\Data\CustomerInterface">
+    </extension_attributes>
+    <extension_attributes for="Magento\Customer\Api\Data\CustomerInterface">
         <attribute code="customer_attribute_1" type="Magento\Customer\Api\Data\CustomerAttributeType1" />
         <attribute code="customer_attribute_2" type="Magento\Customer\Api\Data\CustomerAttributeType2" />
-    </custom_attributes>
-    <custom_attributes for="Magento\Customer\Api\Data\AddressInterface">
+    </extension_attributes>
+    <extension_attributes for="Magento\Customer\Api\Data\Address">
         <attribute code="address_attribute_1" type="Magento\Customer\Api\Data\AddressAttributeType1" />
         <attribute code="address_attribute_2" type="Magento\Customer\Api\Data\AddressAttributeType2" />
-    </custom_attributes>
+    </extension_attributes>
 </config>
diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Export/ProductTest.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Export/ProductTest.php
index def5584983e613573b91eeff95d766599b82655a..a83bb8be1c9feec57cb2e722d69021549a786615 100644
--- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Export/ProductTest.php
+++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Export/ProductTest.php
@@ -125,4 +125,50 @@ class ProductTest extends \PHPUnit_Framework_TestCase
             );
         }
     }
+
+    /**
+     * Verifies if exception processing works properly
+     *
+     * @magentoDataFixture Magento/CatalogImportExport/_files/product_export_data.php
+     */
+    public function testExceptionInGetExportData()
+    {
+        $exception = new \Exception('Error');
+
+        $rowCustomizerMock = $this->getMockBuilder('Magento\CatalogImportExport\Model\Export\RowCustomizerInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $loggerMock = $this->getMockBuilder('\Psr\Log\LoggerInterface')->getMock();
+
+        $directoryMock = $this->getMock('Magento\Framework\Filesystem\Directory\Write', [], [], '', false);
+        $directoryMock->expects($this->any())->method('getParentDirectory')->will($this->returnValue('some#path'));
+        $directoryMock->expects($this->any())->method('isWritable')->will($this->returnValue(true));
+
+        $filesystemMock = $this->getMock('Magento\Framework\Filesystem', [], [], '', false);
+        $filesystemMock->expects($this->once())->method('getDirectoryWrite')->will($this->returnValue($directoryMock));
+
+        $exportAdapter = new \Magento\ImportExport\Model\Export\Adapter\Csv($filesystemMock);
+
+        $rowCustomizerMock->expects($this->once())->method('prepareData')->willThrowException($exception);
+        $loggerMock->expects($this->once())->method('critical')->with($exception);
+
+        $collection = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
+            '\Magento\Catalog\Model\Resource\Product\Collection'
+        );
+
+        /** @var \Magento\CatalogImportExport\Model\Export\Product $model */
+        $model = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
+            'Magento\CatalogImportExport\Model\Export\Product',
+            [
+                'rowCustomizer' => $rowCustomizerMock,
+                'logger' => $loggerMock,
+                'collection' => $collection
+            ]
+        );
+
+
+        $data = $model->setWriter($exportAdapter)->export();
+        $this->assertEmpty($data);
+    }
 }
diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Product/Type/ConfigurableTest.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Product/Type/ConfigurableTest.php
index 2a99dede484227e4b7bc38fd9040e78573584869..ab40348430e024c0d58e42d8ee649321c0ec754b 100644
--- a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Product/Type/ConfigurableTest.php
+++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Product/Type/ConfigurableTest.php
@@ -79,7 +79,6 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase
     public function testSetUsedProductAttributeIds()
     {
         $testConfigurable = $this->_getAttributeByCode('test_configurable');
-        $this->assertEmpty($this->_product->getData('_cache_instance_configurable_attributes'));
         $this->_model->setUsedProductAttributeIds([$testConfigurable->getId()], $this->_product);
         $attributes = $this->_product->getData('_cache_instance_configurable_attributes');
         $this->assertArrayHasKey(0, $attributes);
diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/configurable_attribute_rollback.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/configurable_attribute_rollback.php
new file mode 100644
index 0000000000000000000000000000000000000000..5772edc9317ae5a0a41a9d4aafd419ea982e53fa
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/configurable_attribute_rollback.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+/** @var \Magento\Framework\Registry $registry */
+$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Framework\Registry');
+
+$registry->unregister('isSecureArea');
+$registry->register('isSecureArea', true);
+
+$eavConfig = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Eav\Model\Config');
+$attribute = $eavConfig->getAttribute('catalog_product', 'test_configurable');
+if ($attribute instanceof \Magento\Eav\Model\Entity\Attribute\AbstractAttribute
+    && $attribute->getId()
+) {
+    $attribute->delete();
+}
+$eavConfig->clear();
+
+$registry->unregister('isSecureArea');
+$registry->register('isSecureArea', false);
diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_configurable.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_configurable.php
index b083d7e52dfb293b687d837f145b54909240e617..cc615bf03ea85243af323bf7844bc3d33acac7c9 100644
--- a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_configurable.php
+++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_configurable.php
@@ -12,17 +12,16 @@ $installer = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create
     ['resourceName' => 'catalog_setup']
 );
 
-/* Create simple products per each option */
-/** @var $options \Magento\Eav\Model\Resource\Entity\Attribute\Option\Collection */
-$options = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-    'Magento\Eav\Model\Resource\Entity\Attribute\Option\Collection'
-);
-$options->setAttributeFilter($attribute->getId());
+/* Create simple products per each option value*/
+
+/** @var \Magento\Eav\Api\Data\AttributeOptionInterface[] $options */
+$options = $attribute->getOptions();
 
 $attributeValues = [];
 $productIds = [];
 $attributeSetId = $installer->getAttributeSetId('catalog_product', 'Default');
 $productIds = [10, 20];
+array_shift($options); //remove the first option which is empty
 foreach ($options as $option) {
     /** @var $product \Magento\Catalog\Model\Product */
     $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product');
@@ -36,13 +35,13 @@ foreach ($options as $option) {
     )->setWebsiteIds(
         [1]
     )->setName(
-        'Configurable Option' . $option->getId()
+        'Configurable Option' . $option->getLabel()
     )->setSku(
         'simple_' . $productId
     )->setPrice(
         10
     )->setTestConfigurable(
-        $option->getId()
+        $option->getValue()
     )->setVisibility(
         \Magento\Catalog\Model\Product\Visibility::VISIBILITY_NOT_VISIBLE
     )->setStatus(
@@ -54,7 +53,7 @@ foreach ($options as $option) {
     $attributeValues[] = [
         'label' => 'test',
         'attribute_id' => $attribute->getId(),
-        'value_index' => $option->getId(),
+        'value_index' => $option->getValue(),
         'is_percent' => false,
         'pricing_value' => 5,
     ];
diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_configurable_rollback.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_configurable_rollback.php
index c1b23ce233c9e09240533d5bc7ee97f90a7510da..f1e17b724c8b476f76a622837d2120b0df1c96cd 100644
--- a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_configurable_rollback.php
+++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_configurable_rollback.php
@@ -26,6 +26,11 @@ $product->load(1);
 if ($product->getId()) {
     $product->delete();
 }
+\Magento\TestFramework\Helper\Bootstrap::getObjectManager()
+    ->get('Magento\ConfigurableProduct\Model\Resource\Product\Type\Configurable\Attribute\Price\Data')
+    ->setProductPrice(1, null);
+
+require __DIR__ . '/configurable_attribute_rollback.php';
 
 $registry->unregister('isSecureArea');
 $registry->register('isSecureArea', false);
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php
index b3c578e46cfa26069c1c93c07ac1b15bc3ea59e7..da3a723a0db759702ecd505510159f614a9b5105 100755
--- a/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php
@@ -102,7 +102,7 @@ class IndexTest extends \Magento\Backend\Utility\Controller
     public function testSaveActionWithInvalidCustomerAddressData()
     {
         $post = [
-            'account' => [
+            'customer' => [
                 'middlename' => 'test middlename',
                 'group_id' => 1,
                 'website_id' => 0,
@@ -110,8 +110,8 @@ class IndexTest extends \Magento\Backend\Utility\Controller
                 'lastname' => 'test lastname',
                 'email' => 'example@domain.com',
                 'default_billing' => '_item1',
-                'customer_address' => ['_item1' => []],
             ],
+            'address' => ['_item1' => []],
         ];
         $this->getRequest()->setPostValue($post);
         $this->dispatch('backend/customer/index/save');
@@ -141,7 +141,7 @@ class IndexTest extends \Magento\Backend\Utility\Controller
         $objectManager = Bootstrap::getObjectManager();
 
         $post = [
-            'account' => [
+            'customer' => [
                 'middlename' => 'test middlename',
                 'group_id' => 1,
                 'website_id' => 0,
@@ -150,17 +150,17 @@ class IndexTest extends \Magento\Backend\Utility\Controller
                 'email' => 'example@domain.com',
                 'default_billing' => '_item1',
                 'password' => 'password',
-                'customer_address' => [
-                    '_item1' => [
-                        'firstname' => 'test firstname',
-                        'lastname' => 'test lastname',
-                        'street' => ['test street'],
-                        'city' => 'test city',
-                        'country_id' => 'US',
-                        'postcode' => '01001',
-                        'telephone' => '+7000000001',
-                        'default_billing' => 'true',
-                    ],
+            ],
+            'address' => [
+                '_item1' => [
+                    'firstname' => 'test firstname',
+                    'lastname' => 'test lastname',
+                    'street' => ['test street'],
+                    'city' => 'test city',
+                    'country_id' => 'US',
+                    'postcode' => '01001',
+                    'telephone' => '+7000000001',
+                    'default_billing' => 'true',
                 ],
             ],
         ];
@@ -218,8 +218,8 @@ class IndexTest extends \Magento\Backend\Utility\Controller
     public function testSaveActionExistingCustomerAndExistingAddressData()
     {
         $post = [
-            'customer_id' => '1',
-            'account' => [
+            'customer' => [
+                'entity_id' => '1',
                 'middlename' => 'test middlename',
                 'group_id' => 1,
                 'website_id' => 1,
@@ -232,39 +232,38 @@ class IndexTest extends \Magento\Backend\Utility\Controller
                 'created_at' => '2000-01-01 00:00:00',
                 'default_shipping' => '_item1',
                 'default_billing' => 1,
-                'customer_address' => [
-                    '1' => [
-                        'firstname' => 'update firstname',
-                        'lastname' => 'update lastname',
-                        'street' => ['update street'],
-                        'city' => 'update city',
-                        'country_id' => 'US',
-                        'postcode' => '01001',
-                        'telephone' => '+7000000001',
-                        'default_billing' => 'true',
-                    ],
-                    '_item1' => [
-                        'firstname' => 'new firstname',
-                        'lastname' => 'new lastname',
-                        'street' => ['new street'],
-                        'city' => 'new city',
-                        'country_id' => 'US',
-                        'postcode' => '01001',
-                        'telephone' => '+7000000001',
-                        'default_shipping' => 'true',
-                    ],
-                    '_template_' => [
-                        'firstname' => '',
-                        'lastname' => '',
-                        'street' => [],
-                        'city' => '',
-                        'country_id' => 'US',
-                        'postcode' => '',
-                        'telephone' => '',
-                    ],
+            ],
+            'address' => [
+                '1' => [
+                    'firstname' => 'update firstname',
+                    'lastname' => 'update lastname',
+                    'street' => ['update street'],
+                    'city' => 'update city',
+                    'country_id' => 'US',
+                    'postcode' => '01001',
+                    'telephone' => '+7000000001',
+                    'default_billing' => 'true',
+                ],
+                '_item1' => [
+                    'firstname' => 'new firstname',
+                    'lastname' => 'new lastname',
+                    'street' => ['new street'],
+                    'city' => 'new city',
+                    'country_id' => 'US',
+                    'postcode' => '01001',
+                    'telephone' => '+7000000001',
+                    'default_shipping' => 'true',
+                ],
+                '_template_' => [
+                    'firstname' => '',
+                    'lastname' => '',
+                    'street' => [],
+                    'city' => '',
+                    'country_id' => 'US',
+                    'postcode' => '',
+                    'telephone' => '',
                 ],
             ],
-
             'subscription' => '',
         ];
         $this->getRequest()->setPostValue($post);
@@ -330,7 +329,7 @@ class IndexTest extends \Magento\Backend\Utility\Controller
         $this->assertEquals(1, $subscriber->getStatus());
 
         $post = [
-            'customer_id' => $customerId,
+            'customer' => ['entity_id' => $customerId],
         ];
         $this->getRequest()->setPostValue($post);
         $this->getRequest()->setParam('id', 1);
@@ -360,7 +359,7 @@ class IndexTest extends \Magento\Backend\Utility\Controller
     public function testSaveActionCoreException()
     {
         $post = [
-            'account' => [
+            'customer' => [
                 'middlename' => 'test middlename',
                 'group_id' => 1,
                 'website_id' => 1,
@@ -477,7 +476,7 @@ class IndexTest extends \Magento\Backend\Utility\Controller
     {
         $customerData = [
             'customer_id' => 0,
-            'account' => [
+            'customer' => [
                 'created_in' => false,
                 'disable_auto_group_change' => false,
                 'email' => false,
@@ -887,8 +886,8 @@ class IndexTest extends \Magento\Backend\Utility\Controller
     public function testValidateCustomerWithAddressSuccess()
     {
         $customerData = [
-            'id' => '1',
-            'account' => [
+            'customer' => [
+                'entity_id' => '1',
                 'middlename' => 'new middlename',
                 'group_id' => 1,
                 'website_id' => 1,
@@ -943,8 +942,8 @@ class IndexTest extends \Magento\Backend\Utility\Controller
     public function testValidateCustomerWithAddressFailure()
     {
         $customerData = [
-            'id' => '1',
-            'account' => [
+            'customer' => [
+                'entity_id' => '1',
                 'middlename' => 'new middlename',
                 'group_id' => 1,
                 'website_id' => 1,
@@ -955,30 +954,30 @@ class IndexTest extends \Magento\Backend\Utility\Controller
                 'new_password' => 'auto',
                 'sendemail_store_id' => '1',
                 'sendemail' => '1',
-                'customer_address' => [
-                    '1' => [
-                        'firstname' => '',
-                        'lastname' => '',
-                        'street' => ['update street'],
-                        'city' => 'update city',
-                        'postcode' => '01001',
-                        'telephone' => '',
-                    ],
-                    '_template_' => [
-                        'lastname' => '',
-                        'street' => [],
-                        'city' => '',
-                        'country_id' => 'US',
-                        'postcode' => '',
-                        'telephone' => '',
-                    ],
+            ],
+            'address' => [
+                '1' => [
+                    'firstname' => '',
+                    'lastname' => '',
+                    'street' => ['update street'],
+                    'city' => 'update city',
+                    'postcode' => '01001',
+                    'telephone' => '',
+                ],
+                '_template_' => [
+                    'lastname' => '',
+                    'street' => [],
+                    'city' => '',
+                    'country_id' => 'US',
+                    'postcode' => '',
+                    'telephone' => '',
                 ],
             ],
         ];
         /**
          * set customer data
          */
-        $this->getRequest()->setParams($customerData);
+        $this->getRequest()->setPostValue($customerData);
         $this->dispatch('backend/customer/index/validate');
         $body = $this->getResponse()->getBody();
 
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Model/FileResolverStub.php b/dev/tests/integration/testsuite/Magento/Customer/Model/FileResolverStub.php
index 48d81d30eb84119c45e440be2e57bd48b4c3c8e9..9ee9ed911f7c092aac6034ed441e5c96f2e46aa2 100644
--- a/dev/tests/integration/testsuite/Magento/Customer/Model/FileResolverStub.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/Model/FileResolverStub.php
@@ -21,7 +21,7 @@ class FileResolverStub implements \Magento\Framework\Config\FileResolverInterfac
                 'path' => realpath(__DIR__ . '/../_files/etc'),
             ]
         );
-        $paths = ['data_object.xml'];
+        $paths = ['service_data_attributes.xml'];
         return new \Magento\Framework\Config\FileIterator($readDirectory, $paths);
     }
 }
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/etc/data_object.xml b/dev/tests/integration/testsuite/Magento/Customer/_files/etc/service_data_attributes.xml
similarity index 63%
rename from dev/tests/integration/testsuite/Magento/Catalog/_files/etc/data_object.xml
rename to dev/tests/integration/testsuite/Magento/Customer/_files/etc/service_data_attributes.xml
index c2888a64ee00c0e6f18a7d1126920e4c85a8b091..a7ae041eda7683ce99dd168befc50c2ae5a46f3c 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/_files/etc/data_object.xml
+++ b/dev/tests/integration/testsuite/Magento/Customer/_files/etc/service_data_attributes.xml
@@ -5,22 +5,22 @@
  * See COPYING.txt for license details.
  */
 -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../lib/internal/Magento/Framework/Api/etc/data_object.xsd">
-    <custom_attributes for="Magento\Tax\Api\Data\TaxRateInterface">
-    </custom_attributes>
-    <custom_attributes for="Magento\Catalog\Api\Data\ProductInterface">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../lib/internal/Magento/Framework/Api/etc/service_data_attributes.xsd">
+    <extension_attributes for="Magento\Tax\Api\Data\TaxRateInterface">
+    </extension_attributes>
+    <extension_attributes for="Magento\Catalog\Api\Data\ProductInterface">
         <attribute code="stock_item" type="Magento\CatalogInventory\Service\Data\V1\StockItem" />
-    </custom_attributes>
-    <custom_attributes for="Magento\Catalog\Api\Data\CategoryInterface">
+    </extension_attributes>
+    <extension_attributes for="Magento\Catalog\Api\Data\CategoryInterface">
         <attribute code="category_attribute_1" type="Magento\Catalog\Api\Data\CategoryAttributeType1" />
         <attribute code="category_attribute_2" type="Magento\Catalog\Api\Data\CategoryAttributeType2" />
-    </custom_attributes>
-    <custom_attributes for="Magento\Customer\Api\Data\CustomerInterface">
+    </extension_attributes>
+    <extension_attributes for="Magento\Customer\Api\Data\CustomerInterface">
         <attribute code="customer_attribute_1" type="Magento\Customer\Api\Data\CustomerAttributeType1" />
         <attribute code="customer_attribute_2" type="Magento\Customer\Api\Data\CustomerAttributeType2" />
-    </custom_attributes>
-    <custom_attributes for="Magento\Customer\Api\Data\Address">
+    </extension_attributes>
+    <extension_attributes for="Magento\Customer\Api\Data\AddressInterface">
         <attribute code="address_attribute_1" type="Magento\Customer\Api\Data\AddressAttributeType1" />
         <attribute code="address_attribute_2" type="Magento\Customer\Api\Data\AddressAttributeType2" />
-    </custom_attributes>
+    </extension_attributes>
 </config>
diff --git a/dev/tests/integration/testsuite/Magento/DatabaseTest.php b/dev/tests/integration/testsuite/Magento/DatabaseTest.php
index 4058fcb2b444abeac044b35cd4e368fb6006b238..77e767b03f9a2700d318e05fd1dbcb348d393315 100644
--- a/dev/tests/integration/testsuite/Magento/DatabaseTest.php
+++ b/dev/tests/integration/testsuite/Magento/DatabaseTest.php
@@ -21,7 +21,7 @@ class DatabaseTest extends \PHPUnit_Framework_TestCase
 
         $db = Bootstrap::getInstance()->getBootstrap()->getApplication()->getDbInstance();
         $command = $checkerPath . ' -d ' . $db->getSchema()
-            . ' h=' . $db->getHost()['db_host'] . ',u=' . $db->getUser() . ',p=' . $db->getPassword();
+            . ' h=' . $db->getHost()['db-host'] . ',u=' . $db->getUser() . ',p=' . $db->getPassword();
 
         exec($command, $output, $exitCode);
         $this->assertEquals(0, $exitCode);
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Api/Config/ReaderTest.php b/dev/tests/integration/testsuite/Magento/Framework/Api/Config/ReaderTest.php
index 351a0ba03144a218481d9ab798cca18989ca8db8..07fceddb6424b3bc01d7e4448833cb92a709d6c9 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/Api/Config/ReaderTest.php
+++ b/dev/tests/integration/testsuite/Magento/Framework/Api/Config/ReaderTest.php
@@ -76,12 +76,24 @@ class ReaderTest extends \PHPUnit_Framework_TestCase
         $expectedArray = [
             'Magento\Tax\Api\Data\TaxRateInterface' => [],
             'Magento\Catalog\Api\Data\Product' => [
-                'stock_item' => "Magento\CatalogInventory\Api\Data\StockItem",
+                'stock_item' => [
+                    "type" => "Magento\CatalogInventory\Api\Data\StockItem",
+                    "resourceRefs" => [],
+                ],
             ],
             'Magento\Customer\Api\Data\CustomerInterface' => [
-                'custom_1' => "Magento\Customer\Api\Data\CustomerCustom",
-                'custom_2' => "Magento\CustomerExtra\Api\Data\CustomerCustom22",
-                'custom_3' => "Magento\Customer\Api\Data\CustomerCustom3",
+                'custom_1' => [
+                    "type" => "Magento\Customer\Api\Data\CustomerCustom",
+                    "resourceRefs" => [],
+                ],
+                'custom_2' => [
+                    "type" => "Magento\CustomerExtra\Api\Data\CustomerCustom22",
+                    "resourceRefs" => [],
+                ],
+                'custom_3' => [
+                    "type" => "Magento\Customer\Api\Data\CustomerCustom3",
+                    "resourceRefs" => [],
+                ],
             ],
         ];
 
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Api/Config/_files/config_one.xml b/dev/tests/integration/testsuite/Magento/Framework/Api/Config/_files/config_one.xml
index f5a3d522454ab487f461f697e6108f118f1769e9..82aa641d5e8bd9040d9fa26689d95a09b74e19f3 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/Api/Config/_files/config_one.xml
+++ b/dev/tests/integration/testsuite/Magento/Framework/Api/Config/_files/config_one.xml
@@ -5,14 +5,14 @@
  * See COPYING.txt for license details.
  */
 -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../lib/internal/Magento/Framework/Api/etc/data_object.xsd">
-    <custom_attributes for="Magento\Tax\Api\Data\TaxRateInterface">
-    </custom_attributes>
-    <custom_attributes for="Magento\Catalog\Api\Data\Product">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../lib/internal/Magento/Framework/Api/etc/service_data_attributes.xsd">
+    <extension_attributes for="Magento\Tax\Api\Data\TaxRateInterface">
+    </extension_attributes>
+    <extension_attributes for="Magento\Catalog\Api\Data\Product">
         <attribute code="stock_item" type="Magento\CatalogInventory\Api\Data\StockItem" />
-    </custom_attributes>
-    <custom_attributes for="Magento\Customer\Api\Data\CustomerInterface">
+    </extension_attributes>
+    <extension_attributes for="Magento\Customer\Api\Data\CustomerInterface">
         <attribute code="custom_1" type="Magento\Customer\Api\Data\CustomerCustom" />
         <attribute code="custom_2" type="Magento\CustomerExtra\Service\V1\Data\CustomerCustom21" />
-    </custom_attributes>
+    </extension_attributes>
 </config>
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Api/Config/_files/config_two.xml b/dev/tests/integration/testsuite/Magento/Framework/Api/Config/_files/config_two.xml
index 629efb9b7a30a400dad479894f71d0711da8f24d..5596f61e572f4b076a1d850b38002b6a448a7297 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/Api/Config/_files/config_two.xml
+++ b/dev/tests/integration/testsuite/Magento/Framework/Api/Config/_files/config_two.xml
@@ -5,9 +5,9 @@
  * See COPYING.txt for license details.
  */
 -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../lib/internal/Magento/Framework/Api/etc/data_object.xsd">
-    <custom_attributes for="Magento\Customer\Api\Data\CustomerInterface">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../lib/internal/Magento/Framework/Api/etc/service_data_attributes.xsd">
+    <extension_attributes for="Magento\Customer\Api\Data\CustomerInterface">
         <attribute code="custom_2" type="Magento\CustomerExtra\Api\Data\CustomerCustom22" />
         <attribute code="custom_3" type="Magento\Customer\Api\Data\CustomerCustom3" />
-    </custom_attributes>
+    </extension_attributes>
 </config>
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Session/SessionManagerTest.php b/dev/tests/integration/testsuite/Magento/Framework/Session/SessionManagerTest.php
index c8379e5e9c39f37bb5d4edd46ed4720aa250b788..18a4314710c3d9a19f51bf5688afcc7087b90f93 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/Session/SessionManagerTest.php
+++ b/dev/tests/integration/testsuite/Magento/Framework/Session/SessionManagerTest.php
@@ -3,153 +3,214 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-namespace Magento\Framework\Session;
-
-class SessionManagerTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\Framework\Session\SessionManagerInterface
-     */
-    protected $_model;
-
-    /**
-     * @var \Magento\Framework\Session\SidResolverInterface
-     */
-    protected $_sidResolver;
-
-    /**
-     * @var string
-     */
-    protected $sessionName;
-
-    /**
-     * @var \Magento\Framework\App\RequestInterface
-     */
-    protected $request;
-
-    protected function setUp()
-    {
-        $this->sessionName = 'frontEndSession';
-
-        ini_set('session.use_only_cookies', '0');
-        ini_set('session.name', $this->sessionName);
-
-        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
-
-        /** @var \Magento\Framework\Session\SidResolverInterface $sidResolver */
-        $this->_sidResolver = $objectManager->get('Magento\Framework\Session\SidResolverInterface');
-
-        $this->request = $objectManager->get('Magento\Framework\App\RequestInterface');
-
-        /** @var \Magento\Framework\Session\SessionManager _model */
-        $this->_model = $objectManager->create(
-            'Magento\Framework\Session\SessionManager',
-            [
-                $this->request,
-                $this->_sidResolver,
-                $objectManager->get('Magento\Framework\Session\Config\ConfigInterface'),
-                $objectManager->get('Magento\Framework\Session\SaveHandlerInterface'),
-                $objectManager->get('Magento\Framework\Session\ValidatorInterface'),
-                $objectManager->get('Magento\Framework\Session\StorageInterface')
-            ]
-        );
-    }
-
-    public function testSessionNameFromIni()
-    {
-        $this->_model->start();
-        $this->assertSame($this->sessionName, $this->_model->getName());
-        $this->_model->destroy();
-    }
-
-    public function testSessionUseOnlyCookies()
-    {
-        $expectedValue = '1';
-        $sessionUseOnlyCookies = ini_get('session.use_only_cookies');
-        $this->assertSame($expectedValue, $sessionUseOnlyCookies);
-    }
-
-    public function testGetData()
-    {
-        $this->_model->setData(['test_key' => 'test_value']);
-        $this->assertEquals('test_value', $this->_model->getData('test_key', true));
-        $this->assertNull($this->_model->getData('test_key'));
-    }
-
-    public function testGetSessionId()
-    {
-        $this->assertEquals(session_id(), $this->_model->getSessionId());
-    }
-
-    public function testGetName()
-    {
-        $this->assertEquals(session_name(), $this->_model->getName());
-    }
-
-    public function testSetName()
-    {
-        $this->_model->setName('test');
-        $this->assertEquals('test', $this->_model->getName());
-    }
-
-    public function testDestroy()
-    {
-        $data = ['key' => 'value'];
-        $this->_model->setData($data);
-
-        $this->assertEquals($data, $this->_model->getData());
-        $this->_model->destroy();
-
-        $this->assertEquals([], $this->_model->getData());
-    }
+// @codingStandardsIgnoreStart
+namespace {
+    $mockPHPFunctions = false;
+}
 
-    public function testSetSessionId()
-    {
-        $sessionId = $this->_model->getSessionId();
-        $this->_model->setSessionId($this->_sidResolver->getSid($this->_model));
-        $this->assertEquals($sessionId, $this->_model->getSessionId());
-
-        $this->_model->setSessionId('test');
-        $this->assertEquals('test', $this->_model->getSessionId());
-    }
+namespace Magento\Framework\Session {
+    // @codingStandardsIgnoreEnd
 
     /**
-     * @magentoConfigFixture current_store web/session/use_frontend_sid 1
+     * Mock session_status if in test mode, or continue normal execution otherwise
+     *
+     * @return int Session status code
      */
-    public function testSetSessionIdFromParam()
+    function session_status()
     {
-        $this->assertNotEquals('test_id', $this->_model->getSessionId());
-        $this->request->getQuery()->set($this->_sidResolver->getSessionIdQueryParam($this->_model), 'test-id');
-        $this->_model->setSessionId($this->_sidResolver->getSid($this->_model));
-
-        $this->assertEquals('test-id', $this->_model->getSessionId());
-
-        /* Use not valid identifier */
-        $this->request->getQuery()->set($this->_sidResolver->getSessionIdQueryParam($this->_model), 'test_id');
-        $this->_model->setSessionId($this->_sidResolver->getSid($this->_model));
-        $this->assertEquals('test-id', $this->_model->getSessionId());
+        global $mockPHPFunctions;
+        if ($mockPHPFunctions) {
+            return PHP_SESSION_NONE;
+        }
+        return call_user_func_array('\session_status', func_get_args());
     }
 
-    public function testGetSessionIdForHost()
+    function headers_sent()
     {
-        $this->request->getServer()->set('HTTP_HOST', 'localhost');
-        $this->_model->start();
-        $this->assertEmpty($this->_model->getSessionIdForHost('localhost'));
-        $this->assertNotEmpty($this->_model->getSessionIdForHost('test'));
-        $this->_model->destroy();
+        global $mockPHPFunctions;
+        if ($mockPHPFunctions) {
+            return false;
+        }
+        return call_user_func_array('\headers_sent', func_get_args());
     }
 
-    public function testIsValidForHost()
+    class SessionManagerTest extends \PHPUnit_Framework_TestCase
     {
-        $this->request->getServer()->set('HTTP_HOST', 'localhost');
-        $this->_model->start();
-
-        $reflection = new \ReflectionMethod($this->_model, '_addHost');
-        $reflection->setAccessible(true);
-        $reflection->invoke($this->_model);
-
-        $this->assertFalse($this->_model->isValidForHost('test.com'));
-        $this->assertTrue($this->_model->isValidForHost('localhost'));
-        $this->_model->destroy();
+        /**
+         * @var \Magento\Framework\Session\SessionManagerInterface
+         */
+        protected $_model;
+
+        /**
+         * @var \Magento\Framework\Session\SidResolverInterface
+         */
+        protected $_sidResolver;
+
+        /**
+         * @var string
+         */
+        protected $sessionName;
+
+        /**
+         * @var \Magento\Framework\ObjectManagerInterface
+         */
+        protected $objectManager;
+
+        protected function setUp()
+        {
+            $this->sessionName = 'frontEndSession';
+
+            ini_set('session.use_only_cookies', '0');
+            ini_set('session.name', $this->sessionName);
+
+            $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+
+            /** @var \Magento\Framework\Session\SidResolverInterface $sidResolver */
+            $this->_sidResolver = $this->objectManager->get('Magento\Framework\Session\SidResolverInterface');
+
+            $this->request = $this->objectManager->get('Magento\Framework\App\RequestInterface');
+
+            /** @var \Magento\Framework\Session\SessionManager _model */
+            $this->_model = $this->objectManager->create(
+                'Magento\Framework\Session\SessionManager',
+                [
+                    $this->objectManager->get('Magento\Framework\App\Request\Http'),
+                    $this->_sidResolver,
+                    $this->objectManager->get('Magento\Framework\Session\Config\ConfigInterface'),
+                    $this->objectManager->get('Magento\Framework\Session\SaveHandlerInterface'),
+                    $this->objectManager->get('Magento\Framework\Session\ValidatorInterface'),
+                    $this->objectManager->get('Magento\Framework\Session\StorageInterface')
+                ]
+            );
+        }
+
+        public function testSessionNameFromIni()
+        {
+            $this->_model->start();
+            $this->assertSame($this->sessionName, $this->_model->getName());
+            $this->_model->destroy();
+        }
+
+        public function testSessionUseOnlyCookies()
+        {
+            $expectedValue = '1';
+            $sessionUseOnlyCookies = ini_get('session.use_only_cookies');
+            $this->assertSame($expectedValue, $sessionUseOnlyCookies);
+        }
+
+        public function testGetData()
+        {
+            $this->_model->setData(['test_key' => 'test_value']);
+            $this->assertEquals('test_value', $this->_model->getData('test_key', true));
+            $this->assertNull($this->_model->getData('test_key'));
+        }
+
+        public function testGetSessionId()
+        {
+            $this->assertEquals(session_id(), $this->_model->getSessionId());
+        }
+
+        public function testGetName()
+        {
+            $this->assertEquals(session_name(), $this->_model->getName());
+        }
+
+        public function testSetName()
+        {
+            $this->_model->setName('test');
+            $this->assertEquals('test', $this->_model->getName());
+        }
+
+        public function testDestroy()
+        {
+            $data = ['key' => 'value'];
+            $this->_model->setData($data);
+
+            $this->assertEquals($data, $this->_model->getData());
+            $this->_model->destroy();
+
+            $this->assertEquals([], $this->_model->getData());
+        }
+
+        public function testSetSessionId()
+        {
+            $sessionId = $this->_model->getSessionId();
+            $this->_model->setSessionId($this->_sidResolver->getSid($this->_model));
+            $this->assertEquals($sessionId, $this->_model->getSessionId());
+
+            $this->_model->setSessionId('test');
+            $this->assertEquals('test', $this->_model->getSessionId());
+        }
+
+        /**
+         * @magentoConfigFixture current_store web/session/use_frontend_sid 1
+         */
+        public function testSetSessionIdFromParam()
+        {
+            $this->assertNotEquals('test_id', $this->_model->getSessionId());
+            $this->request->getQuery()->set($this->_sidResolver->getSessionIdQueryParam($this->_model), 'test-id');
+            $this->_model->setSessionId($this->_sidResolver->getSid($this->_model));
+            $this->assertEquals('test-id', $this->_model->getSessionId());
+            /* Use not valid identifier */
+            $this->request->getQuery()->set($this->_sidResolver->getSessionIdQueryParam($this->_model), 'test_id');
+            $this->_model->setSessionId($this->_sidResolver->getSid($this->_model));
+            $this->assertEquals('test-id', $this->_model->getSessionId());
+        }
+
+        public function testGetSessionIdForHost()
+        {
+            $_SERVER['HTTP_HOST'] = 'localhost';
+            $this->_model->start();
+            $this->assertEmpty($this->_model->getSessionIdForHost('localhost'));
+            $this->assertNotEmpty($this->_model->getSessionIdForHost('test'));
+            $this->_model->destroy();
+        }
+
+        public function testIsValidForHost()
+        {
+            $_SERVER['HTTP_HOST'] = 'localhost';
+            $this->_model->start();
+
+            $reflection = new \ReflectionMethod($this->_model, '_addHost');
+            $reflection->setAccessible(true);
+            $reflection->invoke($this->_model);
+
+            $this->assertFalse($this->_model->isValidForHost('test.com'));
+            $this->assertTrue($this->_model->isValidForHost('localhost'));
+            $this->_model->destroy();
+        }
+
+
+        /**
+         * @expectedException \Magento\Framework\Exception\SessionException
+         * @expectedExceptionMessage Area code not set: Area code must be set before starting a session.
+         */
+        public function testStartAreaNotSet()
+        {
+            $scope = $this->objectManager->get('Magento\Framework\Config\ScopeInterface');
+            $appState = new \Magento\Framework\App\State($scope);
+
+            /**
+             * Must be created by "new" in order to get a real Magento\Framework\App\State object that
+             * is not overridden in the TestFramework
+             *
+             * @var \Magento\Framework\Session\SessionManager _model
+             */
+            $this->_model = new \Magento\Framework\Session\SessionManager(
+                $this->objectManager->get('Magento\Framework\App\Request\Http'),
+                $this->_sidResolver,
+                $this->objectManager->get('Magento\Framework\Session\Config\ConfigInterface'),
+                $this->objectManager->get('Magento\Framework\Session\SaveHandlerInterface'),
+                $this->objectManager->get('Magento\Framework\Session\ValidatorInterface'),
+                $this->objectManager->get('Magento\Framework\Session\StorageInterface'),
+                $this->objectManager->get('Magento\Framework\Stdlib\CookieManagerInterface'),
+                $this->objectManager->get('Magento\Framework\Stdlib\Cookie\CookieMetadataFactory'),
+                $appState
+            );
+
+            global $mockPHPFunctions;
+            $mockPHPFunctions = true;
+            $this->_model->start();
+        }
     }
 }
diff --git a/dev/tests/integration/testsuite/Magento/Payment/Block/Transparent/IframeTest.php b/dev/tests/integration/testsuite/Magento/Payment/Block/Transparent/IframeTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..c91ead38e49e959564d03b2f90785d4f5e710bdb
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Payment/Block/Transparent/IframeTest.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Payment\Block\Transparent;
+
+class IframeTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @magentoAppIsolation enabled
+     * @magentoAppArea frontend
+     */
+    public function testToHtml()
+    {
+        $xssString = '</script><script>alert("XSS")</script>';
+
+        /** @var $block Iframe */
+        $block = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
+            'Magento\Framework\View\LayoutInterface'
+        )->createBlock(
+            'Magento\Payment\Block\Transparent\Iframe'
+        );
+
+        $block->setTemplate('transparent/iframe.phtml');
+        $block->setData(
+            'params',
+            [
+                'redirect' => $xssString,
+                'redirect_parent' => $xssString,
+                'error_msg' => $xssString
+            ]
+        );
+
+        $content = $block->toHtml();
+
+        $this->assertNotContains($xssString, $content, 'Params mast be escaped');
+        $this->assertContains(htmlspecialchars($xssString), $content, 'Content must present');
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Payment/Model/ObserverTest.php b/dev/tests/integration/testsuite/Magento/Payment/Model/ObserverTest.php
index 14f306766a10720ac021fc9ce9b94ecff8ee08cd..f83337a307eb201a8d5fd2fc8ef9dc8d6005880a 100644
--- a/dev/tests/integration/testsuite/Magento/Payment/Model/ObserverTest.php
+++ b/dev/tests/integration/testsuite/Magento/Payment/Model/ObserverTest.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\Payment\Model;
 
+use Magento\Framework\App\Config\ScopeConfigInterface;
+
 /**
  * @magentoAppArea adminhtml
  */
@@ -68,7 +70,7 @@ class ObserverTest extends \PHPUnit_Framework_TestCase
         $config->saveConfig(
             'payment/checkmo/order_status',
             $statusCode,
-            \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT,
+            ScopeConfigInterface::SCOPE_TYPE_DEFAULT,
             0
         );
 
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 1313db5e278a098d9687b95ed80501862295b0ec..0a35f0488948b5d142693ee2a423f600eab01e7b 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
@@ -7,6 +7,7 @@ namespace Magento\Sales\Controller\Adminhtml\Order;
 
 /**
  * @magentoAppArea adminhtml
+ * @magentoDbIsolation enabled
  */
 class CreateTest extends \Magento\Backend\Utility\Controller
 {
diff --git a/dev/tests/integration/testsuite/Magento/Store/Model/StoreTest.php b/dev/tests/integration/testsuite/Magento/Store/Model/StoreTest.php
index 8fbdd0f346d4b0c410bd35387dd45564504b61f8..a84b46c3c2981e420d24a251db6a0b46cc332eee 100644
--- a/dev/tests/integration/testsuite/Magento/Store/Model/StoreTest.php
+++ b/dev/tests/integration/testsuite/Magento/Store/Model/StoreTest.php
@@ -451,7 +451,8 @@ class StoreTest extends \PHPUnit_Framework_TestCase
             [true, ['HTTPS' => 'on']],
             [true, ['SSL_OFFLOADED' => 'https']],
             [true, ['HTTP_SSL_OFFLOADED' => 'https']],
-            [true, ['SERVER_PORT' => 80]],
+            [true, ['HTTPS' => 'on', 'SERVER_PORT' => 80]],
+            [false, ['SERVER_PORT' => 80]],
             [false, []],
         ];
     }
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
deleted file mode 100644
index 0bc80a86389f29b09fc9d4b80b001347662d97f8..0000000000000000000000000000000000000000
--- a/dev/tests/integration/testsuite/Magento/Tax/Block/Adminhtml/Rate/FormTest.php
+++ /dev/null
@@ -1,57 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Tax\Block\Adminhtml\Rate;
-
-use Magento\TestFramework\Helper\Bootstrap;
-
-class FormTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\Framework\ObjectManagerInterface
-     */
-    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/Controller/Adminhtml/RateTest.php b/dev/tests/integration/testsuite/Magento/Tax/Controller/Adminhtml/RateTest.php
index b6e6a11859231e98d4f303fcec041ff6f690ad38..ab5c6cd2ba0d57b05bd90e250dd4550a254010e1 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/Controller/Adminhtml/RateTest.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/Controller/Adminhtml/RateTest.php
@@ -44,6 +44,11 @@ class RateTest extends \Magento\Backend\Utility\Controller
         $this->assertEquals($expectedData['tax_postcode'], $rate->getTaxPostcode());
     }
 
+    /**
+     * Data provider for testAjaxSaveAction
+     *
+     * @return array
+     */
     public function ajaxSaveActionDataProvider()
     {
         $postData = ['rate' => '10', 'tax_country_id' => 'US', 'tax_region_id' => '1'];
@@ -193,4 +198,102 @@ class RateTest extends \Magento\Backend\Utility\Controller
             ]
         ];
     }
+
+    /**
+     * @dataProvider ajaxSaveActionDataProvider
+     * @magentoDbIsolation enabled
+     *
+     * @param array $rateClassData
+     * @SuppressWarnings(PHPMD.NPathComplexity)
+     */
+    public function testAjaxLoadAction($rateClassData)
+    {
+        /** @var \Magento\Tax\Api\Data\TaxRateInterfaceFactory $rateClassFactory */
+        $rateClassFactory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
+            'Magento\Tax\Api\Data\TaxRateInterfaceFactory'
+        );
+
+        $rateClass = $rateClassFactory->create();
+        $rateClass->setRate($rateClassData['rate'])
+                  ->setTaxCountryId($rateClassData['tax_country_id'])
+                  ->setTaxRegionId($rateClassData['tax_region_id'])
+                  ->setCode($rateClassData['code'])
+                  ->setZipFrom($rateClassData['zip_from'])
+                  ->setZipIsRange($rateClassData['zip_is_range'])
+                  ->setZipFrom($rateClassData['zip_from'])
+                  ->setZipTo($rateClassData['zip_to'])
+                  ->setTaxPostcode($rateClassData['tax_postcode']);
+
+        $rateClass->save($rateClass);
+
+        $rateClassId=$rateClass->getTaxCalculationRateId();
+        /** @var $class \Magento\Tax\Model\Calculation\Rate */
+        $class = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
+            ->create('Magento\Tax\Model\Calculation\Rate')
+            ->load($rateClassId, 'tax_calculation_rate_id');
+
+        $this->assertEquals($rateClassData['tax_country_id'], $class->getTaxCountryId());
+        $this->assertEquals($rateClassData['tax_region_id'], $class->getTaxRegionId());
+        $this->assertEquals($rateClassData['code'], $class->getCode());
+        $this->assertEquals($rateClassData['rate'], $class->getRate());
+        $this->assertEquals($rateClassData['zip_is_range']==1 ? 1 : 0, $class->getZipIsRange() ? 1 : 0);
+        if ($rateClassData['zip_is_range']=='1') {
+            $this->assertEquals($rateClassData['zip_from'], $class->getZipFrom());
+            $this->assertEquals($rateClassData['zip_to'], $class->getZipTo());
+        }
+
+        $postData = [ 'id' => $rateClassId ];
+        $this->getRequest()->setPostValue($postData);
+        $this->dispatch('backend/tax/rate/ajaxLoad');
+        $jsonBody = $this->getResponse()->getBody();
+
+        $result = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
+            'Magento\Framework\Json\Helper\Data'
+        )->jsonDecode(
+            $jsonBody
+        );
+
+        $this->assertTrue(is_array($result));
+        $this->assertArrayHasKey('success', $result);
+        $this->assertTrue($result['success'] == true);
+        $this->assertArrayHasKey('result', $result);
+        $this->assertTrue(is_array($result['result']));
+        $this->assertEquals($result['result']['tax_country_id'], $class->getTaxCountryId());
+        $this->assertEquals($result['result']['tax_region_id'], $class->getTaxRegionId());
+        $this->assertEquals($result['result']['tax_postcode'], $class->getTaxPostcode());
+        $this->assertEquals($result['result']['code'], $class->getCode());
+        $this->assertEquals($result['result']['rate'], $class->getRate());
+
+        $expectedZipIsRange=$result['result']['zip_is_range'] == 1  ? 1 : 0;
+        $this->assertEquals($expectedZipIsRange, $class->getZipIsRange() ? 1 : 0);
+        if ($expectedZipIsRange) {
+            $this->assertEquals($result['result']['zip_from'], $class->getZipFrom());
+            $this->assertEquals($result['result']['zip_to'], $class->getZipTo());
+        }
+    }
+
+    /**
+     * @magentoDbIsolation enabled
+     *
+     */
+    public function testAjaxNonLoadAction()
+    {
+        $postData = [ 'id' => 99999999 ];
+        $this->getRequest()->setPostValue($postData);
+        $this->dispatch('backend/tax/rate/ajaxLoad');
+        $jsonBody = $this->getResponse()->getBody();
+
+        $result = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
+            'Magento\Framework\Json\Helper\Data'
+        )->jsonDecode(
+            $jsonBody
+        );
+
+        $this->assertTrue(is_array($result));
+        $this->assertArrayHasKey('success', $result);
+        $this->assertTrue($result['success'] == false);
+        $this->assertTrue(!array_key_exists('result', $result));
+        $this->assertArrayHasKey('error_message', $result);
+        $this->assertTrue(strlen($result['error_message'])>0);
+    }
 }
diff --git a/dev/tests/integration/testsuite/Magento/Tax/Model/Calculation/RateRepositoryTest.php b/dev/tests/integration/testsuite/Magento/Tax/Model/Calculation/RateRepositoryTest.php
index 1e9c43ca7fd49621116be74791c4a180c2c4763d..2b0d311757846900c2a9b1f9ccffb29cd221d4c1 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/Model/Calculation/RateRepositoryTest.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/Model/Calculation/RateRepositoryTest.php
@@ -9,6 +9,7 @@ namespace Magento\Tax\Model\Calculation;
 use Magento\Framework\Exception\InputException;
 use Magento\Framework\Exception\NoSuchEntityException;
 use Magento\Tax\Api\Data\TaxRateInterface;
+use Magento\Tax\Model\Calculation\Rate;
 use Magento\Tax\Model\TaxRuleFixtureFactory;
 use Magento\TestFramework\Helper\Bootstrap;
 
@@ -566,14 +567,14 @@ class RateRepositoryTest extends \PHPUnit_Framework_TestCase
 
         return [
             'eq' => [
-                [$filterBuilder->setField(TaxRateInterface::KEY_REGION_ID)->setValue(42)->create()],
+                [$filterBuilder->setField(Rate::KEY_REGION_ID)->setValue(42)->create()],
                 null,
                 ['US - 42 - 7.5', 'US - 42 - 22'],
             ],
             'and' => [
                 [
-                    $filterBuilder->setField(TaxRateInterface::KEY_REGION_ID)->setValue(42)->create(),
-                    $filterBuilder->setField(TaxRateInterface::KEY_PERCENTAGE_RATE)->setValue(22.0)->create(),
+                    $filterBuilder->setField(Rate::KEY_REGION_ID)->setValue(42)->create(),
+                    $filterBuilder->setField(Rate::KEY_PERCENTAGE_RATE)->setValue(22.0)->create(),
                 ],
                 [],
                 ['US - 42 - 22'],
@@ -581,15 +582,14 @@ class RateRepositoryTest extends \PHPUnit_Framework_TestCase
             'or' => [
                 [],
                 [
-                    $filterBuilder->setField(TaxRateInterface::KEY_PERCENTAGE_RATE)->setValue(22.0)->create(),
-                    $filterBuilder->setField(TaxRateInterface::KEY_PERCENTAGE_RATE)->setValue(10.0)->create(),
+                    $filterBuilder->setField(Rate::KEY_PERCENTAGE_RATE)->setValue(22.0)->create(),
+                    $filterBuilder->setField(Rate::KEY_PERCENTAGE_RATE)->setValue(10.0)->create(),
                 ],
                 ['US - 42 - 22', 'US - 12 - 10'],
             ],
             'like' => [
                 [
-                    $filterBuilder->setField(TaxRateInterface::KEY_CODE)->setValue('%7.5')->setConditionType('like')
-                        ->create(),
+                    $filterBuilder->setField(Rate::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/Model/Sales/Total/Quote/SetupUtil.php b/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/SetupUtil.php
index 861079efbac7df145af34557037fa6b79bb886e0..331bfebab31ad4078259e912e982010cb44302e6 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/SetupUtil.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/SetupUtil.php
@@ -8,6 +8,7 @@
 
 namespace Magento\Tax\Model\Sales\Total\Quote;
 
+use Magento\Framework\App\Config\ScopeConfigInterface;
 use Magento\Tax\Model\Config;
 use Magento\Tax\Model\Calculation;
 
@@ -221,7 +222,7 @@ class SetupUtil
             $config->saveConfig(
                 $path,
                 $value,
-                \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT,
+                ScopeConfigInterface::SCOPE_TYPE_DEFAULT,
                 0
             );
         }
diff --git a/dev/tests/integration/testsuite/Magento/Tax/Model/TaxCalculationTest.php b/dev/tests/integration/testsuite/Magento/Tax/Model/TaxCalculationTest.php
index 0c3af306bdeaa8f70d4a0b9e3e0d4bda252693e1..4f8e5da64ba2d3f77397905e9a470127626a84a6 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/Model/TaxCalculationTest.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/Model/TaxCalculationTest.php
@@ -5,8 +5,8 @@
  */
 namespace Magento\Tax\Model;
 
-use Magento\Framework\Model\AbstractExtensibleModel;
 use Magento\Tax\Api\Data\TaxClassKeyInterface;
+use Magento\Tax\Model\TaxClass\Key;
 use Magento\TestFramework\Helper\Bootstrap;
 
 /**
@@ -121,8 +121,8 @@ class TaxCalculationTest extends \PHPUnit_Framework_TestCase
             'quantity' => 2,
             'unit_price' => 10,
             'tax_class_key' => [
-                TaxClassKeyInterface::KEY_TYPE => TaxClassKeyInterface::TYPE_NAME,
-                TaxClassKeyInterface::KEY_VALUE => 'DefaultProductClass',
+                Key::KEY_TYPE => TaxClassKeyInterface::TYPE_NAME,
+                Key::KEY_VALUE => 'DefaultProductClass',
             ],
         ];
         $oneProductResults = [
@@ -649,8 +649,8 @@ class TaxCalculationTest extends \PHPUnit_Framework_TestCase
                     ],
                 ],
                 'customer_tax_class_key' => [
-                    TaxClassKeyInterface::KEY_TYPE => TaxClassKeyInterface::TYPE_NAME,
-                    TaxClassKeyInterface::KEY_VALUE => 'DefaultCustomerClass',
+                    Key::KEY_TYPE => TaxClassKeyInterface::TYPE_NAME,
+                    Key::KEY_VALUE => 'DefaultCustomerClass',
                 ],
             ],
             'expected_tax_details' => [
@@ -1064,8 +1064,8 @@ class TaxCalculationTest extends \PHPUnit_Framework_TestCase
             'quantity' => 9,
             'unit_price' => 0.33, // this is including the store tax of 10%. Pre tax is 0.3
             'tax_class_key' => [
-                TaxClassKeyInterface::KEY_TYPE => TaxClassKeyInterface::TYPE_NAME,
-                TaxClassKeyInterface::KEY_VALUE => 'HigherProductClass',
+                Key::KEY_TYPE => TaxClassKeyInterface::TYPE_NAME,
+                Key::KEY_VALUE => 'HigherProductClass',
             ],
             'tax_included' => true,
         ];
@@ -1817,8 +1817,8 @@ class TaxCalculationTest extends \PHPUnit_Framework_TestCase
                     && is_string($value)
                 ) {
                     $value = [
-                        TaxClassKeyInterface::KEY_TYPE => TaxClassKeyInterface::TYPE_ID,
-                        TaxClassKeyInterface::KEY_VALUE => $this->taxClassIds[$value],
+                        Key::KEY_TYPE => TaxClassKeyInterface::TYPE_ID,
+                        Key::KEY_VALUE => $this->taxClassIds[$value],
                     ];
                 }
             }
diff --git a/dev/tests/integration/testsuite/Magento/Tax/Model/TaxClass/ManagementTest.php b/dev/tests/integration/testsuite/Magento/Tax/Model/TaxClass/ManagementTest.php
index 606540aa09c90b91c3b41a2c6345447a247bfd38..853a42f225c85c999748b0763388cc58d48a83e9 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/Model/TaxClass/ManagementTest.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/Model/TaxClass/ManagementTest.php
@@ -8,6 +8,7 @@ namespace Magento\Tax\Model\TaxClass;
 use Magento\Tax\Api\Data\TaxClassInterfaceFactory;
 use Magento\Tax\Api\Data\TaxClassKeyInterface;
 use Magento\Tax\Api\TaxClassManagementInterface;
+use Magento\Tax\Model\TaxClass\Key;
 use Magento\TestFramework\Helper\Bootstrap;
 
 class ManagementTest extends \PHPUnit_Framework_TestCase
@@ -63,8 +64,8 @@ class ManagementTest extends \PHPUnit_Framework_TestCase
         $this->dataObjectHelper->populateWithArray(
             $taxClassKeyTypeId,
             [
-                TaxClassKeyInterface::KEY_TYPE => TaxClassKeyInterface::TYPE_ID,
-                TaxClassKeyInterface::KEY_VALUE => $taxClassId,
+                Key::KEY_TYPE => TaxClassKeyInterface::TYPE_ID,
+                Key::KEY_VALUE => $taxClassId,
             ],
             '\Magento\Tax\Api\Data\TaxClassKeyInterface'
         );
@@ -76,8 +77,8 @@ class ManagementTest extends \PHPUnit_Framework_TestCase
         $this->dataObjectHelper->populateWithArray(
             $taxClassKeyTypeName,
             [
-                TaxClassKeyInterface::KEY_TYPE => TaxClassKeyInterface::TYPE_NAME,
-                TaxClassKeyInterface::KEY_VALUE => $taxClassName,
+                Key::KEY_TYPE => TaxClassKeyInterface::TYPE_NAME,
+                Key::KEY_VALUE => $taxClassName,
             ],
             '\Magento\Tax\Api\Data\TaxClassKeyInterface'
         );
diff --git a/dev/tests/integration/testsuite/Magento/Test/Integrity/Magento/Payment/MethodsTest.php b/dev/tests/integration/testsuite/Magento/Test/Integrity/Magento/Payment/MethodsTest.php
index 56dfca42c97498e1a5a08510b766b7b925cfeb71..a0073fdd17b0ff1c859e85ec12dc0bc992c6f74c 100644
--- a/dev/tests/integration/testsuite/Magento/Test/Integrity/Magento/Payment/MethodsTest.php
+++ b/dev/tests/integration/testsuite/Magento/Test/Integrity/Magento/Payment/MethodsTest.php
@@ -60,7 +60,7 @@ class MethodsTest extends \PHPUnit_Framework_TestCase
             /** @var $block \Magento\Framework\View\Element\Template */
             $block = $blockFactory->createBlock($blockClass);
             $block->setArea('frontend');
-            $this->assertFileExists($block->getTemplateFile(), $message);
+            $this->assertFileExists((string)$block->getTemplateFile(), $message);
             if ($model->canUseInternal()) {
                 try {
                     \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
@@ -69,7 +69,7 @@ class MethodsTest extends \PHPUnit_Framework_TestCase
                         \Magento\Store\Model\Store::DEFAULT_STORE_ID
                     );
                     $block->setArea('adminhtml');
-                    $this->assertFileExists($block->getTemplateFile(), $message);
+                    $this->assertFileExists((string)$block->getTemplateFile(), $message);
                     \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
                         'Magento\Store\Model\StoreManagerInterface'
                     )->getStore()->setId(
diff --git a/dev/tests/integration/testsuite/Magento/ToolkitFramework/_files/small.xml b/dev/tests/integration/testsuite/Magento/ToolkitFramework/_files/small.xml
index 4c0292a8c2f0d5fd009882546a65c9258892e66c..0a0b04ba6836b74eb5d7584a9290136e540f8d8b 100644
--- a/dev/tests/integration/testsuite/Magento/ToolkitFramework/_files/small.xml
+++ b/dev/tests/integration/testsuite/Magento/ToolkitFramework/_files/small.xml
@@ -29,6 +29,8 @@
         <!-- The price rule condition: minimum products amount in shopping cart for price rule to be applied -->
         <customers>20</customers>
         <!-- Number of customers to generate -->
+        <orders>80</orders>
+        <!-- Orders count -->
         <configs> <!-- Config variables and values for change -->
             <config>
                 <path>admin/security/use_form_key</path>
@@ -61,7 +63,7 @@
                 <value>0</value>
             </config>
             <config>
-                <path>system/full_page_cache/varnish/access_lis</path>
+                <path>system/full_page_cache/varnish/access_list</path>
                 <scope>default</scope>
                 <scopeId>0</scopeId>
                 <value>localhost</value>
@@ -79,5 +81,39 @@
                 <value>8080</value>
             </config>
         </configs>
+        <indexers> <!-- Indexer mode value (true - Update by Schedule, false - Update on Save) -->
+            <indexer>
+                <id>catalog_category_product</id>
+                <set_scheduled>false</set_scheduled>
+            </indexer>
+            <indexer>
+                <id>catalog_product_category</id>
+                <set_scheduled>false</set_scheduled>
+            </indexer>
+            <indexer>
+                <id>catalog_product_price</id>
+                <set_scheduled>false</set_scheduled>
+            </indexer>
+            <indexer>
+                <id>catalog_product_attribute</id>
+                <set_scheduled>false</set_scheduled>
+            </indexer>
+            <indexer>
+                <id>cataloginventory_stock</id>
+                <set_scheduled>false</set_scheduled>
+            </indexer>
+            <indexer>
+                <id>catalogrule_rule</id>
+                <set_scheduled>false</set_scheduled>
+            </indexer>
+            <indexer>
+                <id>catalogrule_product</id>
+                <set_scheduled>false</set_scheduled>
+            </indexer>
+            <indexer>
+                <id>catalogsearch_fulltext</id>
+                <set_scheduled>false</set_scheduled>
+            </indexer>
+        </indexers>
     </profile>
-</config>
\ No newline at end of file
+</config>
diff --git a/dev/tests/js/jasmine/assets/apply/templates/node.html b/dev/tests/js/jasmine/assets/apply/templates/node.html
index 3c6895d98c381b7d64f7210dd5b83b5e04235255..f694083783e00922b7faa63eecb5155251cc0f5a 100644
--- a/dev/tests/js/jasmine/assets/apply/templates/node.html
+++ b/dev/tests/js/jasmine/assets/apply/templates/node.html
@@ -5,6 +5,6 @@
  */
 -->
 <div id="<%= containerId %>">
-    <div id="<%= nodeId %>"
+    <div id="<%= nodeId %>">
         <%= dataAttr %>='<%= JSON.stringify(nodeData) %>'></div>
 </div>
\ No newline at end of file
diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/columns/multiselect.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/columns/multiselect.test.js
new file mode 100644
index 0000000000000000000000000000000000000000..0d68a9dcfa145676d90bd99803fe11ece671d5b0
--- /dev/null
+++ b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/columns/multiselect.test.js
@@ -0,0 +1,150 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+define([
+    'underscore',
+    'Magento_Ui/js/grid/columns/multiselect'
+], function (_, Multiselect) {
+    'use strict';
+
+    describe('ui/js/grid/columns/multiselect', function () {
+        var multiSelect;
+
+        beforeEach(function () {
+            multiSelect = new Multiselect({
+                rows: [],
+                index: 'index',
+                name: 'name',
+                indexField: 'id',
+                dataScope: 'scope',
+                provider: 'provider'
+            });
+            multiSelect.source = {
+                set: function () {}
+            };
+            spyOn(multiSelect.source, 'set');
+        });
+
+        afterEach(function () {
+        });
+
+        it('Default state - Select no rows', function () {
+            multiSelect.rows.push({id:1});
+            multiSelect.rows.push({id:2});
+            multiSelect.rows.push({id:3});
+
+            expect(multiSelect.allSelected()).toBeFalsy();
+            expect(multiSelect.excluded()).toEqual([]);
+            expect(multiSelect.selected()).toEqual([]);
+            multiSelect.exportSelections();
+            //expect(multiSelect.source.set).toHaveBeenCalledWith([]);
+            expect(multiSelect.source.set.calls.argsFor(1))
+                .toEqual([]);
+        });
+
+        it('Select specific several rows on several pages', function () {
+            multiSelect.selected.push(4);
+            multiSelect.selected.push(5);
+
+            expect(multiSelect.allSelected()).toBeFalsy();
+            expect(multiSelect.excluded()).toEqual([]);
+            expect(multiSelect.selected()).toEqual([4,5]);
+        });
+
+        it('Select all rows on several pages', function () {
+            multiSelect.rows([
+                {id:1},
+                {id:2}
+            ]);
+            multiSelect.selectPage();
+            multiSelect.rows([
+                {id:3},
+                {id:4}
+            ]);
+            multiSelect.selectPage();
+
+            expect(multiSelect.allSelected()).toBeFalsy();
+            expect(multiSelect.excluded()).toEqual([]);
+            expect(multiSelect.selected()).toEqual([1,2,3,4]);
+        });
+
+        it('Select all rows on current page with some specific rows on another page', function () {
+            multiSelect.rows([
+                {id:1},
+                {id:2}
+            ]);
+            multiSelect.rows([
+                {id:3},
+                {id:4}
+            ]);
+            multiSelect.selectPage();
+            multiSelect.rows([
+                {id:5},
+                {id:6}
+            ]);
+            multiSelect.selected.push(6);
+
+            expect(multiSelect.allSelected()).toBeFalsy();
+            expect(multiSelect.excluded()).toEqual([]);
+            expect(multiSelect.selected()).toEqual([3,4,6]);
+        });
+
+        it('Select all rows on several pages without some specific rows', function () {
+            multiSelect.rows([
+                {id:1},
+                {id:2}
+            ]);
+            multiSelect.rows([
+                {id:3},
+                {id:4}
+            ]);
+            multiSelect.selectPage();
+            multiSelect.selected.remove(4); // remove second
+
+            expect(multiSelect.allSelected()).toBeFalsy();
+            expect(multiSelect.excluded()).toEqual([]);
+            expect(multiSelect.selected()).toEqual([3]);
+        });
+
+        it('Select all rows all over the Grid', function () {
+            multiSelect.rows([
+                {id:1},
+                {id:2}
+            ]);
+            multiSelect.selectAll();
+            multiSelect.rows([
+                {id:3},
+                {id:4}
+            ]);
+
+            expect(multiSelect.allSelected()).toBeFalsy();
+            expect(multiSelect.excluded()).toEqual([]);
+            expect(multiSelect.selected()).toEqual([1,2]);
+        });
+
+        it('Select all rows all over the Grid without all rows on current page but with specific rows on another page', function () {
+            multiSelect.rows([
+                {id:1},
+                {id:2}
+            ]);
+            multiSelect.rows([
+                {id:3},
+                {id:4}
+            ]);
+            multiSelect.selectAll();
+            multiSelect.deselectPage();
+            multiSelect.rows([
+                {id:5},
+                {id:6}
+            ]);
+            multiSelect.selected.push(6);
+
+            expect(multiSelect.allSelected()).toBeFalsy();
+            expect(multiSelect.excluded()).toEqual([]);
+            expect(multiSelect.selected()).toEqual([6]);
+        });
+
+    });
+});
\ No newline at end of file
diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/controls/columns.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/controls/columns.test.js
new file mode 100644
index 0000000000000000000000000000000000000000..e01b4eb1d22910908e2540a6e8b71a7a4dad7414
--- /dev/null
+++ b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/controls/columns.test.js
@@ -0,0 +1,64 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+define([
+    'underscore',
+    'Magento_Ui/js/grid/controls/columns'
+], function (_, Columns) {
+    'use strict';
+
+    describe('ui/js/grid/controls/columns', function () {
+        var columnsInstance,
+            FakeElement;
+
+        beforeEach(function () {
+            columnsInstance = new Columns({
+                elems: [],
+                index: 'index',
+                name: 'name',
+                indexField: 'id',
+                dataScope: 'scope',
+                provider: 'provider'
+            });
+            FakeElement = function(){
+                return this;
+            };
+            FakeElement.prototype.visible = function(){
+                return true;
+            };
+        });
+
+        it('hasOverflow method', function () {
+            columnsInstance.viewportSize = 2;
+            columnsInstance.elems.push({id:1});
+            columnsInstance.elems.push({id:2});
+
+            expect(columnsInstance.hasOverflow()).toBeFalsy();
+
+            columnsInstance.elems.push({id:3});
+            expect(columnsInstance.hasOverflow()).toBeTruthy();
+        });
+
+        it('isDisabled method', function () {
+            columnsInstance.viewportMaxSize = 4;
+            columnsInstance.elems.push(new FakeElement());
+            expect(columnsInstance.isDisabled(columnsInstance.elems()[0])).toBeTruthy();
+
+            columnsInstance.elems.push(new FakeElement());
+            expect(columnsInstance.isDisabled(columnsInstance.elems()[0])).toBeFalsy();
+
+            columnsInstance.elems.push(new FakeElement());
+            expect(columnsInstance.isDisabled(columnsInstance.elems()[0])).toBeFalsy();
+
+            columnsInstance.elems.push(new FakeElement());
+            expect(columnsInstance.isDisabled(columnsInstance.elems()[0])).toBeFalsy();
+
+            columnsInstance.elems.push(new FakeElement());
+            expect(columnsInstance.isDisabled(columnsInstance.elems()[0])).toBeTruthy();
+            expect(columnsInstance.isDisabled(columnsInstance.elems()[3])).toBeTruthy();
+        });
+
+    });
+});
\ No newline at end of file
diff --git a/dev/tests/performance/benchmark.jmx b/dev/tests/performance/benchmark.jmx
index 34b8617830f417808bcc2e5086b8ecf6efe94c72..af952a0e59cd8c3e4e8a43c08eb8af68c9287140 100644
--- a/dev/tests/performance/benchmark.jmx
+++ b/dev/tests/performance/benchmark.jmx
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
 -->
-<jmeterTestPlan version="1.2" properties="2.6" jmeter="2.11 r1554548">
+<jmeterTestPlan version="1.2" properties="2.7" jmeter="2.12 r1636949">
   <hashTree>
     <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Toolkit" enabled="true">
       <stringProp name="TestPlan.comments"></stringProp>
@@ -53,14 +53,14 @@
             <stringProp name="Argument.value">${__P(admin_path,backend)}</stringProp>
             <stringProp name="Argument.metadata">=</stringProp>
           </elementProp>
-          <elementProp name="admin_user" elementType="Argument">
-            <stringProp name="Argument.name">admin_user</stringProp>
-            <stringProp name="Argument.value">${__P(admin_user,admin)}</stringProp>
+          <elementProp name="admin-user" elementType="Argument">
+            <stringProp name="Argument.name">admin-user</stringProp>
+            <stringProp name="Argument.value">${__P(admin-user,admin)}</stringProp>
             <stringProp name="Argument.metadata">=</stringProp>
           </elementProp>
-          <elementProp name="admin_password" elementType="Argument">
-            <stringProp name="Argument.name">admin_password</stringProp>
-            <stringProp name="Argument.value">${__P(admin_password,123123q)}</stringProp>
+          <elementProp name="admin-password" elementType="Argument">
+            <stringProp name="Argument.name">admin-password</stringProp>
+            <stringProp name="Argument.value">${__P(admin-password,123123q)}</stringProp>
             <stringProp name="Argument.metadata">=</stringProp>
           </elementProp>
           <elementProp name="response_time_file_name" elementType="Argument">
@@ -116,9 +116,10 @@
         <stringProp name="HTTPSampler.port"></stringProp>
         <stringProp name="HTTPSampler.connect_timeout"></stringProp>
         <stringProp name="HTTPSampler.response_timeout"></stringProp>
-        <stringProp name="HTTPSampler.protocol"></stringProp>
-        <stringProp name="HTTPSampler.contentEncoding"></stringProp>
+        <stringProp name="HTTPSampler.protocol">http</stringProp>
+        <stringProp name="HTTPSampler.contentEncoding">utf-8</stringProp>
         <stringProp name="HTTPSampler.path"></stringProp>
+        <stringProp name="HTTPSampler.implementation">HttpClient4</stringProp>
         <stringProp name="HTTPSampler.concurrentPool">4</stringProp>
       </ConfigTestElement>
       <hashTree/>
@@ -196,15 +197,14 @@
           <stringProp name="HTTPSampler.port"></stringProp>
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
-          <stringProp name="HTTPSampler.protocol">http</stringProp>
-          <stringProp name="HTTPSampler.contentEncoding">UTF-8</stringProp>
+          <stringProp name="HTTPSampler.protocol"></stringProp>
+          <stringProp name="HTTPSampler.contentEncoding"></stringProp>
           <stringProp name="HTTPSampler.path">${base_path}${admin_path}</stringProp>
           <stringProp name="HTTPSampler.method">GET</stringProp>
           <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -259,14 +259,14 @@
               </elementProp>
               <elementProp name="login[password]" elementType="HTTPArgument">
                 <boolProp name="HTTPArgument.always_encode">true</boolProp>
-                <stringProp name="Argument.value">${admin_password}</stringProp>
+                <stringProp name="Argument.value">${admin-password}</stringProp>
                 <stringProp name="Argument.metadata">=</stringProp>
                 <boolProp name="HTTPArgument.use_equals">true</boolProp>
                 <stringProp name="Argument.name">login[password]</stringProp>
               </elementProp>
               <elementProp name="login[username]" elementType="HTTPArgument">
                 <boolProp name="HTTPArgument.always_encode">true</boolProp>
-                <stringProp name="Argument.value">${admin_user}</stringProp>
+                <stringProp name="Argument.value">${admin-user}</stringProp>
                 <stringProp name="Argument.metadata">=</stringProp>
                 <boolProp name="HTTPArgument.use_equals">true</boolProp>
                 <stringProp name="Argument.name">login[username]</stringProp>
@@ -277,15 +277,14 @@
           <stringProp name="HTTPSampler.port"></stringProp>
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
-          <stringProp name="HTTPSampler.protocol">http</stringProp>
-          <stringProp name="HTTPSampler.contentEncoding">UTF-8</stringProp>
+          <stringProp name="HTTPSampler.protocol"></stringProp>
+          <stringProp name="HTTPSampler.contentEncoding"></stringProp>
           <stringProp name="HTTPSampler.path">${base_path}${admin_path}</stringProp>
           <stringProp name="HTTPSampler.method">POST</stringProp>
           <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -344,15 +343,14 @@
           <stringProp name="HTTPSampler.port"></stringProp>
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
-          <stringProp name="HTTPSampler.protocol">http</stringProp>
-          <stringProp name="HTTPSampler.contentEncoding">UTF-8</stringProp>
+          <stringProp name="HTTPSampler.protocol"></stringProp>
+          <stringProp name="HTTPSampler.contentEncoding"></stringProp>
           <stringProp name="HTTPSampler.path">${base_path}${admin_path}/admin/cache/massDisable/</stringProp>
           <stringProp name="HTTPSampler.method">POST</stringProp>
           <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -396,7 +394,7 @@
           <stringProp name="HTTPSampler.port"></stringProp>
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
-          <stringProp name="HTTPSampler.protocol">http</stringProp>
+          <stringProp name="HTTPSampler.protocol"></stringProp>
           <stringProp name="HTTPSampler.contentEncoding"></stringProp>
           <stringProp name="HTTPSampler.path">${base_path}</stringProp>
           <stringProp name="HTTPSampler.method">GET</stringProp>
@@ -404,7 +402,6 @@
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -431,7 +428,7 @@
           <stringProp name="HTTPSampler.port"></stringProp>
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
-          <stringProp name="HTTPSampler.protocol">http</stringProp>
+          <stringProp name="HTTPSampler.protocol"></stringProp>
           <stringProp name="HTTPSampler.contentEncoding"></stringProp>
           <stringProp name="HTTPSampler.path">${base_path}${category_url_key}${url_suffix}</stringProp>
           <stringProp name="HTTPSampler.method">GET</stringProp>
@@ -439,7 +436,6 @@
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -466,7 +462,7 @@
           <stringProp name="HTTPSampler.port"></stringProp>
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
-          <stringProp name="HTTPSampler.protocol">http</stringProp>
+          <stringProp name="HTTPSampler.protocol"></stringProp>
           <stringProp name="HTTPSampler.contentEncoding"></stringProp>
           <stringProp name="HTTPSampler.path">${base_path}${simple_product_url_key}${url_suffix}</stringProp>
           <stringProp name="HTTPSampler.method">GET</stringProp>
@@ -474,7 +470,6 @@
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -489,7 +484,7 @@
             <intProp name="Assertion.test_type">2</intProp>
           </ResponseAssertion>
           <hashTree/>
-          <XPathExtractor guiclass="XPathExtractorGui" testclass="XPathExtractor" testname="XPath Extractor: Extarct product id" enabled="true">
+          <XPathExtractor guiclass="XPathExtractorGui" testclass="XPathExtractor" testname="XPath Extractor: Extract product id" enabled="true">
             <stringProp name="XPathExtractor.default"></stringProp>
             <stringProp name="XPathExtractor.refname">simple_product_id</stringProp>
             <stringProp name="XPathExtractor.xpathQuery">.//input[@type=&quot;hidden&quot; and @name=&quot;product&quot;]/@value</stringProp>
@@ -533,7 +528,7 @@
           <stringProp name="HTTPSampler.port"></stringProp>
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
-          <stringProp name="HTTPSampler.protocol">http</stringProp>
+          <stringProp name="HTTPSampler.protocol"></stringProp>
           <stringProp name="HTTPSampler.contentEncoding"></stringProp>
           <stringProp name="HTTPSampler.path">${base_path}checkout/cart/add</stringProp>
           <stringProp name="HTTPSampler.method">POST</stringProp>
@@ -541,7 +536,6 @@
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -589,7 +583,7 @@
           <stringProp name="HTTPSampler.port"></stringProp>
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
-          <stringProp name="HTTPSampler.protocol">http</stringProp>
+          <stringProp name="HTTPSampler.protocol"></stringProp>
           <stringProp name="HTTPSampler.contentEncoding"></stringProp>
           <stringProp name="HTTPSampler.path">${base_path}${configurable_product_url_key}${url_suffix}</stringProp>
           <stringProp name="HTTPSampler.method">GET</stringProp>
@@ -597,7 +591,6 @@
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -612,7 +605,7 @@
             <intProp name="Assertion.test_type">2</intProp>
           </ResponseAssertion>
           <hashTree/>
-          <XPathExtractor guiclass="XPathExtractorGui" testclass="XPathExtractor" testname="XPath Extractor: Extarct product id" enabled="true">
+          <XPathExtractor guiclass="XPathExtractorGui" testclass="XPathExtractor" testname="XPath Extractor: Extract product id" enabled="true">
             <stringProp name="XPathExtractor.default"></stringProp>
             <stringProp name="XPathExtractor.refname">configurable_product_id</stringProp>
             <stringProp name="XPathExtractor.xpathQuery">.//input[@type=&quot;hidden&quot; and @name=&quot;product&quot;]/@value</stringProp>
@@ -621,7 +614,7 @@
             <boolProp name="XPathExtractor.namespace">false</boolProp>
           </XPathExtractor>
           <hashTree/>
-          <RegexExtractor guiclass="RegexExtractorGui" testclass="RegexExtractor" testname="Regular Expression Extractor: Extarct product attribute id" enabled="true">
+          <RegexExtractor guiclass="RegexExtractorGui" testclass="RegexExtractor" testname="Regular Expression Extractor: Extract product attribute id" enabled="true">
             <stringProp name="RegexExtractor.useHeaders">false</stringProp>
             <stringProp name="RegexExtractor.refname">configurable_attribute_id</stringProp>
             <stringProp name="RegexExtractor.regex">&quot;spConfig&quot;:[\s]*\{&quot;attributes&quot;:\{&quot;(\d+)&quot;</stringProp>
@@ -630,7 +623,7 @@
             <stringProp name="RegexExtractor.match_number">1</stringProp>
           </RegexExtractor>
           <hashTree/>
-          <RegexExtractor guiclass="RegexExtractorGui" testclass="RegexExtractor" testname="Regular Expression Extractor: Extarct product attribute option id" enabled="true">
+          <RegexExtractor guiclass="RegexExtractorGui" testclass="RegexExtractor" testname="Regular Expression Extractor: Extract product attribute option id" enabled="true">
             <stringProp name="RegexExtractor.useHeaders">false</stringProp>
             <stringProp name="RegexExtractor.refname">configurable_option_id</stringProp>
             <stringProp name="RegexExtractor.regex">&quot;options&quot;:\[\{&quot;id&quot;:&quot;(\d+)&quot;</stringProp>
@@ -681,7 +674,7 @@
           <stringProp name="HTTPSampler.port"></stringProp>
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
-          <stringProp name="HTTPSampler.protocol">http</stringProp>
+          <stringProp name="HTTPSampler.protocol"></stringProp>
           <stringProp name="HTTPSampler.contentEncoding"></stringProp>
           <stringProp name="HTTPSampler.path">${base_path}checkout/cart/add</stringProp>
           <stringProp name="HTTPSampler.method">POST</stringProp>
@@ -689,7 +682,6 @@
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -737,7 +729,7 @@
           <stringProp name="HTTPSampler.port"></stringProp>
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
-          <stringProp name="HTTPSampler.protocol">http</stringProp>
+          <stringProp name="HTTPSampler.protocol"></stringProp>
           <stringProp name="HTTPSampler.contentEncoding"></stringProp>
           <stringProp name="HTTPSampler.path">${base_path}checkout/onepage/</stringProp>
           <stringProp name="HTTPSampler.method">GET</stringProp>
@@ -745,7 +737,6 @@
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -830,15 +821,14 @@
           <stringProp name="HTTPSampler.port"></stringProp>
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
-          <stringProp name="HTTPSampler.protocol">http</stringProp>
-          <stringProp name="HTTPSampler.contentEncoding">UTF-8</stringProp>
+          <stringProp name="HTTPSampler.protocol"></stringProp>
+          <stringProp name="HTTPSampler.contentEncoding"></stringProp>
           <stringProp name="HTTPSampler.path">${base_path}customer/account/loginPost/</stringProp>
           <stringProp name="HTTPSampler.method">POST</stringProp>
           <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -987,15 +977,14 @@
           <stringProp name="HTTPSampler.port"></stringProp>
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
-          <stringProp name="HTTPSampler.protocol">http</stringProp>
-          <stringProp name="HTTPSampler.contentEncoding">UTF-8</stringProp>
+          <stringProp name="HTTPSampler.protocol"></stringProp>
+          <stringProp name="HTTPSampler.contentEncoding"></stringProp>
           <stringProp name="HTTPSampler.path">${base_path}checkout/onepage/saveBilling/</stringProp>
           <stringProp name="HTTPSampler.method">POST</stringProp>
           <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -1058,15 +1047,14 @@
           <stringProp name="HTTPSampler.port"></stringProp>
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
-          <stringProp name="HTTPSampler.protocol">http</stringProp>
-          <stringProp name="HTTPSampler.contentEncoding">UTF-8</stringProp>
+          <stringProp name="HTTPSampler.protocol"></stringProp>
+          <stringProp name="HTTPSampler.contentEncoding"></stringProp>
           <stringProp name="HTTPSampler.path">${base_path}checkout/onepage/saveShippingMethod/</stringProp>
           <stringProp name="HTTPSampler.method">POST</stringProp>
           <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -1122,15 +1110,14 @@
           <stringProp name="HTTPSampler.port"></stringProp>
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
-          <stringProp name="HTTPSampler.protocol">http</stringProp>
-          <stringProp name="HTTPSampler.contentEncoding">UTF-8</stringProp>
+          <stringProp name="HTTPSampler.protocol"></stringProp>
+          <stringProp name="HTTPSampler.contentEncoding"></stringProp>
           <stringProp name="HTTPSampler.path">${base_path}checkout/onepage/savePayment/</stringProp>
           <stringProp name="HTTPSampler.method">POST</stringProp>
           <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -1187,15 +1174,14 @@
           <stringProp name="HTTPSampler.port"></stringProp>
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
-          <stringProp name="HTTPSampler.protocol">http</stringProp>
-          <stringProp name="HTTPSampler.contentEncoding">UTF-8</stringProp>
+          <stringProp name="HTTPSampler.protocol"></stringProp>
+          <stringProp name="HTTPSampler.contentEncoding"></stringProp>
           <stringProp name="HTTPSampler.path">${base_path}checkout/onepage/saveOrder/</stringProp>
           <stringProp name="HTTPSampler.method">POST</stringProp>
           <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -1222,7 +1208,7 @@
           <stringProp name="HTTPSampler.port"></stringProp>
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
-          <stringProp name="HTTPSampler.protocol">http</stringProp>
+          <stringProp name="HTTPSampler.protocol"></stringProp>
           <stringProp name="HTTPSampler.contentEncoding"></stringProp>
           <stringProp name="HTTPSampler.path">${base_path}checkout/onepage/success/</stringProp>
           <stringProp name="HTTPSampler.method">GET</stringProp>
@@ -1230,7 +1216,6 @@
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -1258,15 +1243,14 @@
           <stringProp name="HTTPSampler.port"></stringProp>
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
-          <stringProp name="HTTPSampler.protocol">http</stringProp>
-          <stringProp name="HTTPSampler.contentEncoding">UTF-8</stringProp>
+          <stringProp name="HTTPSampler.protocol"></stringProp>
+          <stringProp name="HTTPSampler.contentEncoding"></stringProp>
           <stringProp name="HTTPSampler.path">${base_path}customer/account/logout/</stringProp>
           <stringProp name="HTTPSampler.method">GET</stringProp>
           <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -1344,6 +1328,9 @@
             <saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>
             <assertionsResultsToSave>0</assertionsResultsToSave>
             <bytes>true</bytes>
+            <hostname>true</hostname>
+            <threadCounts>true</threadCounts>
+            <sampleCount>true</sampleCount>
           </value>
         </objProp>
         <stringProp name="filename">${response_time_file_name}</stringProp>
diff --git a/dev/tests/performance/config.php.dist b/dev/tests/performance/config.php.dist
index e145b9768ffe2d8b6178edc2e718e0c8220d0770..38d6e0430601f293bdb20c022d7ca5ca358521fc 100644
--- a/dev/tests/performance/config.php.dist
+++ b/dev/tests/performance/config.php.dist
@@ -13,23 +13,23 @@ return array(
                 'language'                   => 'en_US',
                 'timezone'                   => 'America/Los_Angeles',
                 'currency'                   => 'USD',
-                'db_host'                    => 'localhost',
-                'db_name'                    => 'magento',
-                'db_user'                    => 'root',
-                'db_password'                => '',
-                'use_secure'                 => '0',
-                'use_secure_admin'           => '0',
-                'use_rewrites'               => '0',
-                'admin_lastname'             => 'Admin',
-                'admin_firstname'            => 'Admin',
-                'admin_email'                => 'admin@example.com',
-                'admin_user'                 => 'admin',
-                'admin_password'             => '123123q',
-                'admin_use_security_key'     => '0',
-                'backend_frontname'          => 'backend',
+                'db-host'                    => 'localhost',
+                'db-name'                    => 'magento',
+                'db-user'                    => 'root',
+                'db-password'                => '',
+                'use-secure'                 => '0',
+                'use-secure-admin'           => '0',
+                'use-rewrites'               => '0',
+                'admin-lastname'             => 'Admin',
+                'admin-firstname'            => 'Admin',
+                'admin-email'                => 'admin@example.com',
+                'admin-user'                 => 'admin',
+                'admin-password'             => '123123q',
+                'admin-use-security-key'     => '0',
+                'backend-frontname'          => 'backend',
             ),
             'options_no_value' => array(
-                'cleanup_database',
+                'cleanup-database',
             ),
         ),
     ),
diff --git a/dev/tests/performance/framework/Magento/TestFramework/Application.php b/dev/tests/performance/framework/Magento/TestFramework/Application.php
index bd192386c9d747fbb5b154c615a70014c1e7ead6..031ad7194e98a14a330e0354c11b5541c672700e 100644
--- a/dev/tests/performance/framework/Magento/TestFramework/Application.php
+++ b/dev/tests/performance/framework/Magento/TestFramework/Application.php
@@ -156,7 +156,7 @@ class Application
 
         // Populate install options with global options
         $baseUrl = 'http://' . $this->_config->getApplicationUrlHost() . $this->_config->getApplicationUrlPath();
-        $installOptions = array_merge($installOptions, ['base_url' => $baseUrl, 'base_url_secure' => $baseUrl]);
+        $installOptions = array_merge($installOptions, ['base-url' => $baseUrl, 'base-url-secure' => $baseUrl]);
         $installCmd = 'php -f %s setup:install';
         $installCmdArgs = [$this->_script];
         foreach ($installOptions as $optionName => $optionValue) {
diff --git a/dev/tests/performance/framework/Magento/TestFramework/Performance/Config.php b/dev/tests/performance/framework/Magento/TestFramework/Performance/Config.php
index bd01b881c6bb9bb427690147be710d7a21a1900f..65287f5656bacc9a1f78b30a3f5ae3c1e69bee6e 100644
--- a/dev/tests/performance/framework/Magento/TestFramework/Performance/Config.php
+++ b/dev/tests/performance/framework/Magento/TestFramework/Performance/Config.php
@@ -117,7 +117,7 @@ class Config
         }
 
         // Validate admin options data
-        $requiredAdminKeys = ['admin_user', 'admin_password', 'backend_frontname'];
+        $requiredAdminKeys = ['admin-user', 'admin-password', 'backend-frontname'];
         foreach ($requiredAdminKeys as $requiredKeyName) {
             if (empty($configData['application']['installation']['options'][$requiredKeyName])) {
                 throw new \Magento\Framework\Exception\LocalizedException(
@@ -277,9 +277,9 @@ class Config
             \Magento\TestFramework\Performance\Scenario::ARG_HOST => $this->getApplicationUrlHost(),
             \Magento\TestFramework\Performance\Scenario::ARG_PATH => $this->getApplicationUrlPath(),
             \Magento\TestFramework\Performance\Scenario::ARG_BASEDIR => $this->getApplicationBaseDir(),
-            \Magento\TestFramework\Performance\Scenario::ARG_BACKEND_FRONTNAME => $options['backend_frontname'],
-            \Magento\TestFramework\Performance\Scenario::ARG_ADMIN_USER => $options['admin_user'],
-            \Magento\TestFramework\Performance\Scenario::ARG_ADMIN_PASSWORD => $options['admin_password'],
+            \Magento\TestFramework\Performance\Scenario::ARG_BACKEND_FRONTNAME => $options['backend-frontname'],
+            \Magento\TestFramework\Performance\Scenario::ARG_ADMIN_USER => $options['admin-user'],
+            \Magento\TestFramework\Performance\Scenario::ARG_ADMIN_PASSWORD => $options['admin-password'],
             'jmeter.save.saveservice.output_format' => 'xml',
         ];
     }
diff --git a/dev/tests/performance/framework/Magento/TestFramework/Performance/Scenario.php b/dev/tests/performance/framework/Magento/TestFramework/Performance/Scenario.php
index ab19c64f5aebea70028fa971cd2b2c8a96995ee8..0cdbfe20936fd69c9e66a815431fc13f8c0f8770 100644
--- a/dev/tests/performance/framework/Magento/TestFramework/Performance/Scenario.php
+++ b/dev/tests/performance/framework/Magento/TestFramework/Performance/Scenario.php
@@ -24,11 +24,11 @@ class Scenario
 
     const ARG_BASEDIR = 'basedir';
 
-    const ARG_ADMIN_USER = 'admin_user';
+    const ARG_ADMIN_USER = 'admin-user';
 
-    const ARG_ADMIN_PASSWORD = 'admin_password';
+    const ARG_ADMIN_PASSWORD = 'admin-password';
 
-    const ARG_BACKEND_FRONTNAME = 'backend_frontname';
+    const ARG_BACKEND_FRONTNAME = 'backend-frontname';
 
     /**#@-*/
 
diff --git a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/ConfigTest.php b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/ConfigTest.php
index 39685b58894125220e63fd532b39f5b0f54282ac..50794f66c1cee434f92ae7b5b61b53004e2bcc6d 100644
--- a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/ConfigTest.php
+++ b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/ConfigTest.php
@@ -144,9 +144,9 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
         $expectedOptions = [
             'option1' => 'value 1',
             'option2' => 'value 2',
-            'backend_frontname' => 'backend',
-            'admin_user' => 'admin',
-            'admin_password' => 'password1',
+            'backend-frontname' => 'backend',
+            'admin-user' => 'admin',
+            'admin-password' => 'password1',
         ];
         $this->assertEquals($expectedOptions, $this->_object->getInstallOptions());
     }
diff --git a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/bootstrap/config_dist/config.php.dist b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/bootstrap/config_dist/config.php.dist
index 6db1c505bff49c76b7f1472e68c6f83022d73eb4..239c3a60bec11254f1a4cfa27061480fed2b6aeb 100644
--- a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/bootstrap/config_dist/config.php.dist
+++ b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/bootstrap/config_dist/config.php.dist
@@ -10,9 +10,9 @@ return array(
         'url_path' => '/',
         'installation' => array(
             'options' => array(
-                'backend_frontname' => 'backend',
-                'admin_user' => 'admin',
-                'admin_password' => 'password1',
+                'backend-frontname' => 'backend',
+                'admin-user' => 'admin',
+                'admin-password' => 'password1',
             ),
         ),
     ),
diff --git a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/bootstrap/config_normal/config.php b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/bootstrap/config_normal/config.php
index 463b896d34d68ed13d2a2b1dd7c1c70e1d8e9126..07a1a86c76dece35ac4c8af990a571c82dad3708 100644
--- a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/bootstrap/config_normal/config.php
+++ b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/bootstrap/config_normal/config.php
@@ -10,9 +10,9 @@ return [
         'url_path' => '/',
         'installation' => [
             'options' => [
-                'backend_frontname' => 'backend',
-                'admin_user' => 'admin',
-                'admin_password' => 'password1',
+                'backend-frontname' => 'backend',
+                'admin-user' => 'admin',
+                'admin-password' => 'password1',
             ],
         ],
     ],
diff --git a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/bootstrap/config_normal/config.php.dist b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/bootstrap/config_normal/config.php.dist
index 577aadcc45bac471f1262da433d3ae0decc30fd3..a1b5c16c55297e28c8c78d5ac9ca75b4fee3c514 100644
--- a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/bootstrap/config_normal/config.php.dist
+++ b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/bootstrap/config_normal/config.php.dist
@@ -10,9 +10,9 @@ return array(
         'url_path' => '/',
         'installation' => array(
             'options' => array(
-                'backend_frontname' => 'backend',
-                'admin_user' => 'admin',
-                'admin_password' => 'password1',
+                'backend-frontname' => 'backend',
+                'admin-user' => 'admin',
+                'admin-password' => 'password1',
             ),
         ),
     ),
diff --git a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/config_data.php b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/config_data.php
index eaa852c5e31a6ece36b932dfac4c552430aee3dd..f74eb069d8eacd093d1baaa3309ea0c4bc94b18c 100644
--- a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/config_data.php
+++ b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/config_data.php
@@ -12,9 +12,9 @@ return [
             'options' => [
                 'option1' => 'value 1',
                 'option2' => 'value 2',
-                'backend_frontname' => 'backend',
-                'admin_user' => 'admin',
-                'admin_password' => 'password1',
+                'backend-frontname' => 'backend',
+                'admin-user' => 'admin',
+                'admin-password' => 'password1',
             ],
         ],
     ],
diff --git a/dev/tests/performance/testsuite/_samples/_template.jmx b/dev/tests/performance/testsuite/_samples/_template.jmx
index 1effe714f7bbb3d7fa93632793245cdedad049d3..2602b87dade56c7b2bea8e561c2889da1141515b 100644
--- a/dev/tests/performance/testsuite/_samples/_template.jmx
+++ b/dev/tests/performance/testsuite/_samples/_template.jmx
@@ -1,13 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
 /**
- * @category    Magento
- * @package     performance_tests
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
 -->
-<jmeterTestPlan version="1.2" properties="2.1">
+<jmeterTestPlan version="1.2" properties="2.7" jmeter="2.12 r1636949">
   <hashTree>
     <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true">
       <stringProp name="TestPlan.comments"></stringProp>
@@ -64,8 +62,10 @@
         <stringProp name="HTTPSampler.connect_timeout"></stringProp>
         <stringProp name="HTTPSampler.response_timeout"></stringProp>
         <stringProp name="HTTPSampler.protocol">http</stringProp>
-        <stringProp name="HTTPSampler.contentEncoding"></stringProp>
+        <stringProp name="HTTPSampler.contentEncoding">utf-8</stringProp>
         <stringProp name="HTTPSampler.path"></stringProp>
+        <stringProp name="HTTPSampler.implementation">HttpClient4</stringProp>
+        <stringProp name="HTTPSampler.concurrentPool">4</stringProp>
       </ConfigTestElement>
       <hashTree/>
       <CookieManager guiclass="CookiePanel" testclass="CookieManager" testname="HTTP Cookie Manager" enabled="true">
@@ -101,6 +101,9 @@
             <saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>
             <assertionsResultsToSave>0</assertionsResultsToSave>
             <bytes>true</bytes>
+            <hostname>true</hostname>
+            <threadCounts>true</threadCounts>
+            <sampleCount>true</sampleCount>
           </value>
         </objProp>
         <stringProp name="filename"></stringProp>
diff --git a/dev/tests/performance/testsuite/add_to_cart.jmx b/dev/tests/performance/testsuite/add_to_cart.jmx
index b6a872202945507a5fa61f6792518172cea810dc..ec07b71db12101578fa518576a0652d00dd548d1 100644
--- a/dev/tests/performance/testsuite/add_to_cart.jmx
+++ b/dev/tests/performance/testsuite/add_to_cart.jmx
@@ -1,13 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
 /**
- * @category    Magento
- * @package     performance_tests
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
 -->
-<jmeterTestPlan version="1.2" properties="2.1">
+<jmeterTestPlan version="1.2" properties="2.7" jmeter="2.12 r1636949">
   <hashTree>
     <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true">
       <stringProp name="TestPlan.comments"></stringProp>
@@ -60,7 +58,7 @@
           </collectionProp>
         </Arguments>
         <hashTree/>
-        <HTTPSampler guiclass="HttpTestSampleGui" testclass="HTTPSampler" testname="Add to Cart - Product View" enabled="true">
+        <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Add to Cart - Product View" enabled="true">
           <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" enabled="true">
             <collectionProp name="Arguments.arguments"/>
           </elementProp>
@@ -68,7 +66,7 @@
           <stringProp name="HTTPSampler.port"></stringProp>
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
-          <stringProp name="HTTPSampler.protocol">http</stringProp>
+          <stringProp name="HTTPSampler.protocol"></stringProp>
           <stringProp name="HTTPSampler.contentEncoding"></stringProp>
           <stringProp name="HTTPSampler.path">${base_path}${product_url_key}</stringProp>
           <stringProp name="HTTPSampler.method">GET</stringProp>
@@ -78,7 +76,7 @@
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
-        </HTTPSampler>
+        </HTTPSamplerProxy>
         <hashTree>
           <RegexExtractor guiclass="RegexExtractorGui" testclass="RegexExtractor" testname="Extract &quot;product_id&quot;" enabled="true">
             <stringProp name="RegexExtractor.useHeaders">false</stringProp>
@@ -121,7 +119,7 @@
           </ResponseAssertion>
           <hashTree/>
         </hashTree>
-        <HTTPSampler guiclass="HttpTestSampleGui" testclass="HTTPSampler" testname="Cart Add Product &amp; View Redirect" enabled="true">
+        <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Cart Add Product &amp; View Redirect" enabled="true">
           <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" enabled="true">
             <collectionProp name="Arguments.arguments">
               <elementProp name="product" elementType="HTTPArgument">
@@ -151,8 +149,8 @@
           <stringProp name="HTTPSampler.port"></stringProp>
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
-          <stringProp name="HTTPSampler.protocol">http</stringProp>
-          <stringProp name="HTTPSampler.contentEncoding">UTF-8</stringProp>
+          <stringProp name="HTTPSampler.protocol"></stringProp>
+          <stringProp name="HTTPSampler.contentEncoding"></stringProp>
           <stringProp name="HTTPSampler.path">${base_path}checkout/cart/add/product/${product_id}/</stringProp>
           <stringProp name="HTTPSampler.method">POST</stringProp>
           <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
@@ -161,7 +159,7 @@
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
-        </HTTPSampler>
+        </HTTPSamplerProxy>
         <hashTree>
           <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true">
             <collectionProp name="Asserion.test_strings">
@@ -175,7 +173,7 @@
           <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true">
             <collectionProp name="Asserion.test_strings">
               <stringProp name="1554014413">&lt;a href=&quot;${base_uri}${product_url_key}&quot;&gt;${product_name}&lt;/a&gt;</stringProp>
-              <stringProp name="1472794794">You added ${product_name} to your shopping cart.</stringProp>
+              <stringProp name="-149996652">You added ${product_name} to your shopping cart.</stringProp>
             </collectionProp>
             <stringProp name="Assertion.test_field">Assertion.response_data</stringProp>
             <boolProp name="Assertion.assume_success">false</boolProp>
@@ -197,9 +195,11 @@
           <stringProp name="HTTPSampler.port"></stringProp>
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
-          <stringProp name="HTTPSampler.protocol"></stringProp>
-          <stringProp name="HTTPSampler.contentEncoding"></stringProp>
+          <stringProp name="HTTPSampler.protocol">http</stringProp>
+          <stringProp name="HTTPSampler.contentEncoding">utf-8</stringProp>
           <stringProp name="HTTPSampler.path">${base_path}</stringProp>
+          <stringProp name="HTTPSampler.implementation">HttpClient4</stringProp>
+          <stringProp name="HTTPSampler.concurrentPool">4</stringProp>
         </ConfigTestElement>
         <hashTree/>
       </hashTree>
@@ -230,6 +230,9 @@
             <saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>
             <assertionsResultsToSave>0</assertionsResultsToSave>
             <bytes>true</bytes>
+            <hostname>true</hostname>
+            <threadCounts>true</threadCounts>
+            <sampleCount>true</sampleCount>
           </value>
         </objProp>
         <stringProp name="filename"></stringProp>
diff --git a/dev/tests/performance/testsuite/advanced_search.jmx b/dev/tests/performance/testsuite/advanced_search.jmx
index f0c4b5ea01fe28b23c71dcf980de62ac0d37af29..9b9679b2311b6bf69094920dfb2c42bc49b6ec5f 100644
--- a/dev/tests/performance/testsuite/advanced_search.jmx
+++ b/dev/tests/performance/testsuite/advanced_search.jmx
@@ -1,13 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
 /**
- * @category    Magento
- * @package     performance_tests
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
 -->
-<jmeterTestPlan version="1.2" properties="2.3">
+<jmeterTestPlan version="1.2" properties="2.7" jmeter="2.12 r1636949">
   <hashTree>
     <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Advanced Search" enabled="true">
       <stringProp name="TestPlan.comments"></stringProp>
@@ -69,7 +67,7 @@
           <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" enabled="true">
             <collectionProp name="Arguments.arguments"/>
           </elementProp>
-          <stringProp name="HTTPSampler.domain">${HOST}</stringProp>
+          <stringProp name="HTTPSampler.domain"></stringProp>
           <stringProp name="HTTPSampler.port"></stringProp>
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
@@ -81,14 +79,13 @@
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
         <hashTree>
           <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Assertion: Header Presence" enabled="true">
             <collectionProp name="Asserion.test_strings">
-              <stringProp name="-462078532">Advanced Search</stringProp>
+              <stringProp name="-1680539802">Advanced Search</stringProp>
             </collectionProp>
             <stringProp name="Assertion.test_field">Assertion.response_data</stringProp>
             <boolProp name="Assertion.assume_success">false</boolProp>
@@ -143,19 +140,18 @@
               </elementProp>
             </collectionProp>
           </elementProp>
-          <stringProp name="HTTPSampler.domain">${HOST}</stringProp>
+          <stringProp name="HTTPSampler.domain"></stringProp>
           <stringProp name="HTTPSampler.port"></stringProp>
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
           <stringProp name="HTTPSampler.protocol"></stringProp>
-          <stringProp name="HTTPSampler.contentEncoding">UTF-8</stringProp>
+          <stringProp name="HTTPSampler.contentEncoding"></stringProp>
           <stringProp name="HTTPSampler.path">${PATH}catalogsearch/advanced/result/</stringProp>
           <stringProp name="HTTPSampler.method">GET</stringProp>
           <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -215,6 +211,9 @@
             <saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>
             <assertionsResultsToSave>0</assertionsResultsToSave>
             <bytes>true</bytes>
+            <hostname>true</hostname>
+            <threadCounts>true</threadCounts>
+            <sampleCount>true</sampleCount>
           </value>
         </objProp>
         <stringProp name="filename"></stringProp>
@@ -249,6 +248,21 @@
         </collectionProp>
       </HeaderManager>
       <hashTree/>
+      <ConfigTestElement guiclass="HttpDefaultsGui" testclass="ConfigTestElement" testname="HTTP Request Defaults" enabled="true">
+        <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
+          <collectionProp name="Arguments.arguments"/>
+        </elementProp>
+        <stringProp name="HTTPSampler.domain">${HOST}</stringProp>
+        <stringProp name="HTTPSampler.port"></stringProp>
+        <stringProp name="HTTPSampler.connect_timeout"></stringProp>
+        <stringProp name="HTTPSampler.response_timeout"></stringProp>
+        <stringProp name="HTTPSampler.protocol">http</stringProp>
+        <stringProp name="HTTPSampler.contentEncoding">utf-8</stringProp>
+        <stringProp name="HTTPSampler.path"></stringProp>
+        <stringProp name="HTTPSampler.implementation">HttpClient4</stringProp>
+        <stringProp name="HTTPSampler.concurrentPool">4</stringProp>
+      </ConfigTestElement>
+      <hashTree/>
     </hashTree>
   </hashTree>
 </jmeterTestPlan>
diff --git a/dev/tests/performance/testsuite/backend.jmx b/dev/tests/performance/testsuite/backend.jmx
index fbf480529e8084e7895f66a1541972d697f9e046..e3e9dd82a55d3060900a3368df5ee97c305086b9 100644
--- a/dev/tests/performance/testsuite/backend.jmx
+++ b/dev/tests/performance/testsuite/backend.jmx
@@ -1,13 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
 /**
- * @category    Magento
- * @package     performance_tests
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
 -->
-<jmeterTestPlan version="1.2" properties="2.4" jmeter="2.9 r1437961">
+<jmeterTestPlan version="1.2" properties="2.7" jmeter="2.12 r1636949">
   <hashTree>
     <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Backend High Load Testing" enabled="true">
       <stringProp name="TestPlan.comments"></stringProp>
@@ -22,17 +20,17 @@
           </elementProp>
           <elementProp name="ADMIN_PATH" elementType="Argument">
             <stringProp name="Argument.name">ADMIN_PATH</stringProp>
-            <stringProp name="Argument.value">${__P(path,/)}${__P(backend_frontname,backend)}/</stringProp>
+            <stringProp name="Argument.value">${__P(path,/)}${__P(backend-frontname,backend)}/</stringProp>
             <stringProp name="Argument.metadata">=</stringProp>
           </elementProp>
           <elementProp name="ADMIN_USER" elementType="Argument">
             <stringProp name="Argument.name">ADMIN_USER</stringProp>
-            <stringProp name="Argument.value">${__P(admin_user,admin)}</stringProp>
+            <stringProp name="Argument.value">${__P(admin-user,admin)}</stringProp>
             <stringProp name="Argument.metadata">=</stringProp>
           </elementProp>
           <elementProp name="ADMIN_PASSWORD" elementType="Argument">
             <stringProp name="Argument.name">ADMIN_PASSWORD</stringProp>
-            <stringProp name="Argument.value">${__P(admin_password,123123q)}</stringProp>
+            <stringProp name="Argument.value">${__P(admin-password,123123q)}</stringProp>
             <stringProp name="Argument.metadata">=</stringProp>
           </elementProp>
           <elementProp name="products_number" elementType="Argument">
@@ -88,7 +86,7 @@
           <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
             <collectionProp name="Arguments.arguments"/>
           </elementProp>
-          <stringProp name="HTTPSampler.domain">${HOST}</stringProp>
+          <stringProp name="HTTPSampler.domain"></stringProp>
           <stringProp name="HTTPSampler.port"></stringProp>
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
@@ -100,14 +98,13 @@
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
         <hashTree>
           <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Assert Total Number of Products" enabled="true">
             <collectionProp name="Asserion.test_strings">
-              <stringProp name="-1786510475">&lt;h1 class=&quot;title&quot;&gt;Products&lt;/h1&gt;</stringProp>
+              <stringProp name="658046956">&lt;h1 class=&quot;title&quot;&gt;Products&lt;/h1&gt;</stringProp>
               <stringProp name="-1952867632">Total ${products_number} records found</stringProp>
             </collectionProp>
             <stringProp name="Assertion.test_field">Assertion.response_data</stringProp>
@@ -120,26 +117,25 @@
           <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
             <collectionProp name="Arguments.arguments"/>
           </elementProp>
-          <stringProp name="HTTPSampler.domain">${HOST}</stringProp>
+          <stringProp name="HTTPSampler.domain"></stringProp>
           <stringProp name="HTTPSampler.port"></stringProp>
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
           <stringProp name="HTTPSampler.protocol"></stringProp>
-          <stringProp name="HTTPSampler.contentEncoding">UTF8</stringProp>
+          <stringProp name="HTTPSampler.contentEncoding"></stringProp>
           <stringProp name="HTTPSampler.path">${ADMIN_PATH}customer/</stringProp>
           <stringProp name="HTTPSampler.method">GET</stringProp>
           <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
         <hashTree>
           <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Assert Total Number of Customers" enabled="true">
             <collectionProp name="Asserion.test_strings">
-              <stringProp name="-5737002">&lt;h1 class=&quot;title&quot;&gt;Customers&lt;/h1&gt;</stringProp>
+              <stringProp name="-1533867969">&lt;h1 class=&quot;title&quot;&gt;Customers&lt;/h1&gt;</stringProp>
               <stringProp name="1843270971">Total ${customers_number} records found</stringProp>
             </collectionProp>
             <stringProp name="Assertion.test_field">Assertion.response_data</stringProp>
@@ -152,19 +148,18 @@
           <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
             <collectionProp name="Arguments.arguments"/>
           </elementProp>
-          <stringProp name="HTTPSampler.domain">${HOST}</stringProp>
+          <stringProp name="HTTPSampler.domain"></stringProp>
           <stringProp name="HTTPSampler.port"></stringProp>
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
           <stringProp name="HTTPSampler.protocol"></stringProp>
-          <stringProp name="HTTPSampler.contentEncoding">UTF8</stringProp>
+          <stringProp name="HTTPSampler.contentEncoding"></stringProp>
           <stringProp name="HTTPSampler.path">${ADMIN_PATH}sales/order/</stringProp>
           <stringProp name="HTTPSampler.method">GET</stringProp>
           <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -185,6 +180,21 @@
           <boolProp name="CookieManager.clearEachIteration">true</boolProp>
         </CookieManager>
         <hashTree/>
+        <ConfigTestElement guiclass="HttpDefaultsGui" testclass="ConfigTestElement" testname="HTTP Request Defaults" enabled="true">
+          <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
+            <collectionProp name="Arguments.arguments"/>
+          </elementProp>
+          <stringProp name="HTTPSampler.domain">${HOST}</stringProp>
+          <stringProp name="HTTPSampler.port"></stringProp>
+          <stringProp name="HTTPSampler.connect_timeout"></stringProp>
+          <stringProp name="HTTPSampler.response_timeout"></stringProp>
+          <stringProp name="HTTPSampler.protocol">http</stringProp>
+          <stringProp name="HTTPSampler.contentEncoding">utf-8</stringProp>
+          <stringProp name="HTTPSampler.path"></stringProp>
+          <stringProp name="HTTPSampler.implementation">HttpClient4</stringProp>
+          <stringProp name="HTTPSampler.concurrentPool">4</stringProp>
+        </ConfigTestElement>
+        <hashTree/>
         <ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree" enabled="false">
           <boolProp name="ResultCollector.error_logging">false</boolProp>
           <objProp>
@@ -212,6 +222,9 @@
               <saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>
               <assertionsResultsToSave>0</assertionsResultsToSave>
               <bytes>true</bytes>
+              <hostname>true</hostname>
+              <threadCounts>true</threadCounts>
+              <sampleCount>true</sampleCount>
             </value>
           </objProp>
           <stringProp name="filename"></stringProp>
diff --git a/dev/tests/performance/testsuite/category_view.jmx b/dev/tests/performance/testsuite/category_view.jmx
index c5954e9be980fd0b3cb30a2db248413238bc2f6e..5697ace521dd272df24023823501f3378d6998e2 100644
--- a/dev/tests/performance/testsuite/category_view.jmx
+++ b/dev/tests/performance/testsuite/category_view.jmx
@@ -1,13 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
 /**
- * @category    Magento
- * @package     performance_tests
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
 -->
-<jmeterTestPlan version="1.2" properties="2.2">
+<jmeterTestPlan version="1.2" properties="2.7" jmeter="2.12 r1636949">
   <hashTree>
     <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Category View" enabled="true">
       <stringProp name="TestPlan.comments"></stringProp>
@@ -64,11 +62,11 @@
           <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" enabled="true">
             <collectionProp name="Arguments.arguments"/>
           </elementProp>
-          <stringProp name="HTTPSampler.domain">${HOST}</stringProp>
+          <stringProp name="HTTPSampler.domain"></stringProp>
           <stringProp name="HTTPSampler.port"></stringProp>
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
-          <stringProp name="HTTPSampler.protocol">http</stringProp>
+          <stringProp name="HTTPSampler.protocol"></stringProp>
           <stringProp name="HTTPSampler.contentEncoding"></stringProp>
           <stringProp name="HTTPSampler.path">${PATH}${CATEGORY_URI}</stringProp>
           <stringProp name="HTTPSampler.method">GET</stringProp>
@@ -76,7 +74,6 @@
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -105,7 +102,7 @@
           <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true">
             <collectionProp name="Asserion.test_strings">
               <stringProp name="-1004972625">Category 1</stringProp>
-              <stringProp name="952135968">Simple Product</stringProp>
+              <stringProp name="1413426305">Simple Product</stringProp>
             </collectionProp>
             <stringProp name="Assertion.test_field">Assertion.response_data</stringProp>
             <boolProp name="Assertion.assume_success">false</boolProp>
@@ -114,6 +111,21 @@
           <hashTree/>
         </hashTree>
       </hashTree>
+      <ConfigTestElement guiclass="HttpDefaultsGui" testclass="ConfigTestElement" testname="HTTP Request Defaults" enabled="true">
+        <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
+          <collectionProp name="Arguments.arguments"/>
+        </elementProp>
+        <stringProp name="HTTPSampler.domain">${HOST}</stringProp>
+        <stringProp name="HTTPSampler.port"></stringProp>
+        <stringProp name="HTTPSampler.connect_timeout"></stringProp>
+        <stringProp name="HTTPSampler.response_timeout"></stringProp>
+        <stringProp name="HTTPSampler.protocol">http</stringProp>
+        <stringProp name="HTTPSampler.contentEncoding">utf-8</stringProp>
+        <stringProp name="HTTPSampler.path"></stringProp>
+        <stringProp name="HTTPSampler.implementation">HttpClient4</stringProp>
+        <stringProp name="HTTPSampler.concurrentPool">4</stringProp>
+      </ConfigTestElement>
+      <hashTree/>
       <ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree" enabled="false">
         <boolProp name="ResultCollector.error_logging">false</boolProp>
         <objProp>
@@ -141,6 +153,9 @@
             <saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>
             <assertionsResultsToSave>0</assertionsResultsToSave>
             <bytes>true</bytes>
+            <hostname>true</hostname>
+            <threadCounts>true</threadCounts>
+            <sampleCount>true</sampleCount>
           </value>
         </objProp>
         <stringProp name="filename"></stringProp>
diff --git a/dev/tests/performance/testsuite/checkout.jmx b/dev/tests/performance/testsuite/checkout.jmx
index 5dda04cb25a9e0a66328da0833506d92c7f7a71a..6306e47f71ab4d71d780ea77e958cfea918d27c8 100644
--- a/dev/tests/performance/testsuite/checkout.jmx
+++ b/dev/tests/performance/testsuite/checkout.jmx
@@ -1,13 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
 /**
- * @category    Magento
- * @package     performance_tests
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
 -->
-<jmeterTestPlan version="1.2" properties="2.3">
+<jmeterTestPlan version="1.2" properties="2.7" jmeter="2.12 r1636949">
   <hashTree>
     <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="One Page Checkout" enabled="true">
       <stringProp name="TestPlan.comments"></stringProp>
@@ -42,17 +40,17 @@
           </elementProp>
           <elementProp name="ADMIN_PATH" elementType="Argument">
             <stringProp name="Argument.name">ADMIN_PATH</stringProp>
-            <stringProp name="Argument.value">${__P(path,/)}${__P(backend_frontname,backend)}/</stringProp>
+            <stringProp name="Argument.value">${__P(path,/)}${__P(backend-frontname,backend)}/</stringProp>
             <stringProp name="Argument.metadata">=</stringProp>
           </elementProp>
           <elementProp name="ADMIN_USER" elementType="Argument">
             <stringProp name="Argument.name">ADMIN_USER</stringProp>
-            <stringProp name="Argument.value">${__P(admin_user,admin)}</stringProp>
+            <stringProp name="Argument.value">${__P(admin-user,admin)}</stringProp>
             <stringProp name="Argument.metadata">=</stringProp>
           </elementProp>
           <elementProp name="ADMIN_PASSWORD" elementType="Argument">
             <stringProp name="Argument.name">ADMIN_PASSWORD</stringProp>
-            <stringProp name="Argument.value">${__P(admin_password,123123q)}</stringProp>
+            <stringProp name="Argument.value">${__P(admin-password,123123q)}</stringProp>
             <stringProp name="Argument.metadata">=</stringProp>
           </elementProp>
         </collectionProp>
@@ -74,7 +72,7 @@
           <stringProp name="HTTPSampler.port"></stringProp>
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
-          <stringProp name="HTTPSampler.protocol">http</stringProp>
+          <stringProp name="HTTPSampler.protocol"></stringProp>
           <stringProp name="HTTPSampler.contentEncoding"></stringProp>
           <stringProp name="HTTPSampler.path">${ADMIN_PATH}sales/order/</stringProp>
           <stringProp name="HTTPSampler.method">GET</stringProp>
@@ -82,7 +80,6 @@
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -172,7 +169,6 @@
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -250,14 +246,13 @@
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
           <stringProp name="HTTPSampler.protocol"></stringProp>
-          <stringProp name="HTTPSampler.contentEncoding">UTF-8</stringProp>
+          <stringProp name="HTTPSampler.contentEncoding"></stringProp>
           <stringProp name="HTTPSampler.path">${PATH}checkout/cart/add/product/${product_id}/</stringProp>
           <stringProp name="HTTPSampler.method">POST</stringProp>
           <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -307,7 +302,6 @@
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -339,14 +333,13 @@
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
           <stringProp name="HTTPSampler.protocol"></stringProp>
-          <stringProp name="HTTPSampler.contentEncoding">UTF-8</stringProp>
+          <stringProp name="HTTPSampler.contentEncoding"></stringProp>
           <stringProp name="HTTPSampler.path">${PATH}checkout/onepage/saveMethod/</stringProp>
           <stringProp name="HTTPSampler.method">POST</stringProp>
           <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -526,14 +519,13 @@
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
           <stringProp name="HTTPSampler.protocol"></stringProp>
-          <stringProp name="HTTPSampler.contentEncoding">UTF-8</stringProp>
+          <stringProp name="HTTPSampler.contentEncoding"></stringProp>
           <stringProp name="HTTPSampler.path">${PATH}checkout/onepage/saveBilling/</stringProp>
           <stringProp name="HTTPSampler.method">POST</stringProp>
           <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -586,14 +578,13 @@
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
           <stringProp name="HTTPSampler.protocol"></stringProp>
-          <stringProp name="HTTPSampler.contentEncoding">UTF-8</stringProp>
+          <stringProp name="HTTPSampler.contentEncoding"></stringProp>
           <stringProp name="HTTPSampler.path">${PATH}checkout/onepage/getAdditional/</stringProp>
           <stringProp name="HTTPSampler.method">POST</stringProp>
           <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -648,7 +639,6 @@
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -692,14 +682,13 @@
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
           <stringProp name="HTTPSampler.protocol"></stringProp>
-          <stringProp name="HTTPSampler.contentEncoding">UTF-8</stringProp>
+          <stringProp name="HTTPSampler.contentEncoding"></stringProp>
           <stringProp name="HTTPSampler.path">${PATH}checkout/onepage/saveShippingMethod/</stringProp>
           <stringProp name="HTTPSampler.method">POST</stringProp>
           <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -752,14 +741,13 @@
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
           <stringProp name="HTTPSampler.protocol"></stringProp>
-          <stringProp name="HTTPSampler.contentEncoding">UTF-8</stringProp>
+          <stringProp name="HTTPSampler.contentEncoding"></stringProp>
           <stringProp name="HTTPSampler.path">${PATH}checkout/onepage/progress/</stringProp>
           <stringProp name="HTTPSampler.method">GET</stringProp>
           <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -799,14 +787,13 @@
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
           <stringProp name="HTTPSampler.protocol"></stringProp>
-          <stringProp name="HTTPSampler.contentEncoding">UTF-8</stringProp>
+          <stringProp name="HTTPSampler.contentEncoding"></stringProp>
           <stringProp name="HTTPSampler.path">${PATH}checkout/onepage/savePayment/</stringProp>
           <stringProp name="HTTPSampler.method">POST</stringProp>
           <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -859,14 +846,13 @@
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
           <stringProp name="HTTPSampler.protocol"></stringProp>
-          <stringProp name="HTTPSampler.contentEncoding">UTF-8</stringProp>
+          <stringProp name="HTTPSampler.contentEncoding"></stringProp>
           <stringProp name="HTTPSampler.path">${PATH}checkout/onepage/progress/</stringProp>
           <stringProp name="HTTPSampler.method">GET</stringProp>
           <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -914,14 +900,13 @@
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
           <stringProp name="HTTPSampler.protocol"></stringProp>
-          <stringProp name="HTTPSampler.contentEncoding">UTF-8</stringProp>
+          <stringProp name="HTTPSampler.contentEncoding"></stringProp>
           <stringProp name="HTTPSampler.path">${PATH}checkout/onepage/saveOrder/</stringProp>
           <stringProp name="HTTPSampler.method">POST</stringProp>
           <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -981,7 +966,6 @@
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -1067,6 +1051,9 @@ if (numAfter !== null) { // The asserion is called for every sampler, but we wan
             <saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>
             <assertionsResultsToSave>0</assertionsResultsToSave>
             <bytes>true</bytes>
+            <hostname>true</hostname>
+            <threadCounts>true</threadCounts>
+            <sampleCount>true</sampleCount>
           </value>
         </objProp>
         <stringProp name="filename"></stringProp>
@@ -1081,8 +1068,9 @@ if (numAfter !== null) { // The asserion is called for every sampler, but we wan
         <stringProp name="HTTPSampler.connect_timeout"></stringProp>
         <stringProp name="HTTPSampler.response_timeout"></stringProp>
         <stringProp name="HTTPSampler.protocol">http</stringProp>
-        <stringProp name="HTTPSampler.contentEncoding"></stringProp>
+        <stringProp name="HTTPSampler.contentEncoding">utf-8</stringProp>
         <stringProp name="HTTPSampler.path"></stringProp>
+        <stringProp name="HTTPSampler.implementation">HttpClient4</stringProp>
         <stringProp name="HTTPSampler.concurrentPool">4</stringProp>
       </ConfigTestElement>
       <hashTree/>
diff --git a/dev/tests/performance/testsuite/fixtures/catalog_category_flat_enabled.php b/dev/tests/performance/testsuite/fixtures/catalog_category_flat_enabled.php
index 00cd8ce5cb1d148ff81ebcad4ad463fd1933df2f..056fe99b815516c7bb1b20181297a78013312268 100644
--- a/dev/tests/performance/testsuite/fixtures/catalog_category_flat_enabled.php
+++ b/dev/tests/performance/testsuite/fixtures/catalog_category_flat_enabled.php
@@ -3,6 +3,7 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
+use Magento\Framework\App\Config\ScopeConfigInterface;
 
 /** @var \Magento\TestFramework\Application $this */
 
@@ -13,7 +14,7 @@ $configData = $this->getObjectManager()->create('Magento\Framework\App\Config\Va
 $configData->setPath(
     'catalog/frontend/flat_catalog_category'
 )->setScope(
-    \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT
+    ScopeConfigInterface::SCOPE_TYPE_DEFAULT
 )->setScopeId(
     0
 )->setValue(
diff --git a/dev/tests/performance/testsuite/fixtures/catalog_product_flat_enabled.php b/dev/tests/performance/testsuite/fixtures/catalog_product_flat_enabled.php
index 2258e72023d4ad642e1e799134e8b32cbb94d1ab..e06ed0e26c053f2742d6a132f17b4a0f4b8558ce 100644
--- a/dev/tests/performance/testsuite/fixtures/catalog_product_flat_enabled.php
+++ b/dev/tests/performance/testsuite/fixtures/catalog_product_flat_enabled.php
@@ -3,6 +3,7 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
+use Magento\Framework\App\Config\ScopeConfigInterface;
 
 /** @var \Magento\TestFramework\Application $this */
 
@@ -13,7 +14,7 @@ $configData = $this->getObjectManager()->create('Magento\Framework\App\Config\Va
 $configData->setPath(
     'catalog/frontend/flat_catalog_product'
 )->setScope(
-    \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT
+    ScopeConfigInterface::SCOPE_TYPE_DEFAULT
 )->setScopeId(
     0
 )->setValue(
diff --git a/dev/tests/performance/testsuite/fixtures/shipping_flatrate_enabled.php b/dev/tests/performance/testsuite/fixtures/shipping_flatrate_enabled.php
index e0f50505c4adcf397a358a5d8d31e336bd00a3e6..15b445ce1f8b5ca75cf4b6eb1ae20a179bcfa356 100644
--- a/dev/tests/performance/testsuite/fixtures/shipping_flatrate_enabled.php
+++ b/dev/tests/performance/testsuite/fixtures/shipping_flatrate_enabled.php
@@ -3,6 +3,7 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
+use Magento\Framework\App\Config\ScopeConfigInterface;
 
 /** @var \Magento\TestFramework\Application $this */
 
@@ -13,7 +14,7 @@ $configData = $this->getObjectManager()->create('Magento\Framework\App\Config\Va
 $configData->setPath(
     'carriers/flatrate/active'
 )->setScope(
-    \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT
+    ScopeConfigInterface::SCOPE_TYPE_DEFAULT
 )->setScopeId(
     0
 )->setValue(
diff --git a/dev/tests/performance/testsuite/home_page.jmx b/dev/tests/performance/testsuite/home_page.jmx
index 91f82ddcaecc43aa548b832ad6a83bdeb714ccea..b335bdceb5ac27c8275ba7791b7f0e423ff75c52 100644
--- a/dev/tests/performance/testsuite/home_page.jmx
+++ b/dev/tests/performance/testsuite/home_page.jmx
@@ -1,13 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
 /**
- * @category    Magento
- * @package     performance_tests
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
 -->
-<jmeterTestPlan version="1.2" properties="2.5" jmeter="2.10 r1533061">
+<jmeterTestPlan version="1.2" properties="2.7" jmeter="2.12 r1636949">
   <hashTree>
     <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true">
       <stringProp name="TestPlan.comments"></stringProp>
@@ -53,7 +51,7 @@
           <stringProp name="HTTPSampler.port"></stringProp>
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
-          <stringProp name="HTTPSampler.protocol">http</stringProp>
+          <stringProp name="HTTPSampler.protocol"></stringProp>
           <stringProp name="HTTPSampler.contentEncoding"></stringProp>
           <stringProp name="HTTPSampler.path">${base_path}</stringProp>
           <stringProp name="HTTPSampler.method">GET</stringProp>
@@ -61,7 +59,6 @@
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -105,11 +102,29 @@
             <saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>
             <assertionsResultsToSave>0</assertionsResultsToSave>
             <bytes>true</bytes>
+            <hostname>true</hostname>
+            <threadCounts>true</threadCounts>
+            <sampleCount>true</sampleCount>
           </value>
         </objProp>
         <stringProp name="filename"></stringProp>
       </ResultCollector>
       <hashTree/>
+      <ConfigTestElement guiclass="HttpDefaultsGui" testclass="ConfigTestElement" testname="HTTP Request Defaults" enabled="true">
+        <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
+          <collectionProp name="Arguments.arguments"/>
+        </elementProp>
+        <stringProp name="HTTPSampler.domain"></stringProp>
+        <stringProp name="HTTPSampler.port"></stringProp>
+        <stringProp name="HTTPSampler.connect_timeout"></stringProp>
+        <stringProp name="HTTPSampler.response_timeout"></stringProp>
+        <stringProp name="HTTPSampler.protocol">http</stringProp>
+        <stringProp name="HTTPSampler.contentEncoding">utf-8</stringProp>
+        <stringProp name="HTTPSampler.path"></stringProp>
+        <stringProp name="HTTPSampler.implementation">HttpClient4</stringProp>
+        <stringProp name="HTTPSampler.concurrentPool">4</stringProp>
+      </ConfigTestElement>
+      <hashTree/>
     </hashTree>
   </hashTree>
 </jmeterTestPlan>
diff --git a/dev/tests/performance/testsuite/product_edit.jmx b/dev/tests/performance/testsuite/product_edit.jmx
index 199c36235c16396d48dcfed93ed116ec14dd5b72..c4b2ced13478c5ee364d629957529ee46d23c619 100644
--- a/dev/tests/performance/testsuite/product_edit.jmx
+++ b/dev/tests/performance/testsuite/product_edit.jmx
@@ -1,13 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
 /**
- * @category    Magento
- * @package     performance_tests
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
 -->
-<jmeterTestPlan version="1.2" properties="2.3">
+<jmeterTestPlan version="1.2" properties="2.7" jmeter="2.12 r1636949">
   <hashTree>
     <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Admin - Edit Product" enabled="true">
       <stringProp name="TestPlan.comments"></stringProp>
@@ -22,7 +20,7 @@
           </elementProp>
           <elementProp name="ADMIN_PATH" elementType="Argument">
             <stringProp name="Argument.name">ADMIN_PATH</stringProp>
-            <stringProp name="Argument.value">${__P(path,/)}${__P(backend_frontname,backend)}/</stringProp>
+            <stringProp name="Argument.value">${__P(path,/)}${__P(backend-frontname,backend)}/</stringProp>
             <stringProp name="Argument.metadata">=</stringProp>
           </elementProp>
           <elementProp name="USERS" elementType="Argument">
@@ -37,12 +35,12 @@
           </elementProp>
           <elementProp name="ADMIN_USER" elementType="Argument">
             <stringProp name="Argument.name">ADMIN_USER</stringProp>
-            <stringProp name="Argument.value">${__P(admin_user,admin)}</stringProp>
+            <stringProp name="Argument.value">${__P(admin-user,admin)}</stringProp>
             <stringProp name="Argument.metadata">=</stringProp>
           </elementProp>
           <elementProp name="ADMIN_PASSWORD" elementType="Argument">
             <stringProp name="Argument.name">ADMIN_PASSWORD</stringProp>
-            <stringProp name="Argument.value">${__P(admin_password,123123q)}</stringProp>
+            <stringProp name="Argument.value">${__P(admin-password,123123q)}</stringProp>
             <stringProp name="Argument.metadata">=</stringProp>
           </elementProp>
           <elementProp name="product_sku" elementType="Argument">
@@ -100,11 +98,11 @@
               </elementProp>
             </collectionProp>
           </elementProp>
-          <stringProp name="HTTPSampler.domain">${HOST}</stringProp>
+          <stringProp name="HTTPSampler.domain"></stringProp>
           <stringProp name="HTTPSampler.port"></stringProp>
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
-          <stringProp name="HTTPSampler.protocol">http</stringProp>
+          <stringProp name="HTTPSampler.protocol"></stringProp>
           <stringProp name="HTTPSampler.contentEncoding"></stringProp>
           <stringProp name="HTTPSampler.path">${ADMIN_PATH}catalog/product/grid/product_filter/${grid_product_filter}/</stringProp>
           <stringProp name="HTTPSampler.method">GET</stringProp>
@@ -112,7 +110,6 @@
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -163,11 +160,11 @@ vars.put(&quot;grid_product_filter&quot;, gridProductFilter);</stringProp>
           <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" enabled="true">
             <collectionProp name="Arguments.arguments"/>
           </elementProp>
-          <stringProp name="HTTPSampler.domain">${HOST}</stringProp>
+          <stringProp name="HTTPSampler.domain"></stringProp>
           <stringProp name="HTTPSampler.port"></stringProp>
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
-          <stringProp name="HTTPSampler.protocol">http</stringProp>
+          <stringProp name="HTTPSampler.protocol"></stringProp>
           <stringProp name="HTTPSampler.contentEncoding"></stringProp>
           <stringProp name="HTTPSampler.path">${ADMIN_PATH}catalog/product/edit/id/${product_id}/</stringProp>
           <stringProp name="HTTPSampler.method">GET</stringProp>
@@ -175,7 +172,6 @@ vars.put(&quot;grid_product_filter&quot;, gridProductFilter);</stringProp>
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -193,6 +189,21 @@ vars.put(&quot;grid_product_filter&quot;, gridProductFilter);</stringProp>
           </ResponseAssertion>
           <hashTree/>
         </hashTree>
+        <ConfigTestElement guiclass="HttpDefaultsGui" testclass="ConfigTestElement" testname="HTTP Request Defaults" enabled="true">
+          <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
+            <collectionProp name="Arguments.arguments"/>
+          </elementProp>
+          <stringProp name="HTTPSampler.domain">${HOST}</stringProp>
+          <stringProp name="HTTPSampler.port"></stringProp>
+          <stringProp name="HTTPSampler.connect_timeout"></stringProp>
+          <stringProp name="HTTPSampler.response_timeout"></stringProp>
+          <stringProp name="HTTPSampler.protocol">http</stringProp>
+          <stringProp name="HTTPSampler.contentEncoding">utf-8</stringProp>
+          <stringProp name="HTTPSampler.path"></stringProp>
+          <stringProp name="HTTPSampler.implementation">HttpClient4</stringProp>
+          <stringProp name="HTTPSampler.concurrentPool">4</stringProp>
+        </ConfigTestElement>
+        <hashTree/>
         <CookieManager guiclass="CookiePanel" testclass="CookieManager" testname="HTTP Cookie Manager" enabled="true">
           <collectionProp name="CookieManager.cookies"/>
           <boolProp name="CookieManager.clearEachIteration">true</boolProp>
@@ -226,6 +237,9 @@ vars.put(&quot;grid_product_filter&quot;, gridProductFilter);</stringProp>
             <saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>
             <assertionsResultsToSave>0</assertionsResultsToSave>
             <bytes>true</bytes>
+            <hostname>true</hostname>
+            <threadCounts>true</threadCounts>
+            <sampleCount>true</sampleCount>
           </value>
         </objProp>
         <stringProp name="filename"></stringProp>
diff --git a/dev/tests/performance/testsuite/product_view.jmx b/dev/tests/performance/testsuite/product_view.jmx
index 44598d85913f78269299018dd404c4a1d22c9a6a..218f3478b1101a1fba42b6fed7ee60cd770b7dac 100644
--- a/dev/tests/performance/testsuite/product_view.jmx
+++ b/dev/tests/performance/testsuite/product_view.jmx
@@ -1,13 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
 /**
- * @category    Magento
- * @package     performance_tests
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
 -->
-<jmeterTestPlan version="1.2" properties="2.1">
+<jmeterTestPlan version="1.2" properties="2.7" jmeter="2.12 r1636949">
   <hashTree>
     <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Product View" enabled="true">
       <stringProp name="TestPlan.comments"></stringProp>
@@ -55,15 +53,15 @@
         <stringProp name="ThreadGroup.delay"></stringProp>
       </ThreadGroup>
       <hashTree>
-        <HTTPSampler guiclass="HttpTestSampleGui" testclass="HTTPSampler" testname="Product View" enabled="true">
+        <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Product View" enabled="true">
           <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" enabled="true">
             <collectionProp name="Arguments.arguments"/>
           </elementProp>
-          <stringProp name="HTTPSampler.domain">${base_host}</stringProp>
+          <stringProp name="HTTPSampler.domain"></stringProp>
           <stringProp name="HTTPSampler.port"></stringProp>
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
-          <stringProp name="HTTPSampler.protocol">http</stringProp>
+          <stringProp name="HTTPSampler.protocol"></stringProp>
           <stringProp name="HTTPSampler.contentEncoding"></stringProp>
           <stringProp name="HTTPSampler.path">${base_path}${product_url_key}</stringProp>
           <stringProp name="HTTPSampler.method">GET</stringProp>
@@ -73,7 +71,7 @@
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
-        </HTTPSampler>
+        </HTTPSamplerProxy>
         <hashTree>
           <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true">
             <collectionProp name="Asserion.test_strings">
@@ -86,6 +84,21 @@
           <hashTree/>
         </hashTree>
       </hashTree>
+      <ConfigTestElement guiclass="HttpDefaultsGui" testclass="ConfigTestElement" testname="HTTP Request Defaults" enabled="true">
+        <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
+          <collectionProp name="Arguments.arguments"/>
+        </elementProp>
+        <stringProp name="HTTPSampler.domain">${base_host}</stringProp>
+        <stringProp name="HTTPSampler.port"></stringProp>
+        <stringProp name="HTTPSampler.connect_timeout"></stringProp>
+        <stringProp name="HTTPSampler.response_timeout"></stringProp>
+        <stringProp name="HTTPSampler.protocol">http</stringProp>
+        <stringProp name="HTTPSampler.contentEncoding">utf-8</stringProp>
+        <stringProp name="HTTPSampler.path"></stringProp>
+        <stringProp name="HTTPSampler.implementation">HttpClient4</stringProp>
+        <stringProp name="HTTPSampler.concurrentPool">4</stringProp>
+      </ConfigTestElement>
+      <hashTree/>
       <ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree" enabled="false">
         <boolProp name="ResultCollector.error_logging">false</boolProp>
         <objProp>
@@ -113,6 +126,9 @@
             <saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>
             <assertionsResultsToSave>0</assertionsResultsToSave>
             <bytes>true</bytes>
+            <hostname>true</hostname>
+            <threadCounts>true</threadCounts>
+            <sampleCount>true</sampleCount>
           </value>
         </objProp>
         <stringProp name="filename"></stringProp>
diff --git a/dev/tests/performance/testsuite/quick_search.jmx b/dev/tests/performance/testsuite/quick_search.jmx
index 8aaf25840e63788e5bd9e391352801222c55a4db..82ab754249e5b72acc767bdb30f25db1faf2b8da 100644
--- a/dev/tests/performance/testsuite/quick_search.jmx
+++ b/dev/tests/performance/testsuite/quick_search.jmx
@@ -1,13 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
 /**
- * @category    Magento
- * @package     performance_tests
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
 -->
-<jmeterTestPlan version="1.2" properties="2.1">
+<jmeterTestPlan version="1.2" properties="2.7" jmeter="2.12 r1636949">
   <hashTree>
     <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Quick Search" enabled="true">
       <stringProp name="TestPlan.comments"></stringProp>
@@ -60,7 +58,7 @@
         <stringProp name="ThreadGroup.delay"></stringProp>
       </ThreadGroup>
       <hashTree>
-        <HTTPSampler guiclass="HttpTestSampleGui" testclass="HTTPSampler" testname="Quick Search" enabled="true">
+        <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Quick Search" enabled="true">
           <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" enabled="true">
             <collectionProp name="Arguments.arguments">
               <elementProp name="q" elementType="HTTPArgument">
@@ -72,7 +70,7 @@
               </elementProp>
             </collectionProp>
           </elementProp>
-          <stringProp name="HTTPSampler.domain">${HOST}</stringProp>
+          <stringProp name="HTTPSampler.domain"></stringProp>
           <stringProp name="HTTPSampler.port"></stringProp>
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
@@ -86,7 +84,7 @@
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
-        </HTTPSampler>
+        </HTTPSamplerProxy>
         <hashTree>
           <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true">
             <collectionProp name="HeaderManager.headers">
@@ -119,7 +117,7 @@
           <hashTree/>
           <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true">
             <collectionProp name="Asserion.test_strings">
-              <stringProp name="-887183200">Search results for: &apos;${search_query}&apos;</stringProp>
+              <stringProp name="-382529492">Search results for: &apos;${search_query}&apos;</stringProp>
             </collectionProp>
             <stringProp name="Assertion.test_field">Assertion.response_data</stringProp>
             <boolProp name="Assertion.assume_success">false</boolProp>
@@ -128,6 +126,21 @@
           <hashTree/>
         </hashTree>
       </hashTree>
+      <ConfigTestElement guiclass="HttpDefaultsGui" testclass="ConfigTestElement" testname="HTTP Request Defaults" enabled="true">
+        <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
+          <collectionProp name="Arguments.arguments"/>
+        </elementProp>
+        <stringProp name="HTTPSampler.domain">${HOST}</stringProp>
+        <stringProp name="HTTPSampler.port"></stringProp>
+        <stringProp name="HTTPSampler.connect_timeout"></stringProp>
+        <stringProp name="HTTPSampler.response_timeout"></stringProp>
+        <stringProp name="HTTPSampler.protocol">http</stringProp>
+        <stringProp name="HTTPSampler.contentEncoding">utf-8</stringProp>
+        <stringProp name="HTTPSampler.path"></stringProp>
+        <stringProp name="HTTPSampler.implementation">HttpClient4</stringProp>
+        <stringProp name="HTTPSampler.concurrentPool">4</stringProp>
+      </ConfigTestElement>
+      <hashTree/>
       <CookieManager guiclass="CookiePanel" testclass="CookieManager" testname="HTTP Cookie Manager" enabled="true">
         <collectionProp name="CookieManager.cookies"/>
         <boolProp name="CookieManager.clearEachIteration">true</boolProp>
diff --git a/dev/tests/performance/testsuite/reusable/admin_login.jmx b/dev/tests/performance/testsuite/reusable/admin_login.jmx
index 6d271217d8989d6d97eb0aaf52f9627c5ddcb9f8..9d6eb8fb2cb2e2d23d120603de002bcd3ab108dc 100644
--- a/dev/tests/performance/testsuite/reusable/admin_login.jmx
+++ b/dev/tests/performance/testsuite/reusable/admin_login.jmx
@@ -1,13 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
 /**
- * @category    Magento
- * @package     performance_tests
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
 -->
-<jmeterTestPlan version="1.2" properties="2.4" jmeter="2.9 r1437961">
+<jmeterTestPlan version="1.2" properties="2.7" jmeter="2.12 r1636949">
   <hashTree>
     <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Admin - Login" enabled="true">
       <stringProp name="TestPlan.comments">Reusable scenario to log-in to admin backend. Needs: HOST, ADMIN_PATH, ADMIN_USER, ADMIN_PASSWORD, Http Cookie Manager</stringProp>
@@ -29,7 +27,7 @@
           <stringProp name="HTTPSampler.port"></stringProp>
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
-          <stringProp name="HTTPSampler.protocol">http</stringProp>
+          <stringProp name="HTTPSampler.protocol"></stringProp>
           <stringProp name="HTTPSampler.contentEncoding"></stringProp>
           <stringProp name="HTTPSampler.path">${ADMIN_PATH}</stringProp>
           <stringProp name="HTTPSampler.method">GET</stringProp>
@@ -37,14 +35,13 @@
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
         <hashTree>
           <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Assert login form shown" enabled="true">
             <collectionProp name="Asserion.test_strings">
-              <stringProp name="1661392365">Log into Magento Admin Page</stringProp>
+              <stringProp name="731356397">Log into Magento Admin Page</stringProp>
             </collectionProp>
             <stringProp name="Assertion.test_field">Assertion.response_data</stringProp>
             <boolProp name="Assertion.assume_success">false</boolProp>
@@ -91,11 +88,11 @@
               </elementProp>
             </collectionProp>
           </elementProp>
-          <stringProp name="HTTPSampler.domain">${HOST}</stringProp>
+          <stringProp name="HTTPSampler.domain"></stringProp>
           <stringProp name="HTTPSampler.port"></stringProp>
           <stringProp name="HTTPSampler.connect_timeout"></stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
-          <stringProp name="HTTPSampler.protocol">http</stringProp>
+          <stringProp name="HTTPSampler.protocol"></stringProp>
           <stringProp name="HTTPSampler.contentEncoding"></stringProp>
           <stringProp name="HTTPSampler.path">${ADMIN_PATH}</stringProp>
           <stringProp name="HTTPSampler.method">POST</stringProp>
@@ -103,14 +100,13 @@
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
         <hashTree>
           <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Assert logged-in" enabled="true">
             <collectionProp name="Asserion.test_strings">
-              <stringProp name="934841248">${ADMIN_USER}</stringProp>
+              <stringProp name="-348322869">${ADMIN_USER}</stringProp>
               <stringProp name="-989788387">Account Setting</stringProp>
               <stringProp name="374398571">Sign Out</stringProp>
             </collectionProp>
@@ -159,23 +155,38 @@
             </elementProp>
             <elementProp name="ADMIN_PATH" elementType="Argument">
               <stringProp name="Argument.name">ADMIN_PATH</stringProp>
-              <stringProp name="Argument.value">${__P(path,/)}${__P(backend_frontname,backend)}/</stringProp>
+              <stringProp name="Argument.value">${__P(path,/)}${__P(backend-frontname,backend)}/</stringProp>
               <stringProp name="Argument.metadata">=</stringProp>
             </elementProp>
             <elementProp name="ADMIN_USER" elementType="Argument">
               <stringProp name="Argument.name">ADMIN_USER</stringProp>
-              <stringProp name="Argument.value">${__P(admin_user,admin)}</stringProp>
+              <stringProp name="Argument.value">${__P(admin-user,admin)}</stringProp>
               <stringProp name="Argument.metadata">=</stringProp>
             </elementProp>
             <elementProp name="ADMIN_PASSWORD" elementType="Argument">
               <stringProp name="Argument.name">ADMIN_PASSWORD</stringProp>
-              <stringProp name="Argument.value">${__P(admin_password,123123q)}</stringProp>
+              <stringProp name="Argument.value">${__P(admin-password,123123q)}</stringProp>
               <stringProp name="Argument.metadata">=</stringProp>
             </elementProp>
           </collectionProp>
         </Arguments>
         <hashTree/>
       </hashTree>
+      <ConfigTestElement guiclass="HttpDefaultsGui" testclass="ConfigTestElement" testname="HTTP Request Defaults" enabled="true">
+        <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
+          <collectionProp name="Arguments.arguments"/>
+        </elementProp>
+        <stringProp name="HTTPSampler.domain">${HOST}</stringProp>
+        <stringProp name="HTTPSampler.port"></stringProp>
+        <stringProp name="HTTPSampler.connect_timeout"></stringProp>
+        <stringProp name="HTTPSampler.response_timeout"></stringProp>
+        <stringProp name="HTTPSampler.protocol">http</stringProp>
+        <stringProp name="HTTPSampler.contentEncoding">utf-8</stringProp>
+        <stringProp name="HTTPSampler.path"></stringProp>
+        <stringProp name="HTTPSampler.implementation">HttpClient4</stringProp>
+        <stringProp name="HTTPSampler.concurrentPool">4</stringProp>
+      </ConfigTestElement>
+      <hashTree/>
       <ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree" enabled="true">
         <boolProp name="ResultCollector.error_logging">false</boolProp>
         <objProp>
@@ -203,6 +214,9 @@
             <saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>
             <assertionsResultsToSave>0</assertionsResultsToSave>
             <bytes>true</bytes>
+            <hostname>true</hostname>
+            <threadCounts>true</threadCounts>
+            <sampleCount>true</sampleCount>
           </value>
         </objProp>
         <stringProp name="filename"></stringProp>
diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/Readme/_files/blacklist/ce.txt b/dev/tests/static/testsuite/Magento/Test/Integrity/Readme/_files/blacklist/ce.txt
index 2fd6ad123621cb9b830d5d02b3840463d4520fbc..564d756255d7e6b7be5db625ccf8ebb0e634a026 100644
--- a/dev/tests/static/testsuite/Magento/Test/Integrity/Readme/_files/blacklist/ce.txt
+++ b/dev/tests/static/testsuite/Magento/Test/Integrity/Readme/_files/blacklist/ce.txt
@@ -35,5 +35,6 @@ lib/internal/Magento/Framework/System
 lib/internal/Magento/Framework/Test
 lib/internal/Magento/Framework/App/Utility
 lib/internal/Magento/Framework/Url
+lib/internal/Magento/Framework/UrlInterface
 lib/internal/Magento/Framework/Xml
 lib/internal/Magento/Framework
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/LayoutTest.php b/dev/tests/static/testsuite/Magento/Test/Legacy/LayoutTest.php
index ae89d5ddb32941c6dace4b041fe459153a34a6cb..28353e7f953138cfa0dd3d91b04c17f70062e07a 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/LayoutTest.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/LayoutTest.php
@@ -316,7 +316,6 @@ class LayoutTest extends \PHPUnit_Framework_TestCase
             'setListOrders',
             'setMAPTemplate',
             'setMethodFormTemplate',
-            'setMethodInfo',
             'setMyClass',
             'setPageLayout',
             'setPageTitle',
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_constants.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_constants.php
index a3fa40a7f43a6718bc2949067c23dd314b874c11..b0e6f2627029a8da911b3e6a4358c3aff4f133af 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_constants.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_constants.php
@@ -702,4 +702,26 @@ return [
         'Use \Magento\Eav\Model\Entity\Type::getDefaultAttributeSetId() method instead',
     ],
     ['CONFIG_PATH_WSDL_CACHE_ENABLED', 'Magento\Webapi\Model\Soap\Server'],
+    ['ENTITY', 'Magento\Framework\App\Config\ValueInterface'],
+    ['XML_PATH_ALLOW_CURRENCIES_INSTALLED', 'Magento\Framework\Locale\CurrencyInterface'],
+    [
+        'DEFAULT_CURRENCY',
+        'Magento\Framework\Locale\CurrencyInterface',
+        'Magento\Framework\Locale\Currency::DEFAULT_CURRENCY'
+    ],
+    [
+        'DEFAULT_LOCALE',
+        'Magento\Framework\Locale\ResolverInterface',
+        'Magento\Framework\Locale\Resolver::DEFAULT_LOCALE'
+    ],
+    [
+        'DEFAULT_GROUP',
+        'Magento\Framework\Message\ManagerInterface',
+        'Magento\Framework\Message\Manager::DEFAULT_GROUP'
+    ],
+    [
+        'SCOPE_DEFAULT',
+        'Magento\Framework\App\ScopeInterface',
+        'Magento\Framework\App\Config\ScopeConfigInterface::SCOPE_TYPE_DEFAULT'
+    ]
 ];
diff --git a/dev/tests/unit/framework/bootstrap.php b/dev/tests/unit/framework/bootstrap.php
index b30486b50a17dc3a6e0b67adaa072868b1747736..45ae70bc21fbb39fc79b347cc4749a6243d18d7f 100755
--- a/dev/tests/unit/framework/bootstrap.php
+++ b/dev/tests/unit/framework/bootstrap.php
@@ -6,6 +6,11 @@
 
 require_once __DIR__ . '/../../../../app/autoload.php';
 
+$updateAppBootstrap = __DIR__ . '/../../../../update/app/bootstrap.php';
+if (file_exists($updateAppBootstrap)) {
+    require_once $updateAppBootstrap;
+}
+
 if (!defined('TESTS_TEMP_DIR')) {
     define('TESTS_TEMP_DIR', dirname(__DIR__) . '/tmp');
 }
diff --git a/dev/tests/unit/phpunit.xml.dist b/dev/tests/unit/phpunit.xml.dist
index 5c785e252e48aa8c82aa8bcfe817c761b38ecc23..4c5587187da794847e7e0e6c47157106193a14fd 100644
--- a/dev/tests/unit/phpunit.xml.dist
+++ b/dev/tests/unit/phpunit.xml.dist
@@ -17,6 +17,7 @@
         <directory suffix="Test.php">../../../lib/internal/*/*/Test/Unit</directory>
         <directory suffix="Test.php">../../../lib/internal/*/*/*/Test/Unit</directory>
         <directory suffix="Test.php">../../../setup/src/*/*/Test/Unit</directory>
+        <directory suffix="Test.php">../../../update/dev/tests/unit/testsuite</directory>
     </testsuite>
     <php>
         <ini name="date.timezone" value="America/Los_Angeles"/>
@@ -26,6 +27,7 @@
             <directory suffix=".php">../../../app/code/*</directory>
             <directory suffix=".php">../../../lib/internal/Magento</directory>
             <directory suffix=".php">../../../setup/src/*</directory>
+            <directory suffix=".php">../../../update/app/code/*</directory>
             <exclude>
                 <directory>../../../app/code/*/*/Test</directory>
                 <directory>../../../lib/internal/*/*/Test</directory>
diff --git a/dev/tools/performance-toolkit/fixtures/indexers_states_apply.php b/dev/tools/performance-toolkit/fixtures/indexers_states_apply.php
new file mode 100644
index 0000000000000000000000000000000000000000..8b072e2b68995399e051ab77cf868efb15638630
--- /dev/null
+++ b/dev/tools/performance-toolkit/fixtures/indexers_states_apply.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+/**
+ * Class IndexersStatesApplyFixture
+ */
+class IndexersStatesApplyFixture extends \Magento\ToolkitFramework\Fixture
+{
+    /**
+     * @var int
+     */
+    protected $priority = 170;
+
+    /**
+     * {@inheritdoc}
+     */
+    public function execute()
+    {
+        $indexers = \Magento\ToolkitFramework\Config::getInstance()->getValue('indexers', []);
+        if (!isset($indexers["indexer"]) || empty($indexers["indexer"])) {
+            return;
+        }
+        $this->application->resetObjectManager();
+        foreach ($indexers["indexer"] as $indexer) {
+            $this->application->indexersStates[$indexer['id']] = ($indexer['set_scheduled'] == "true");
+        }
+        $this->application->getObjectManager()->get('Magento\Framework\App\CacheInterface')
+            ->clean([\Magento\Framework\App\Config::CACHE_TAG]);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getActionTitle()
+    {
+        return 'Indexers Mode Changes';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function introduceParamLabels()
+    {
+        return [];
+    }
+}
+
+return new IndexersStatesApplyFixture($this);
diff --git a/dev/tools/performance-toolkit/fixtures/orders.php b/dev/tools/performance-toolkit/fixtures/orders.php
new file mode 100644
index 0000000000000000000000000000000000000000..041fcea755125f106f7715913c5bfe13b1dff926
--- /dev/null
+++ b/dev/tools/performance-toolkit/fixtures/orders.php
@@ -0,0 +1,314 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+/**
+ * Class OrdersFixture
+ */
+class OrdersFixture extends \Magento\ToolkitFramework\Fixture
+{
+    /**
+     * @var int
+     */
+    protected $priority = 135;
+
+    /**
+     * {@inheritdoc}
+     */
+    public function execute()
+    {
+        $ordersCount = \Magento\ToolkitFramework\Config::getInstance()->getValue('orders', 0);
+        if ($ordersCount < 1) {
+            return;
+        }
+        $this->application->resetObjectManager();
+
+        $writeAdapter = $this->getConnection('write');
+
+        $quoteTableName = $this->getTableName(
+            'quote',
+            'Magento\Quote\Model\Resource\Quote'
+        );
+        $quoteAddressTableName = $this->getTableName(
+            'quote_address',
+            'Magento\Quote\Model\Resource\Quote\Address'
+        );
+        $quoteItemTableName = $this->getTableName(
+            'quote_item',
+            'Magento\Quote\Model\Resource\Quote\Item'
+        );
+        $quoteItemOptionTableName = $this->getTableName(
+            'quote_item_option',
+            'Magento\Quote\Model\Resource\Quote\Item\Option'
+        );
+        $quotePaymentTableName = $this->getTableName(
+            'quote_payment',
+            'Magento\Quote\Model\Resource\Quote\Payment'
+        );
+        $quoteAddressRateTableName = $this->getTableName(
+            'quote_shipping_rate',
+            'Magento\Quote\Model\Resource\Quote\Address\Rate'
+        );
+        $reportEventTableName = $this->getTableName(
+            'report_event',
+            'Magento\Reports\Model\Resource\Event'
+        );
+        $salesOrderTableName = $this->getTableName(
+            'sales_order',
+            'Magento\Sales\Model\Resource\Order'
+        );
+        $salesOrderAddressTableName = $this->getTableName(
+            'sales_order_address',
+            'Magento\Sales\Model\Resource\Order'
+        );
+        $salesOrderGridTableName = $this->getTableName(
+            'sales_order_grid',
+            'Magento\Sales\Model\Resource\Order\Grid'
+        );
+        $salesOrderItemTableName = $this->getTableName(
+            'sales_order_item',
+            'Magento\Sales\Model\Resource\Order\Item'
+        );
+        $salesOrderPaymentTableName = $this->getTableName(
+            'sales_order_payment',
+            'Magento\Sales\Model\Resource\Order\Payment'
+        );
+        $salesOrderStatusHistoryTableName = $this->getTableName(
+            'sales_order_status_history',
+            'Magento\Sales\Model\Resource\Order\Status\History'
+        );
+        $eavEntityStoreTableName = $this->getTableName(
+            'eav_entity_store',
+            '\Magento\Eav\Model\Resource\Entity\Store'
+        );
+        /** @var \Magento\Store\Model\StoreManager $storeManager */
+        $storeManager = $this->application->getObjectManager()->create('Magento\Store\Model\StoreManager');
+        /** @var $category \Magento\Catalog\Model\Category */
+        $category = $this->application->getObjectManager()->get('Magento\Catalog\Model\Category');
+        /** @var $product \Magento\Catalog\Model\Product */
+        $product = $this->application->getObjectManager()->get('Magento\Catalog\Model\Product');
+
+        $result = [];
+        $stores = $storeManager->getStores();
+        foreach ($stores as $store) {
+            $storeId = $store->getStoreId();
+            $websiteId = $store->getWebsite()->getId();
+            $websiteName = $store->getWebsite()->getName();
+            $groupName = $store->getGroup()->getName();
+            $storeName = $store->getName();
+            $storeRootCategory = $store->getRootCategoryId();
+            $category->load($storeRootCategory);
+            $categoryResource = $category->getResource();
+            //Get all categories
+            $resultsCategories = $categoryResource->getAllChildren($category);
+            foreach ($resultsCategories as $resultsCategory) {
+                $category->load($resultsCategory);
+                $structure = explode('/', $category->getPath());
+                $pathSize = count($structure);
+                if ($pathSize > 1) {
+                    $path = [];
+                    for ($i = 1; $i < $pathSize; $i++) {
+                        $path[] = $category->load($structure[$i])->getName();
+                    }
+                    array_shift($path);
+                    $resultsCategoryName = implode('/', $path);
+                } else {
+                    $resultsCategoryName = $category->getName();
+                }
+                //Not use root categories
+                if (trim($resultsCategoryName) != '') {
+                    /** @var $productCategory \Magento\Catalog\Model\Category */
+                    $productCategory = $this->application->getObjectManager()->get('Magento\Catalog\Model\Category');
+
+                    /** @var $simpleProductCollection \Magento\Catalog\Model\Resource\Product\Collection */
+                    $simpleProductCollection = $this->application->getObjectManager()->create(
+                        'Magento\Catalog\Model\Resource\Product\Collection'
+                    );
+
+                    $simpleProductCollection->addStoreFilter($storeId);
+                    $simpleProductCollection->addWebsiteFilter($websiteId);
+                    $simpleProductCollection->addCategoryFilter($productCategory->load($resultsCategory));
+                    $simpleProductCollection->getSelect()->where(" type_id = 'simple' ");
+                    $simpleIds = $simpleProductCollection->getAllIds(2);
+                    $simpleProductsResult = [];
+                    foreach ($simpleIds as $key => $simpleId) {
+                        $simpleProduct = $product->load($simpleId);
+                        $simpleProductsResult[$key]['simpleProductId'] = $simpleId;
+                        $simpleProductsResult[$key]['simpleProductSku'] = $simpleProduct->getSku();
+                        $simpleProductsResult[$key]['simpleProductName'] = $simpleProduct->getName();
+                    }
+
+                    $result[] = [
+                        $storeId,
+                        $websiteName. '\n'. $groupName . '\n' . $storeName,
+                        $simpleProductsResult
+                    ];
+                }
+            }
+        }
+
+        $productStoreId = function ($index) use ($result) {
+            return $result[$index % count($result)][0];
+        };
+        $productStoreName = function ($index) use ($result) {
+            return $result[$index % count($result)][1];
+        };
+
+        $simpleProductId[0] = function ($index) use ($result) {
+            return $result[$index % count($result)][2][0]['simpleProductId'];
+        };
+        $simpleProductId[1] = function ($index) use ($result) {
+            return $result[$index % count($result)][2][1]['simpleProductId'];
+        };
+        $simpleProductSku[0] = function ($index) use ($result) {
+            return $result[$index % count($result)][2][0]['simpleProductSku'];
+        };
+        $simpleProductSku[1] = function ($index) use ($result) {
+            return $result[$index % count($result)][2][1]['simpleProductSku'];
+        };
+        $simpleProductName[0] = function ($index) use ($result) {
+            return $result[$index % count($result)][2][0]['simpleProductName'];
+        };
+        $simpleProductName[1] = function ($index) use ($result) {
+            return $result[$index % count($result)][2][1]['simpleProductName'];
+        };
+
+        $entityId = 1;
+        while ($entityId <= $ordersCount) {
+            $queries = "";
+
+            $orderNumber = 100000000 * $productStoreId($entityId) + $entityId;
+            $email = 'order_' . $entityId . '@example.com';
+            $firstName = 'First Name';
+            $lastName = 'Last Name';
+            $company = 'Company';
+            $address = 'Address';
+            $city = 'City';
+            $state = 'Alabama';
+            $country = 'US';
+            $zip = '11111';
+            $phone = '911';
+            $time = date("Y-m-d h:i:s");
+
+            $simpleProductIdLen[0] = strlen($simpleProductId[0]($entityId));
+            $simpleProductIdLen[1] = strlen($simpleProductId[1]($entityId));
+
+            $queries .= "INSERT INTO `{$eavEntityStoreTableName}` (`entity_store_id`, `entity_type_id`, `store_id`, `increment_prefix`, `increment_last_id`) VALUES ({$productStoreId($entityId)}, 5, {$productStoreId($entityId)}, '{$productStoreId($entityId)}', '{$orderNumber}') ON DUPLICATE KEY UPDATE `increment_last_id`='{$orderNumber}';";
+
+            $quoteId = $entityId;
+            $queries .= "INSERT INTO `{$quoteTableName}` (`entity_id`, `store_id`, `created_at`, `updated_at`, `converted_at`, `is_active`, `is_virtual`, `is_multi_shipping`, `items_count`, `items_qty`, `orig_order_id`, `store_to_base_rate`, `store_to_quote_rate`, `base_currency_code`, `store_currency_code`, `quote_currency_code`, `grand_total`, `base_grand_total`, `checkout_method`, `customer_id`, `customer_tax_class_id`, `customer_group_id`, `customer_email`, `customer_prefix`, `customer_firstname`, `customer_middlename`, `customer_lastname`, `customer_suffix`, `customer_dob`, `customer_note`, `customer_note_notify`, `customer_is_guest`, `remote_ip`, `applied_rule_ids`, `reserved_order_id`, `password_hash`, `coupon_code`, `global_currency_code`, `base_to_global_rate`, `base_to_quote_rate`, `customer_taxvat`, `customer_gender`, `subtotal`, `base_subtotal`, `subtotal_with_discount`, `base_subtotal_with_discount`, `is_changed`, `trigger_recollect`, `ext_shipping_info`, `is_persistent`, `gift_message_id`) VALUES ({$quoteId}, {$productStoreId($entityId)}, '{$time}', '1970-01-01 03:00:00', NULL, 0, 0, 0, 2, 2.0000, 0, 0.0000, 0.0000, 'USD', 'USD', 'USD', 25.3000, 25.3000, 'guest', NULL, 3, 0, '{$email}', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1, 1, '127.0.0.1', '1', NULL, NULL, NULL, 'USD', 1.0000, 1.0000, NULL, NULL, 17.0000, 17.0000, 15.3000, 15.3000, 1, 0, NULL, 0, NULL);";
+
+            $quoteAddressId[0] = $entityId * 2 - 1;
+            $quoteAddressId[1] = $entityId * 2;
+            $queries .= "INSERT INTO `{$quoteAddressTableName}` (`address_id`, `quote_id`, `created_at`, `updated_at`, `customer_id`, `save_in_address_book`, `customer_address_id`, `address_type`, `email`, `prefix`, `firstname`, `middlename`, `lastname`, `suffix`, `company`, `street`, `city`, `region`, `region_id`, `postcode`, `country_id`, `telephone`, `fax`, `same_as_billing`, `collect_shipping_rates`, `shipping_method`, `shipping_description`, `weight`, `subtotal`, `base_subtotal`, `subtotal_with_discount`, `base_subtotal_with_discount`, `tax_amount`, `base_tax_amount`, `shipping_amount`, `base_shipping_amount`, `shipping_tax_amount`, `base_shipping_tax_amount`, `discount_amount`, `base_discount_amount`, `grand_total`, `base_grand_total`, `customer_notes`, `applied_taxes`, `discount_description`, `shipping_discount_amount`, `base_shipping_discount_amount`, `subtotal_incl_tax`, `base_subtotal_total_incl_tax`, `hidden_tax_amount`, `base_hidden_tax_amount`, `shipping_hidden_tax_amount`, `base_shipping_hidden_tax_amnt`, `shipping_incl_tax`, `base_shipping_incl_tax`, `free_shipping`, `vat_id`, `vat_is_valid`, `vat_request_id`, `vat_request_date`, `vat_request_success`, `gift_message_id`) VALUES ({$quoteAddressId[0]}, {$quoteId}, '{$time}', '1970-01-01 03:00:00', NULL, 1, NULL, 'billing', '{$email}', NULL, '{$firstName}', NULL, '{$lastName}', NULL, '{$company}', '{$address}', '{$city}', '{$state}', 1, '{$zip}', '{$country}', '{$phone}', NULL, 0, 0, NULL, NULL, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, NULL, NULL, 0.0000, 0.0000, 0.0000, 0.0000, NULL, NULL, NULL, NULL, NULL, 0.0000, NULL, 0.0000, 0.0000, 0.0000, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL);";
+            $queries .= "INSERT INTO `{$quoteAddressTableName}` (`address_id`, `quote_id`, `created_at`, `updated_at`, `customer_id`, `save_in_address_book`, `customer_address_id`, `address_type`, `email`, `prefix`, `firstname`, `middlename`, `lastname`, `suffix`, `company`, `street`, `city`, `region`, `region_id`, `postcode`, `country_id`, `telephone`, `fax`, `same_as_billing`, `collect_shipping_rates`, `shipping_method`, `shipping_description`, `weight`, `subtotal`, `base_subtotal`, `subtotal_with_discount`, `base_subtotal_with_discount`, `tax_amount`, `base_tax_amount`, `shipping_amount`, `base_shipping_amount`, `shipping_tax_amount`, `base_shipping_tax_amount`, `discount_amount`, `base_discount_amount`, `grand_total`, `base_grand_total`, `customer_notes`, `applied_taxes`, `discount_description`, `shipping_discount_amount`, `base_shipping_discount_amount`, `subtotal_incl_tax`, `base_subtotal_total_incl_tax`, `hidden_tax_amount`, `base_hidden_tax_amount`, `shipping_hidden_tax_amount`, `base_shipping_hidden_tax_amnt`, `shipping_incl_tax`, `base_shipping_incl_tax`, `free_shipping`, `vat_id`, `vat_is_valid`, `vat_request_id`, `vat_request_date`, `vat_request_success`, `gift_message_id`) VALUES ({$quoteAddressId[1]}, {$quoteId}, '{$time}', '1970-01-01 03:00:00', NULL, 0, NULL, 'shipping', '{$email}', NULL, '{$firstName}', NULL, '{$lastName}', NULL, '{$company}', '{$address}', '{$city}', '{$state}', 1, '{$zip}', '{$country}', '{$phone}', NULL, 1, 0, 'flatrate_flatrate', 'Flat Rate - Fixed', 2.0000, 17.0000, 17.0000, 0.0000, 0.0000, 0.0000, 0.0000, 10.0000, 10.0000, 0.0000, 0.0000, -1.7000, -1.7000, 25.3000, 25.3000, NULL, 'a:0:{}', NULL, 0.0000, 0.0000, 17.0000, NULL, 0.0000, 0.0000, 0.0000, NULL, 10.0000, 10.0000, 0, NULL, NULL, NULL, NULL, NULL, NULL);";
+
+            $quoteItemId[0] = $entityId * 4 - 3;
+            $quoteItemId[1] = $entityId * 4 - 2;
+            $quoteItemId[2] = $entityId * 4 - 1;
+            $quoteItemId[3] = $entityId * 4;
+            $queries .= "INSERT INTO `{$quoteItemTableName}` (`item_id`, `quote_id`, `created_at`, `updated_at`, `product_id`, `store_id`, `parent_item_id`, `is_virtual`, `sku`, `name`, `description`, `applied_rule_ids`, `additional_data`, `is_qty_decimal`, `no_discount`, `weight`, `qty`, `price`, `base_price`, `custom_price`, `discount_percent`, `discount_amount`, `base_discount_amount`, `tax_percent`, `tax_amount`, `base_tax_amount`, `row_total`, `base_row_total`, `row_total_with_discount`, `row_weight`, `product_type`, `base_tax_before_discount`, `tax_before_discount`, `original_custom_price`, `redirect_url`, `base_cost`, `price_incl_tax`, `base_price_incl_tax`, `row_total_incl_tax`, `base_row_total_incl_tax`, `hidden_tax_amount`, `base_hidden_tax_amount`, `free_shipping`, `gift_message_id`, `weee_tax_applied`, `weee_tax_applied_amount`, `weee_tax_applied_row_amount`, `weee_tax_disposition`, `weee_tax_row_disposition`, `base_weee_tax_applied_amount`, `base_weee_tax_applied_row_amnt`, `base_weee_tax_disposition`, `base_weee_tax_row_disposition`) VALUES ({$quoteItemId[0]}, {$quoteId}, '1970-01-01 03:00:00', '1970-01-01 03:00:00', {$simpleProductId[0]($entityId)}, {$productStoreId($entityId)}, NULL, 0, '{$simpleProductSku[0]($entityId)}', '{$simpleProductName[0]($entityId)}', NULL, '1', NULL, 0, 0, 1.0000, 1.0000, 8.5000, 8.5000, NULL, 10.0000, 0.8500, 0.8500, 0.0000, 0.0000, 0.0000, 8.5000, 8.5000, 0.0000, 1.0000, 'simple', NULL, NULL, NULL, NULL, NULL, 8.5000, 8.5000, 8.5000, 8.5000, 0.0000, 0.0000, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);";
+            $queries .= "INSERT INTO `{$quoteItemTableName}` (`item_id`, `quote_id`, `created_at`, `updated_at`, `product_id`, `store_id`, `parent_item_id`, `is_virtual`, `sku`, `name`, `description`, `applied_rule_ids`, `additional_data`, `is_qty_decimal`, `no_discount`, `weight`, `qty`, `price`, `base_price`, `custom_price`, `discount_percent`, `discount_amount`, `base_discount_amount`, `tax_percent`, `tax_amount`, `base_tax_amount`, `row_total`, `base_row_total`, `row_total_with_discount`, `row_weight`, `product_type`, `base_tax_before_discount`, `tax_before_discount`, `original_custom_price`, `redirect_url`, `base_cost`, `price_incl_tax`, `base_price_incl_tax`, `row_total_incl_tax`, `base_row_total_incl_tax`, `hidden_tax_amount`, `base_hidden_tax_amount`, `free_shipping`, `gift_message_id`, `weee_tax_applied`, `weee_tax_applied_amount`, `weee_tax_applied_row_amount`, `weee_tax_disposition`, `weee_tax_row_disposition`, `base_weee_tax_applied_amount`, `base_weee_tax_applied_row_amnt`, `base_weee_tax_disposition`, `base_weee_tax_row_disposition`) VALUES ({$quoteItemId[1]}, {$quoteId}, '1970-01-01 03:00:00', '1970-01-01 03:00:00', {$simpleProductId[1]($entityId)}, {$productStoreId($entityId)}, NULL, 0, '{$simpleProductSku[1]($entityId)}', '{$simpleProductName[1]($entityId)}', NULL, '1', NULL, 0, 0, 1.0000, 1.0000, 8.5000, 8.5000, NULL, 10.0000, 0.8500, 0.8500, 0.0000, 0.0000, 0.0000, 8.5000, 8.5000, 0.0000, 1.0000, 'simple', NULL, NULL, NULL, NULL, NULL, 8.5000, 8.5000, 8.5000, 8.5000, 0.0000, 0.0000, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);";
+
+            $quoteItemOptionId[0] = $entityId * 8 - 7;
+            $quoteItemOptionId[1] = $entityId * 8 - 6;
+            $quoteItemOptionId[2] = $entityId * 8 - 5;
+            $quoteItemOptionId[3] = $entityId * 8 - 4;
+            $quoteItemOptionId[4] = $entityId * 8 - 3;
+            $quoteItemOptionId[5] = $entityId * 8 - 2;
+            $quoteItemOptionId[6] = $entityId * 8 - 1;
+            $quoteItemOptionId[7] = $entityId * 8;
+            $queries .= "INSERT INTO `{$quoteItemOptionTableName}` (`option_id`, `item_id`, `product_id`, `code`, `value`) VALUES ({$quoteItemOptionId[0]}, {$quoteItemId[0]}, {$simpleProductId[0]($entityId)}, 'info_buyRequest', 'a:3:{s:4:\"uenc\";s:44:\"aHR0cDovL21hZ2UyLmNvbS9jYXRlZ29yeS0xLmh0bWw,\";s:7:\"product\";s:{$simpleProductIdLen[0]}:\"{$simpleProductId[0]($entityId)}\";s:3:\"qty\";i:1;}');";
+            $queries .= "INSERT INTO `{$quoteItemOptionTableName}` (`option_id`, `item_id`, `product_id`, `code`, `value`) VALUES ({$quoteItemOptionId[1]}, {$quoteItemId[1]}, {$simpleProductId[1]($entityId)}, 'info_buyRequest', 'a:3:{s:4:\"uenc\";s:44:\"aHR0cDovL21hZ2UyLmNvbS9jYXRlZ29yeS0xLmh0bWw,\";s:7:\"product\";s:{$simpleProductIdLen[1]}:\"{$simpleProductId[1]($entityId)}\";s:3:\"qty\";i:1;}');";
+
+            $quotePaymentId = $quoteId;
+            $queries .= "INSERT INTO `{$quotePaymentTableName}` (`payment_id`, `quote_id`, `created_at`, `updated_at`, `method`, `cc_type`, `cc_number_enc`, `cc_last_4`, `cc_cid_enc`, `cc_owner`, `cc_exp_month`, `cc_exp_year`, `cc_ss_owner`, `cc_ss_start_month`, `cc_ss_start_year`, `po_number`, `additional_data`, `cc_ss_issue`, `additional_information`) VALUES ({$quotePaymentId}, {$quoteId}, '{$time}', '1970-01-01 03:00:00', 'checkmo', NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0, 0, NULL, NULL, NULL, NULL);";
+
+            $quoteShippingRateId = $quoteAddressId[1];
+            $queries .= "INSERT INTO `{$quoteAddressRateTableName}` (`rate_id`, `address_id`, `created_at`, `updated_at`, `carrier`, `carrier_title`, `code`, `method`, `method_description`, `price`, `error_message`, `method_title`) VALUES ({$quoteShippingRateId}, {$quoteAddressId[1]}, '{$time}', '1970-01-01 03:00:00', 'flatrate', 'Flat Rate', 'flatrate_flatrate', 'flatrate', NULL, 10.0000, NULL, 'Fixed');";
+
+            $reportEventId[0] = $quoteItemId[0];
+            $reportEventId[1] = $quoteItemId[1];
+            $reportEventId[2] = $quoteItemId[2];
+            $reportEventId[3] = $quoteItemId[3];
+            $queries .= "INSERT INTO `{$reportEventTableName}` (`event_id`, `logged_at`, `event_type_id`, `object_id`, `subject_id`, `subtype`, `store_id`) VALUES ({$reportEventId[0]}, '{$time}', 4, {$simpleProductId[0]($entityId)}, 2, 1, {$productStoreId($entityId)});";
+            $queries .= "INSERT INTO `{$reportEventTableName}` (`event_id`, `logged_at`, `event_type_id`, `object_id`, `subject_id`, `subtype`, `store_id`) VALUES ({$reportEventId[1]}, '{$time}', 4, {$simpleProductId[1]($entityId)}, 2, 1, {$productStoreId($entityId)});";
+
+            $salesOrderId = $quoteId;
+            $queries .= "INSERT INTO `{$salesOrderTableName}` (`entity_id`, `state`, `status`, `coupon_code`, `protect_code`, `shipping_description`, `is_virtual`, `store_id`, `customer_id`, `base_discount_amount`, `base_discount_canceled`, `base_discount_invoiced`, `base_discount_refunded`, `base_grand_total`, `base_shipping_amount`, `base_shipping_canceled`, `base_shipping_invoiced`, `base_shipping_refunded`, `base_shipping_tax_amount`, `base_shipping_tax_refunded`, `base_subtotal`, `base_subtotal_canceled`, `base_subtotal_invoiced`, `base_subtotal_refunded`, `base_tax_amount`, `base_tax_canceled`, `base_tax_invoiced`, `base_tax_refunded`, `base_to_global_rate`, `base_to_order_rate`, `base_total_canceled`, `base_total_invoiced`, `base_total_invoiced_cost`, `base_total_offline_refunded`, `base_total_online_refunded`, `base_total_paid`, `base_total_qty_ordered`, `base_total_refunded`, `discount_amount`, `discount_canceled`, `discount_invoiced`, `discount_refunded`, `grand_total`, `shipping_amount`, `shipping_canceled`, `shipping_invoiced`, `shipping_refunded`, `shipping_tax_amount`, `shipping_tax_refunded`, `store_to_base_rate`, `store_to_order_rate`, `subtotal`, `subtotal_canceled`, `subtotal_invoiced`, `subtotal_refunded`, `tax_amount`, `tax_canceled`, `tax_invoiced`, `tax_refunded`, `total_canceled`, `total_invoiced`, `total_offline_refunded`, `total_online_refunded`, `total_paid`, `total_qty_ordered`, `total_refunded`, `can_ship_partially`, `can_ship_partially_item`, `customer_is_guest`, `customer_note_notify`, `billing_address_id`, `customer_group_id`, `edit_increment`, `email_sent`, `send_email`, `forced_shipment_with_invoice`, `payment_auth_expiration`, `quote_address_id`, `quote_id`, `shipping_address_id`, `adjustment_negative`, `adjustment_positive`, `base_adjustment_negative`, `base_adjustment_positive`, `base_shipping_discount_amount`, `base_subtotal_incl_tax`, `base_total_due`, `payment_authorization_amount`, `shipping_discount_amount`, `subtotal_incl_tax`, `total_due`, `weight`, `customer_dob`, `increment_id`, `applied_rule_ids`, `base_currency_code`, `customer_email`, `customer_firstname`, `customer_lastname`, `customer_middlename`, `customer_prefix`, `customer_suffix`, `customer_taxvat`, `discount_description`, `ext_customer_id`, `ext_order_id`, `global_currency_code`, `hold_before_state`, `hold_before_status`, `order_currency_code`, `original_increment_id`, `relation_child_id`, `relation_child_real_id`, `relation_parent_id`, `relation_parent_real_id`, `remote_ip`, `shipping_method`, `store_currency_code`, `store_name`, `x_forwarded_for`, `customer_note`, `created_at`, `updated_at`, `total_item_count`, `customer_gender`, `hidden_tax_amount`, `base_hidden_tax_amount`, `shipping_hidden_tax_amount`, `base_shipping_hidden_tax_amnt`, `hidden_tax_invoiced`, `base_hidden_tax_invoiced`, `hidden_tax_refunded`, `base_hidden_tax_refunded`, `shipping_incl_tax`, `base_shipping_incl_tax`, `coupon_rule_name`, `gift_message_id`) VALUES ({$salesOrderId}, 'new', 'pending', NULL, '272ecb', 'Flat Rate - Fixed', 0, {$productStoreId($entityId)}, NULL, -1.7000, NULL, NULL, NULL, 25.3000, 10.0000, NULL, NULL, NULL, 0.0000, NULL, 17.0000, NULL, NULL, NULL, 0.0000, NULL, NULL, NULL, 1.0000, 1.0000, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1.7000, NULL, NULL, NULL, 25.3000, 10.0000, NULL, NULL, NULL, 0.0000, NULL, 0.0000, 0.0000, 17.0000, NULL, NULL, NULL, 0.0000, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 2.0000, NULL, NULL, NULL, 1, 1, 2, 0, NULL, 1, 1, NULL, NULL, NULL, 1, 1, NULL, NULL, NULL, NULL, NULL, 17.0000, 25.3000, NULL, NULL, 17.0000, 25.3000, 2.0000, NULL, {$orderNumber}, '1', 'USD', '{$email}', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'USD', NULL, NULL, 'USD', NULL, NULL, NULL, NULL, NULL, '127.0.0.1', 'flatrate_flatrate', 'USD', '{$productStoreName($entityId)}', NULL, NULL, '{$time}', '{$time}', 2, NULL, 0.0000, 0.0000, 0.0000, NULL, NULL, NULL, NULL, NULL, 10.0000, 10.0000, NULL, NULL);";
+
+            $salesOrderAddressId[0] = $quoteAddressId[0];
+            $salesOrderAddressId[1] = $quoteAddressId[1];
+            $queries .= "INSERT INTO `{$salesOrderAddressTableName}` (`entity_id`, `parent_id`, `customer_address_id`, `quote_address_id`, `region_id`, `customer_id`, `fax`, `region`, `postcode`, `lastname`, `street`, `city`, `email`, `telephone`, `country_id`, `firstname`, `address_type`, `prefix`, `middlename`, `suffix`, `company`, `vat_id`, `vat_is_valid`, `vat_request_id`, `vat_request_date`, `vat_request_success`) VALUES ({$salesOrderAddressId[0]}, {$salesOrderId}, NULL, NULL, 1, NULL, NULL, '{$state}', '{$zip}', '{$lastName}', '{$address}', '{$city}', '{$email}', '{$phone}', '{$country}', '{$firstName}', 'shipping', NULL, NULL, NULL, '{$company}', NULL, NULL, NULL, NULL, NULL);";
+            $queries .= "INSERT INTO `{$salesOrderAddressTableName}` (`entity_id`, `parent_id`, `customer_address_id`, `quote_address_id`, `region_id`, `customer_id`, `fax`, `region`, `postcode`, `lastname`, `street`, `city`, `email`, `telephone`, `country_id`, `firstname`, `address_type`, `prefix`, `middlename`, `suffix`, `company`, `vat_id`, `vat_is_valid`, `vat_request_id`, `vat_request_date`, `vat_request_success`) VALUES ({$salesOrderAddressId[1]}, {$salesOrderId}, NULL, NULL, 1, NULL, NULL, '{$state}', '{$zip}', '{$lastName}', '{$address}', '{$city}', '{$email}', '{$phone}', '{$country}', '{$firstName}', 'billing', NULL, NULL, NULL, '{$company}', NULL, NULL, NULL, NULL, NULL);";
+
+            $salesOrderGridId = $salesOrderId;
+            $queries .= "INSERT INTO `{$salesOrderGridTableName}` (`entity_id`, `status`, `store_id`, `store_name`, `customer_id`, `base_grand_total`, `base_total_paid`, `grand_total`, `total_paid`, `increment_id`, `base_currency_code`, `order_currency_code`, `shipping_name`, `billing_name`, `created_at`, `updated_at`) VALUES ({$salesOrderGridId}, 'pending', {$productStoreId($entityId)}, '{$productStoreName($entityId)}', NULL, 25.3000, NULL, 25.3000, NULL, {$orderNumber}, 'USD', 'USD', '', '', '{$time}', NULL);";
+
+            $salesOrderItemId[0] = $quoteItemId[0];
+            $salesOrderItemId[1] = $quoteItemId[1];
+            $salesOrderItemId[2] = $quoteItemId[2];
+            $salesOrderItemId[3] = $quoteItemId[3];
+            $queries .= "INSERT INTO `{$salesOrderItemTableName}` (`item_id`, `order_id`, `parent_item_id`, `quote_item_id`, `store_id`, `created_at`, `updated_at`, `product_id`, `product_type`, `product_options`, `weight`, `is_virtual`, `sku`, `name`, `description`, `applied_rule_ids`, `additional_data`, `is_qty_decimal`, `no_discount`, `qty_backordered`, `qty_canceled`, `qty_invoiced`, `qty_ordered`, `qty_refunded`, `qty_shipped`, `base_cost`, `price`, `base_price`, `original_price`, `base_original_price`, `tax_percent`, `tax_amount`, `base_tax_amount`, `tax_invoiced`, `base_tax_invoiced`, `discount_percent`, `discount_amount`, `base_discount_amount`, `discount_invoiced`, `base_discount_invoiced`, `amount_refunded`, `base_amount_refunded`, `row_total`, `base_row_total`, `row_invoiced`, `base_row_invoiced`, `row_weight`, `base_tax_before_discount`, `tax_before_discount`, `ext_order_item_id`, `locked_do_invoice`, `locked_do_ship`, `price_incl_tax`, `base_price_incl_tax`, `row_total_incl_tax`, `base_row_total_incl_tax`, `hidden_tax_amount`, `base_hidden_tax_amount`, `hidden_tax_invoiced`, `base_hidden_tax_invoiced`, `hidden_tax_refunded`, `base_hidden_tax_refunded`, `tax_canceled`, `hidden_tax_canceled`, `tax_refunded`, `base_tax_refunded`, `discount_refunded`, `base_discount_refunded`, `free_shipping`, `gift_message_id`, `gift_message_available`, `weee_tax_applied`, `weee_tax_applied_amount`, `weee_tax_applied_row_amount`, `weee_tax_disposition`, `weee_tax_row_disposition`, `base_weee_tax_applied_amount`, `base_weee_tax_applied_row_amnt`, `base_weee_tax_disposition`, `base_weee_tax_row_disposition`) VALUES ({$salesOrderItemId[0]}, {$salesOrderId}, NULL, {$quoteItemId[0]}, {$productStoreId($entityId)}, '{$time}', '0000-00-00 00:00:00', {$simpleProductId[0]($entityId)}, 'simple', 'a:1:{s:15:\"info_buyRequest\";a:3:{s:4:\"uenc\";s:44:\"aHR0cDovL21hZ2UyLmNvbS9jYXRlZ29yeS0xLmh0bWw,\";s:7:\"product\";s:{$simpleProductIdLen[0]}:\"{$simpleProductId[0]($entityId)}\";s:3:\"qty\";i:1;}}', 1.0000, 0, '{$simpleProductSku[0]($entityId)}', '{$simpleProductName[0]($entityId)}', NULL, '1', NULL, 0, 0, NULL, 0.0000, 0.0000, 1.0000, 0.0000, 0.0000, NULL, 8.5000, 8.5000, 10.0000, 10.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 10.0000, 0.8500, 0.8500, 0.0000, 0.0000, 0.0000, 0.0000, 8.5000, 8.5000, 0.0000, 0.0000, 1.0000, NULL, NULL, NULL, NULL, NULL, 8.5000, 8.5000, 8.5000, 8.5000, 0.0000, 0.0000, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);";
+            $queries .= "INSERT INTO `{$salesOrderItemTableName}` (`item_id`, `order_id`, `parent_item_id`, `quote_item_id`, `store_id`, `created_at`, `updated_at`, `product_id`, `product_type`, `product_options`, `weight`, `is_virtual`, `sku`, `name`, `description`, `applied_rule_ids`, `additional_data`, `is_qty_decimal`, `no_discount`, `qty_backordered`, `qty_canceled`, `qty_invoiced`, `qty_ordered`, `qty_refunded`, `qty_shipped`, `base_cost`, `price`, `base_price`, `original_price`, `base_original_price`, `tax_percent`, `tax_amount`, `base_tax_amount`, `tax_invoiced`, `base_tax_invoiced`, `discount_percent`, `discount_amount`, `base_discount_amount`, `discount_invoiced`, `base_discount_invoiced`, `amount_refunded`, `base_amount_refunded`, `row_total`, `base_row_total`, `row_invoiced`, `base_row_invoiced`, `row_weight`, `base_tax_before_discount`, `tax_before_discount`, `ext_order_item_id`, `locked_do_invoice`, `locked_do_ship`, `price_incl_tax`, `base_price_incl_tax`, `row_total_incl_tax`, `base_row_total_incl_tax`, `hidden_tax_amount`, `base_hidden_tax_amount`, `hidden_tax_invoiced`, `base_hidden_tax_invoiced`, `hidden_tax_refunded`, `base_hidden_tax_refunded`, `tax_canceled`, `hidden_tax_canceled`, `tax_refunded`, `base_tax_refunded`, `discount_refunded`, `base_discount_refunded`, `free_shipping`, `gift_message_id`, `gift_message_available`, `weee_tax_applied`, `weee_tax_applied_amount`, `weee_tax_applied_row_amount`, `weee_tax_disposition`, `weee_tax_row_disposition`, `base_weee_tax_applied_amount`, `base_weee_tax_applied_row_amnt`, `base_weee_tax_disposition`, `base_weee_tax_row_disposition`) VALUES ({$salesOrderItemId[1]}, {$salesOrderId}, NULL, {$quoteItemId[1]}, {$productStoreId($entityId)}, '{$time}', '0000-00-00 00:00:00', {$simpleProductId[1]($entityId)}, 'simple', 'a:1:{s:15:\"info_buyRequest\";a:3:{s:4:\"uenc\";s:44:\"aHR0cDovL21hZ2UyLmNvbS9jYXRlZ29yeS0xLmh0bWw,\";s:7:\"product\";s:{$simpleProductIdLen[1]}:\"{$simpleProductId[1]($entityId)}\";s:3:\"qty\";i:1;}}', 1.0000, 0, '{$simpleProductSku[1]($entityId)}', '{$simpleProductName[1]($entityId)}', NULL, '1', NULL, 0, 0, NULL, 0.0000, 0.0000, 1.0000, 0.0000, 0.0000, NULL, 8.5000, 8.5000, 10.0000, 10.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 10.0000, 0.8500, 0.8500, 0.0000, 0.0000, 0.0000, 0.0000, 8.5000, 8.5000, 0.0000, 0.0000, 1.0000, NULL, NULL, NULL, NULL, NULL, 8.5000, 8.5000, 8.5000, 8.5000, 0.0000, 0.0000, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);";
+
+            $salesOrderPaymentId = $salesOrderId;
+            $queries .= "INSERT INTO `{$salesOrderPaymentTableName}` (`entity_id`, `parent_id`, `base_shipping_captured`, `shipping_captured`, `amount_refunded`, `base_amount_paid`, `amount_canceled`, `base_amount_authorized`, `base_amount_paid_online`, `base_amount_refunded_online`, `base_shipping_amount`, `shipping_amount`, `amount_paid`, `amount_authorized`, `base_amount_ordered`, `base_shipping_refunded`, `shipping_refunded`, `base_amount_refunded`, `amount_ordered`, `base_amount_canceled`, `quote_payment_id`, `additional_data`, `cc_exp_month`, `cc_ss_start_year`, `echeck_bank_name`, `method`, `cc_debug_request_body`, `cc_secure_verify`, `protection_eligibility`, `cc_approval`, `cc_last_4`, `cc_status_description`, `echeck_type`, `cc_debug_response_serialized`, `cc_ss_start_month`, `echeck_account_type`, `last_trans_id`, `cc_cid_status`, `cc_owner`, `cc_type`, `po_number`, `cc_exp_year`, `cc_status`, `echeck_routing_number`, `account_status`, `anet_trans_method`, `cc_debug_response_body`, `cc_ss_issue`, `echeck_account_name`, `cc_avs_status`, `cc_number_enc`, `cc_trans_id`, `address_status`, `additional_information`) VALUES ({$salesOrderPaymentId}, {$salesOrderId}, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 10.0000, 10.0000, NULL, NULL, 25.3000, NULL, NULL, NULL, 25.3000, NULL, NULL, NULL, NULL, '0', NULL, 'checkmo', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '0', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'a:1:{s:53:\"a:1:{s:12:\"method_title\";s:19:\"Check / Money order\";}\";N;}');";
+
+            $salesOrderStatusHistoryId = $salesOrderId;
+            $queries .= "INSERT INTO `{$salesOrderStatusHistoryTableName}` (`entity_id`, `parent_id`, `is_customer_notified`, `is_visible_on_front`, `comment`, `status`, `created_at`, `entity_name`) VALUES ({$salesOrderStatusHistoryId}, {$salesOrderId}, 1, 0, NULL, 'pending', '{$time}', 'order');";
+
+            $writeAdapter->multiQuery($queries);
+
+            $entityId++;
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getActionTitle()
+    {
+        return 'Generating orders';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function introduceParamLabels()
+    {
+        return [
+            'orders'     => 'Orders'
+        ];
+    }
+
+    /**
+     * Get real table name for db table, validated by db adapter
+     *
+     * @param string $tableName
+     * @param string $resourceName
+     * @return string
+     */
+    public function getTableName($tableName, $resourceName)
+    {
+        $resource = $this->application->getObjectManager()->get($resourceName);
+        return $this->getConnection('write')->getTableName($resource->getTable($tableName));
+    }
+
+    /**
+     * Retrieve connection to resource specified by $resourceName
+     *
+     * @param string $resourceName
+     * @return \Magento\Framework\DB\Adapter\AdapterInterface|false
+     */
+    public function getConnection($resourceName)
+    {
+        return $this->application->getObjectManager()->get(
+            'Magento\Framework\App\Resource'
+        )->getConnection($resourceName);
+    }
+}
+
+return new OrdersFixture($this);
diff --git a/lib/internal/Magento/Framework/Api/Code/Generator/ExtensionAttributesGenerator.php b/lib/internal/Magento/Framework/Api/Code/Generator/ExtensionAttributesGenerator.php
index 98f5dc5d5e07250fe7b427ca68286cb99c22ee35..aa91250b41fb3ce83f95c8d3df94e144c79a9bfb 100644
--- a/lib/internal/Magento/Framework/Api/Code/Generator/ExtensionAttributesGenerator.php
+++ b/lib/internal/Magento/Framework/Api/Code/Generator/ExtensionAttributesGenerator.php
@@ -8,6 +8,7 @@ namespace Magento\Framework\Api\Code\Generator;
 use Magento\Framework\Code\Generator\DefinedClasses;
 use Magento\Framework\Code\Generator\Io;
 use Magento\Framework\Api\SimpleDataObjectConverter;
+use Magento\Framework\Api\Config\Converter;
 
 /**
  * Code generator for data object extensions.
@@ -79,14 +80,15 @@ class ExtensionAttributesGenerator extends \Magento\Framework\Code\Generator\Ent
     protected function _getClassMethods()
     {
         $methods = [];
-        foreach ($this->getCustomAttributes() as $attributeName => $attributeType) {
+        foreach ($this->getCustomAttributes() as $attributeName => $attributeMetadata) {
+            $attributeType = $attributeMetadata[Converter::DATA_TYPE];
             $propertyName = SimpleDataObjectConverter::snakeCaseToCamelCase($attributeName);
             $getterName = 'get' . ucfirst($propertyName);
             $setterName = 'set' . ucfirst($propertyName);
             $methods[] = [
                 'name' => $getterName,
                 'body' => "return \$this->_get('{$attributeName}');",
-                'docblock' => ['tags' => [['name' => 'return', 'description' => $attributeType]]],
+                'docblock' => ['tags' => [['name' => 'return', 'description' => $attributeType . '|null']]],
             ];
             $methods[] = [
                 'name' => $setterName,
@@ -150,11 +152,12 @@ class ExtensionAttributesGenerator extends \Magento\Framework\Code\Generator\Ent
         }
         $dataInterface = ltrim($this->getSourceClassName(), '\\');
         if (isset($this->allCustomAttributes[$dataInterface])) {
-            foreach ($this->allCustomAttributes[$dataInterface] as $attributeName => $attributeType) {
+            foreach ($this->allCustomAttributes[$dataInterface] as $attributeName => $attributeMetadata) {
+                $attributeType = $attributeMetadata[Converter::DATA_TYPE];
                 if (strpos($attributeType, '\\') !== false) {
                     /** Add preceding slash to class names, while leaving primitive types as is */
                     $attributeType = $this->_getFullyQualifiedClassName($attributeType);
-                    $this->allCustomAttributes[$dataInterface][$attributeName] =
+                    $this->allCustomAttributes[$dataInterface][$attributeName][Converter::DATA_TYPE] =
                         $this->_getFullyQualifiedClassName($attributeType);
                 }
             }
diff --git a/lib/internal/Magento/Framework/Api/Config/Converter.php b/lib/internal/Magento/Framework/Api/Config/Converter.php
index f21db3bbd9b224b1c29eaa36be3f6043dcdf4ae9..68914a98b5c77ab1bc452c90fc26dfbee64797d8 100644
--- a/lib/internal/Magento/Framework/Api/Config/Converter.php
+++ b/lib/internal/Magento/Framework/Api/Config/Converter.php
@@ -7,6 +7,9 @@ namespace Magento\Framework\Api\Config;
 
 class Converter implements \Magento\Framework\Config\ConverterInterface
 {
+    const RESOURCE_PERMISSIONS = "resourceRefs";
+    const DATA_TYPE = "type";
+
     /**
      * Convert dom node tree to array
      *
@@ -21,7 +24,7 @@ class Converter implements \Magento\Framework\Config\ConverterInterface
         }
 
         /** @var \DOMNodeList $types */
-        $types = $source->getElementsByTagName('custom_attributes');
+        $types = $source->getElementsByTagName('extension_attributes');
         /** @var \DOMNode $type */
         foreach ($types as $type) {
             $typeConfig = [];
@@ -32,9 +35,22 @@ class Converter implements \Magento\Framework\Config\ConverterInterface
                 $code = $attribute->getAttribute('code');
                 $codeType = $attribute->getAttribute('type');
 
-                if ($code && $codeType) {
-                    $typeConfig[$code] = $codeType;
+                $resourcesElement = $attribute->getElementsByTagName('resources')->item(0);
+                $resourceRefs = [];
+                if ($resourcesElement && $resourcesElement->nodeType === XML_ELEMENT_NODE) {
+                    $singleResourceElements = $resourcesElement->getElementsByTagName('resource');
+                    foreach ($singleResourceElements as $element) {
+                        if ($element->nodeType != XML_ELEMENT_NODE) {
+                            continue;
+                        }
+                        $resourceRefs[] = $element->attributes->getNamedItem('ref')->nodeValue;
+                    }
                 }
+
+                $typeConfig[$code] = [
+                    self::DATA_TYPE => $codeType,
+                    self::RESOURCE_PERMISSIONS => $resourceRefs,
+                ];
             }
 
             $output[$typeName] = $typeConfig;
diff --git a/lib/internal/Magento/Framework/Api/Config/Reader.php b/lib/internal/Magento/Framework/Api/Config/Reader.php
index 8cd1a8ac3293568553c30f0e126ab1ee61b78a38..6bc97c71c11563cfb46efeaaedf2ecd03fd3bf83 100644
--- a/lib/internal/Magento/Framework/Api/Config/Reader.php
+++ b/lib/internal/Magento/Framework/Api/Config/Reader.php
@@ -13,8 +13,8 @@ class Reader extends \Magento\Framework\Config\Reader\Filesystem
      * @var array
      */
     protected $_idAttributes = [
-        '/config/custom_attributes' => 'for',
-        '/config/custom_attributes/attribute' => 'code',
+        '/config/extension_attributes' => 'for',
+        '/config/extension_attributes/attribute' => 'code',
     ];
 
     /**
@@ -32,7 +32,7 @@ class Reader extends \Magento\Framework\Config\Reader\Filesystem
         \Magento\Framework\Api\Config\Converter $converter,
         \Magento\Framework\Api\Config\SchemaLocator $schemaLocator,
         \Magento\Framework\Config\ValidationStateInterface $validationState,
-        $fileName = 'data_object.xml',
+        $fileName = 'service_data_attributes.xml',
         $idAttributes = [],
         $domDocumentClass = 'Magento\Framework\Config\Dom',
         $defaultScope = 'global'
diff --git a/lib/internal/Magento/Framework/Api/Config/SchemaLocator.php b/lib/internal/Magento/Framework/Api/Config/SchemaLocator.php
index 86662ab2528136ecc4c8182d650a55b9e80f0a2f..1e8334c643def347b9392eba52d624b5fdaab556 100644
--- a/lib/internal/Magento/Framework/Api/Config/SchemaLocator.php
+++ b/lib/internal/Magento/Framework/Api/Config/SchemaLocator.php
@@ -16,7 +16,7 @@ class SchemaLocator implements \Magento\Framework\Config\SchemaLocatorInterface
      */
     public function getSchema()
     {
-        return realpath(__DIR__ . '/../etc/data_object.xsd');
+        return realpath(__DIR__ . '/../etc/service_data_attributes.xsd');
     }
 
     /**
diff --git a/lib/internal/Magento/Framework/Api/DataObjectHelper.php b/lib/internal/Magento/Framework/Api/DataObjectHelper.php
index d0a22a194be444bbc4b71f5d60dd6bf29fd1de42..fc3a3b0920c60430f28de95db7cd6a6ab84f6868 100644
--- a/lib/internal/Magento/Framework/Api/DataObjectHelper.php
+++ b/lib/internal/Magento/Framework/Api/DataObjectHelper.php
@@ -6,6 +6,8 @@
 
 namespace Magento\Framework\Api;
 
+use Magento\Framework\Reflection\MethodsMap;
+
 class DataObjectHelper
 {
     /**
@@ -28,22 +30,30 @@ class DataObjectHelper
      */
     protected $extensionFactory;
 
+    /**
+     * @var MethodsMap
+     */
+    protected $methodsMapProcessor;
+
     /**
      * @param ObjectFactory $objectFactory
      * @param \Magento\Framework\Reflection\DataObjectProcessor $objectProcessor
      * @param \Magento\Framework\Reflection\TypeProcessor $typeProcessor
      * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
+     * @param MethodsMap $methodsMapProcessor
      */
     public function __construct(
         ObjectFactory $objectFactory,
         \Magento\Framework\Reflection\DataObjectProcessor $objectProcessor,
         \Magento\Framework\Reflection\TypeProcessor $typeProcessor,
-        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
+        MethodsMap $methodsMapProcessor
     ) {
         $this->objectFactory = $objectFactory;
         $this->objectProcessor = $objectProcessor;
         $this->typeProcessor = $typeProcessor;
         $this->extensionFactory = $extensionFactory;
+        $this->methodsMapProcessor = $methodsMapProcessor;
     }
 
     /**
@@ -128,7 +138,7 @@ class DataObjectHelper
         if ($interfaceName == null) {
             $interfaceName = get_class($dataObject);
         }
-        $returnType = $this->objectProcessor->getMethodReturnType($interfaceName, $getterMethodName);
+        $returnType = $this->methodsMapProcessor->getMethodReturnType($interfaceName, $getterMethodName);
         if ($this->typeProcessor->isTypeSimple($returnType)) {
             $dataObject->$methodName($value);
             return $this;
diff --git a/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/ExtensionAttributesGeneratorTest.php b/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/ExtensionAttributesGeneratorTest.php
index 5207a20588c73dcbf83aa767b907f585db8bb114..efdeb4ae914348fa51302891271d018b06c70067 100644
--- a/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/ExtensionAttributesGeneratorTest.php
+++ b/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/ExtensionAttributesGeneratorTest.php
@@ -6,6 +6,8 @@
 // @codingStandardsIgnoreFile
 namespace Magento\Framework\Api\Test\Unit\Code\Generator;
 
+use Magento\Framework\Api\Config\Converter;
+
 class ExtensionAttributesGeneratorTest extends \PHPUnit_Framework_TestCase
 {
     /**
@@ -44,11 +46,21 @@ class ExtensionAttributesGeneratorTest extends \PHPUnit_Framework_TestCase
             ->willReturn(
                 [
                     'Magento\Catalog\Api\Data\ProductInterface' => [
-                        'string_attribute' => 'string',
-                        'complex_object_attribute' => '\Magento\Bundle\Api\Data\OptionInterface[]'
+                        'string_attribute' => [
+                            Converter::DATA_TYPE => 'string',
+                            Converter::RESOURCE_PERMISSIONS => [],
+
+                        ],
+                        'complex_object_attribute' => [
+                            Converter::DATA_TYPE => '\Magento\Bundle\Api\Data\OptionInterface[]',
+                            Converter::RESOURCE_PERMISSIONS => [],
+                        ],
                     ],
                     'Magento\Catalog\Api\Data\Product' => [
-                        'should_not_include' => 'string',
+                        'should_not_include' => [
+                            Converter::DATA_TYPE => 'string',
+                            Converter::RESOURCE_PERMISSIONS => [],
+                        ],
                     ],
                 ]
             );
diff --git a/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/ExtensionAttributesInterfaceGeneratorTest.php b/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/ExtensionAttributesInterfaceGeneratorTest.php
index 8f80baf39beeeec1955800e7ea4a51ac12d02382..33d4ecf9e7906c2abd4bfe15ef429c539405b059 100644
--- a/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/ExtensionAttributesInterfaceGeneratorTest.php
+++ b/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/ExtensionAttributesInterfaceGeneratorTest.php
@@ -6,6 +6,8 @@
 // @codingStandardsIgnoreFile
 namespace Magento\Framework\Api\Test\Unit\Code\Generator;
 
+use Magento\Framework\Api\Config\Converter;
+
 class ExtensionAttributesInterfaceGeneratorTest extends \PHPUnit_Framework_TestCase
 {
     public function testGenerate()
@@ -19,11 +21,20 @@ class ExtensionAttributesInterfaceGeneratorTest extends \PHPUnit_Framework_TestC
             ->willReturn(
                 [
                     'Magento\Catalog\Api\Data\ProductInterface' => [
-                        'string_attribute' => 'string',
-                        'complex_object_attribute' => '\Magento\Bundle\Api\Data\OptionInterface[]'
+                        'string_attribute' => [
+                            Converter::DATA_TYPE => 'string',
+                            Converter::RESOURCE_PERMISSIONS => [],
+                        ],
+                        'complex_object_attribute' => [
+                            Converter::DATA_TYPE => '\Magento\Bundle\Api\Data\OptionInterface[]',
+                            Converter::RESOURCE_PERMISSIONS => [],
+                        ],
                     ],
                     'Magento\Catalog\Api\Data\Product' => [
-                        'should_not_include' => 'string',
+                        'should_not_include' => [
+                            Converter::DATA_TYPE => 'string',
+                            Converter::RESOURCE_PERMISSIONS => [],
+                        ],
                     ],
                 ]
             );
diff --git a/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/_files/SampleExtension.txt b/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/_files/SampleExtension.txt
index 8b5caad1ecc4456ae51380e25c735be8f2660d37..0f9838bd8736c9c0545b6bb82ab5adbe9762a946 100644
--- a/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/_files/SampleExtension.txt
+++ b/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/_files/SampleExtension.txt
@@ -6,7 +6,7 @@ namespace Magento\Catalog\Api\Data;
 class ProductExtension extends \Magento\Framework\Api\AbstractSimpleObject implements \Magento\Catalog\Api\Data\ProductExtensionInterface
 {
     /**
-     * @return string
+     * @return string|null
      */
     public function getStringAttribute()
     {
@@ -24,7 +24,7 @@ class ProductExtension extends \Magento\Framework\Api\AbstractSimpleObject imple
     }
 
     /**
-     * @return \Magento\Bundle\Api\Data\OptionInterface[]
+     * @return \Magento\Bundle\Api\Data\OptionInterface[]|null
      */
     public function getComplexObjectAttribute()
     {
diff --git a/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/_files/SampleExtensionInterface.txt b/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/_files/SampleExtensionInterface.txt
index ec9edd7affc2d68e5444d914b833bff81ccc1d4d..75dde39b2151952b49beb587ce4eecff56418997 100644
--- a/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/_files/SampleExtensionInterface.txt
+++ b/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/_files/SampleExtensionInterface.txt
@@ -6,7 +6,7 @@ namespace Magento\Catalog\Api\Data;
 interface ProductExtensionInterface extends \Magento\Framework\Api\ExtensionAttributesInterface
 {
     /**
-     * @return string
+     * @return string|null
      */
     public function getStringAttribute();
 
@@ -17,7 +17,7 @@ interface ProductExtensionInterface extends \Magento\Framework\Api\ExtensionAttr
     public function setStringAttribute($stringAttribute);
 
     /**
-     * @return \Magento\Bundle\Api\Data\OptionInterface[]
+     * @return \Magento\Bundle\Api\Data\OptionInterface[]|null
      */
     public function getComplexObjectAttribute();
 
diff --git a/lib/internal/Magento/Framework/Api/Test/Unit/Config/ConverterTest.php b/lib/internal/Magento/Framework/Api/Test/Unit/Config/ConverterTest.php
index 94f5a4494a75dd9c57afa409c90eb622ad26827c..d4629213b20be2d7bbca2ff16bacf0b36de608e5 100644
--- a/lib/internal/Magento/Framework/Api/Test/Unit/Config/ConverterTest.php
+++ b/lib/internal/Magento/Framework/Api/Test/Unit/Config/ConverterTest.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\Framework\Api\Test\Unit\Config;
 
+use Magento\Framework\Api\Config\Converter;
+
 class ConverterTest extends \PHPUnit_Framework_TestCase
 {
     /**
@@ -47,15 +49,39 @@ class ConverterTest extends \PHPUnit_Framework_TestCase
             'Magento\Tax\Api\Data\TaxRateInterface' => [
             ],
             'Magento\Catalog\Api\Data\ProductInterface' => [
-                'stock_item' => 'Magento\CatalogInventory\Api\Data\StockItemInterface'
+                'stock_item' => [
+                    Converter::DATA_TYPE => 'Magento\CatalogInventory\Api\Data\StockItemInterface',
+                    Converter::RESOURCE_PERMISSIONS => [],
+                ],
             ],
             'Magento\Customer\Api\Data\CustomerInterface' => [
-                'custom_1' => 'Magento\Customer\Api\Data\CustomerCustom',
-                'custom_2' => 'Magento\CustomerExtra\Api\Data\CustomerCustom2'
+                'custom_1' => [
+                    Converter::DATA_TYPE => 'Magento\Customer\Api\Data\CustomerCustom',
+                    Converter::RESOURCE_PERMISSIONS => [],
+                ],
+                'custom_2' => [
+                    Converter::DATA_TYPE => 'Magento\CustomerExtra\Api\Data\CustomerCustom2',
+                    Converter::RESOURCE_PERMISSIONS => [],
+                ],
+            ],
+            'Magento\Customer\Api\Data\CustomerInterface2' => [
+                'custom_with_permission' => [
+                    Converter::DATA_TYPE => 'Magento\Customer\Api\Data\CustomerCustom',
+                    Converter::RESOURCE_PERMISSIONS => [
+                        'Magento_Customer::manage',
+                    ],
+                ],
+                'custom_with_multiple_permissions' => [
+                    Converter::DATA_TYPE => 'Magento\CustomerExtra\Api\Data\CustomerCustom2',
+                    Converter::RESOURCE_PERMISSIONS => [
+                        'Magento_Customer::manage',
+                        'Magento_Customer::manage2',
+                    ],
+                ],
             ],
         ];
 
-        $xmlFile = __DIR__ . '/_files/data_object_valid.xml';
+        $xmlFile = __DIR__ . '/_files/service_data_attributes.xml';
         $dom = new \DOMDocument();
         $dom->loadXML(file_get_contents($xmlFile));
         $result = $this->_converter->convert($dom);
diff --git a/lib/internal/Magento/Framework/Api/Test/Unit/Config/SchemaLocatorTest.php b/lib/internal/Magento/Framework/Api/Test/Unit/Config/SchemaLocatorTest.php
index f0df38d59a070958d77d6ddccb0d339162d256da..f05583db0490194e949261bce0a2c176932dbdb5 100644
--- a/lib/internal/Magento/Framework/Api/Test/Unit/Config/SchemaLocatorTest.php
+++ b/lib/internal/Magento/Framework/Api/Test/Unit/Config/SchemaLocatorTest.php
@@ -22,7 +22,7 @@ class SchemaLocatorTest extends \PHPUnit_Framework_TestCase
 
     public function testGetSchema()
     {
-        $expected = str_replace('\\', '/', BP . '/lib/internal/Magento/Framework/Api/etc/data_object.xsd');
+        $expected = str_replace('\\', '/', BP . '/lib/internal/Magento/Framework/Api/etc/service_data_attributes.xsd');
         $actual = str_replace('\\', '/', $this->_model->getSchema());
         $this->assertEquals($expected, $actual);
     }
@@ -30,7 +30,7 @@ class SchemaLocatorTest extends \PHPUnit_Framework_TestCase
     public function testGetPerFileSchema()
     {
         $actual = str_replace('\\', '/', $this->_model->getPerFileSchema());
-        $expected = str_replace('\\', '/', BP . '/lib/internal/Magento/Framework/Api/etc/data_object.xsd');
+        $expected = str_replace('\\', '/', BP . '/lib/internal/Magento/Framework/Api/etc/service_data_attributes.xsd');
         $this->assertEquals($expected, $actual);
     }
 }
diff --git a/lib/internal/Magento/Framework/Api/Test/Unit/Config/_files/data_object_valid.xml b/lib/internal/Magento/Framework/Api/Test/Unit/Config/_files/data_object_valid.xml
deleted file mode 100644
index 67606deab2eb46e78dc3022a723b41a1bb25bfa3..0000000000000000000000000000000000000000
--- a/lib/internal/Magento/Framework/Api/Test/Unit/Config/_files/data_object_valid.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0"?>
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../lib/internal/Magento/Framework/Api/etc/data_object.xsd">
-    <custom_attributes for="Magento\Tax\Api\Data\TaxRateInterface">
-    </custom_attributes>
-    <custom_attributes for="Magento\Catalog\Api\Data\ProductInterface">
-        <attribute code="stock_item" type="Magento\CatalogInventory\Api\Data\StockItemInterface" />
-    </custom_attributes>
-    <custom_attributes for="Magento\Customer\Api\Data\CustomerInterface">
-        <attribute code="custom_1" type="Magento\Customer\Api\Data\CustomerCustom" />
-        <attribute code="custom_2" type="Magento\CustomerExtra\Api\Data\CustomerCustom2" />
-    </custom_attributes>
-</config>
diff --git a/lib/internal/Magento/Framework/Api/Test/Unit/Config/_files/service_data_attributes.xml b/lib/internal/Magento/Framework/Api/Test/Unit/Config/_files/service_data_attributes.xml
new file mode 100644
index 0000000000000000000000000000000000000000..4f6a9838bfcdb6bd9dbfa20b18ffcfde80bd625d
--- /dev/null
+++ b/lib/internal/Magento/Framework/Api/Test/Unit/Config/_files/service_data_attributes.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../lib/internal/Magento/Framework/Api/etc/service_data_attributes.xsd">
+    <extension_attributes for="Magento\Tax\Api\Data\TaxRateInterface">
+    </extension_attributes>
+    <extension_attributes for="Magento\Catalog\Api\Data\ProductInterface">
+        <attribute code="stock_item" type="Magento\CatalogInventory\Api\Data\StockItemInterface" />
+    </extension_attributes>
+    <extension_attributes for="Magento\Customer\Api\Data\CustomerInterface">
+        <attribute code="custom_1" type="Magento\Customer\Api\Data\CustomerCustom" />
+        <attribute code="custom_2" type="Magento\CustomerExtra\Api\Data\CustomerCustom2" />
+    </extension_attributes>
+    <extension_attributes for="Magento\Customer\Api\Data\CustomerInterface2">
+        <attribute code="custom_with_permission" type="Magento\Customer\Api\Data\CustomerCustom">
+            <resources>
+                <resource ref="Magento_Customer::manage"/>
+            </resources>
+        </attribute>
+        <attribute code="custom_with_multiple_permissions" type="Magento\CustomerExtra\Api\Data\CustomerCustom2">
+            <resources>
+                <resource ref="Magento_Customer::manage"/>
+                <resource ref="Magento_Customer::manage2"/>
+            </resources>
+        </attribute>
+    </extension_attributes>
+</config>
diff --git a/lib/internal/Magento/Framework/Api/Test/Unit/DataObjectHelperTest.php b/lib/internal/Magento/Framework/Api/Test/Unit/DataObjectHelperTest.php
index ff229abd7d22e9be0f810da4034336e5e9631f63..65c7cb906d1f2f15b8f251145633cdb6e85848c5 100644
--- a/lib/internal/Magento/Framework/Api/Test/Unit/DataObjectHelperTest.php
+++ b/lib/internal/Magento/Framework/Api/Test/Unit/DataObjectHelperTest.php
@@ -43,6 +43,11 @@ class DataObjectHelperTest extends \PHPUnit_Framework_TestCase
      */
     protected $attributeValueFactoryMock;
 
+    /**
+     * @var \Magento\Framework\Reflection\MethodsMap|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $methodsMapProcessor;
+
     public function setUp()
     {
         $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
@@ -53,6 +58,9 @@ class DataObjectHelperTest extends \PHPUnit_Framework_TestCase
         $this->objectProcessorMock = $this->getMockBuilder('\Magento\Framework\Reflection\DataObjectProcessor')
             ->disableOriginalConstructor()
             ->getMock();
+        $this->methodsMapProcessor = $this->getMockBuilder('\Magento\Framework\Reflection\MethodsMap')
+            ->disableOriginalConstructor()
+            ->getMock();
         $this->attributeValueFactoryMock = $this->getMockBuilder('\Magento\Framework\Api\AttributeValueFactory')
             ->disableOriginalConstructor()
             ->getMock();
@@ -63,6 +71,7 @@ class DataObjectHelperTest extends \PHPUnit_Framework_TestCase
                 'objectFactory' => $this->objectFactoryMock,
                 'typeProcessor' => $this->typeProcessor,
                 'objectProcessor' => $this->objectProcessorMock,
+                'methodsMapProcessor' => $this->methodsMapProcessor,
             ]
         );
     }
@@ -103,11 +112,11 @@ class DataObjectHelperTest extends \PHPUnit_Framework_TestCase
             ],
         ];
 
-        $this->objectProcessorMock->expects($this->at(0))
+        $this->methodsMapProcessor->expects($this->at(0))
             ->method('getMethodReturnType')
             ->with('\Magento\Customer\Api\Data\AddressInterface', 'getStreet')
             ->willReturn('string[]');
-        $this->objectProcessorMock->expects($this->at(1))
+        $this->methodsMapProcessor->expects($this->at(1))
             ->method('getMethodReturnType')
             ->with('\Magento\Customer\Api\Data\AddressInterface', 'getRegion')
             ->willReturn('\Magento\Customer\Api\Data\RegionInterface');
@@ -317,11 +326,11 @@ class DataObjectHelperTest extends \PHPUnit_Framework_TestCase
             ->method('buildOutputDataArray')
             ->with($secondAddressDataObject, get_class($firstAddressDataObject))
             ->willReturn($data2);
-        $this->objectProcessorMock->expects($this->at(1))
+        $this->methodsMapProcessor->expects($this->at(0))
             ->method('getMethodReturnType')
             ->with('Magento\Customer\Model\Data\Address', 'getStreet')
             ->willReturn('string[]');
-        $this->objectProcessorMock->expects($this->at(2))
+        $this->methodsMapProcessor->expects($this->at(1))
             ->method('getMethodReturnType')
             ->with('Magento\Customer\Model\Data\Address', 'getRegion')
             ->willReturn('\Magento\Customer\Api\Data\RegionInterface');
diff --git a/lib/internal/Magento/Framework/Api/etc/data_object.xsd b/lib/internal/Magento/Framework/Api/etc/data_object.xsd
deleted file mode 100644
index 0983dbbf912385c5a83dd1b8db18d768071c42fc..0000000000000000000000000000000000000000
--- a/lib/internal/Magento/Framework/Api/etc/data_object.xsd
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
-  <xs:element name="config">
-      <xs:complexType>
-          <xs:sequence>
-              <xs:element name="custom_attributes" type="custom_attributesType" minOccurs="1" maxOccurs="unbounded">
-                  <xs:annotation>
-                      <xs:documentation>Main schema element. Extended Attributes</xs:documentation>
-                  </xs:annotation>
-              </xs:element>
-          </xs:sequence>
-      </xs:complexType>
-  </xs:element>
-  <xs:complexType name="attributeType">
-    <xs:simpleContent>
-      <xs:extension base="xs:string">
-        <xs:attribute type="xs:string" name="code" use="required"/>
-        <xs:attribute type="xs:string" name="type" use="required"/>
-      </xs:extension>
-    </xs:simpleContent>
-  </xs:complexType>
-  <xs:complexType name="custom_attributesType">
-    <xs:sequence>
-      <xs:element type="attributeType" name="attribute" minOccurs="0" maxOccurs="unbounded"/>
-    </xs:sequence>
-    <xs:attribute type="xs:string" name="for" use="required"/>
-  </xs:complexType>
-</xs:schema>
diff --git a/lib/internal/Magento/Framework/Api/etc/service_data_attributes.xsd b/lib/internal/Magento/Framework/Api/etc/service_data_attributes.xsd
new file mode 100644
index 0000000000000000000000000000000000000000..24590e3d758c79afeef7ce85c8cb9f6547e6f524
--- /dev/null
+++ b/lib/internal/Magento/Framework/Api/etc/service_data_attributes.xsd
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified"
+           xmlns:xs="http://www.w3.org/2001/XMLSchema">
+    <xs:element name="config">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element name="extension_attributes" type="extension_attributesType" minOccurs="1"
+                            maxOccurs="unbounded">
+                    <xs:annotation>
+                        <xs:documentation>Main schema element. Extended Attributes</xs:documentation>
+                    </xs:annotation>
+                </xs:element>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+    <xs:complexType name="attributeType">
+        <xs:sequence>
+            <xs:element name="resources" type="resourcesType" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:sequence>
+        <xs:attribute type="xs:string" name="code" use="required"/>
+        <xs:attribute type="xs:string" name="type" use="required"/>
+    </xs:complexType>
+    <xs:complexType name="extension_attributesType">
+        <xs:sequence>
+            <xs:element type="attributeType" name="attribute" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:sequence>
+        <xs:attribute type="xs:string" name="for" use="required"/>
+    </xs:complexType>
+    <xs:complexType name="resourcesType">
+        <xs:sequence>
+            <xs:element name="resource" type="resourceType" maxOccurs="unbounded"/>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:complexType name="resourceType">
+        <xs:attribute name="ref" use="required">
+            <xs:simpleType>
+                <xs:restriction base="xs:string">
+                    <xs:pattern value=".+(, ?.+)*"/>
+                </xs:restriction>
+            </xs:simpleType>
+        </xs:attribute>
+    </xs:complexType>
+</xs:schema>
diff --git a/lib/internal/Magento/Framework/App/Action/AbstractAction.php b/lib/internal/Magento/Framework/App/Action/AbstractAction.php
index b0027ca824ec085480664fcbfe0ce6d36e0c60bd..d6119f9fe876b972e7a7513050c4af994d95bf53 100644
--- a/lib/internal/Magento/Framework/App/Action/AbstractAction.php
+++ b/lib/internal/Magento/Framework/App/Action/AbstractAction.php
@@ -24,6 +24,11 @@ abstract class AbstractAction implements \Magento\Framework\App\ActionInterface
      */
     protected $resultRedirectFactory;
 
+    /**
+     * @var \Magento\Framework\Controller\ResultFactory
+     */
+    protected $resultFactory;
+
     /**
      * @param \Magento\Framework\App\Action\Context $context
      */
@@ -33,6 +38,7 @@ abstract class AbstractAction implements \Magento\Framework\App\ActionInterface
         $this->_request = $context->getRequest();
         $this->_response = $context->getResponse();
         $this->resultRedirectFactory = $context->getResultRedirectFactory();
+        $this->resultFactory = $context->getResultFactory();
     }
 
     /**
diff --git a/lib/internal/Magento/Framework/App/Action/Context.php b/lib/internal/Magento/Framework/App/Action/Context.php
index 22aef5cc083c9dd8278100b6afcd6fffc6858884..a812800bc059948ac5b0cdd85eb04f7891445379 100644
--- a/lib/internal/Magento/Framework/App/Action/Context.php
+++ b/lib/internal/Magento/Framework/App/Action/Context.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\Framework\App\Action;
 
+use Magento\Framework\Controller\ResultFactory;
+
 class Context implements \Magento\Framework\ObjectManager\ContextInterface
 {
     /**
@@ -57,6 +59,11 @@ class Context implements \Magento\Framework\ObjectManager\ContextInterface
      */
     protected $resultRedirectFactory;
 
+    /**
+     * @var \Magento\Framework\Controller\ResultFactory
+     */
+    protected $resultFactory;
+
     /**
      * @param \Magento\Framework\App\RequestInterface $request
      * @param \Magento\Framework\App\ResponseInterface $response
@@ -68,6 +75,7 @@ class Context implements \Magento\Framework\ObjectManager\ContextInterface
      * @param \Magento\Framework\App\ViewInterface $view
      * @param \Magento\Framework\Message\ManagerInterface $messageManager
      * @param \Magento\Framework\Controller\Result\RedirectFactory $resultRedirectFactory
+     * @param \Magento\Framework\Controller\ResultFactory $resultFactory
      *
      * @SuppressWarnings(PHPMD.ExcessiveParameterList)
      */
@@ -81,7 +89,8 @@ class Context implements \Magento\Framework\ObjectManager\ContextInterface
         \Magento\Framework\App\ActionFlag $actionFlag,
         \Magento\Framework\App\ViewInterface $view,
         \Magento\Framework\Message\ManagerInterface $messageManager,
-        \Magento\Framework\Controller\Result\RedirectFactory $resultRedirectFactory
+        \Magento\Framework\Controller\Result\RedirectFactory $resultRedirectFactory,
+        ResultFactory $resultFactory
     ) {
         $this->_request = $request;
         $this->_response = $response;
@@ -93,6 +102,7 @@ class Context implements \Magento\Framework\ObjectManager\ContextInterface
         $this->_view = $view;
         $this->messageManager = $messageManager;
         $this->resultRedirectFactory = $resultRedirectFactory;
+        $this->resultFactory = $resultFactory;
     }
 
     /**
@@ -174,4 +184,12 @@ class Context implements \Magento\Framework\ObjectManager\ContextInterface
     {
         return $this->resultRedirectFactory;
     }
+
+    /**
+     * @return \Magento\Framework\Controller\ResultFactory
+     */
+    public function getResultFactory()
+    {
+        return $this->resultFactory;
+    }
 }
diff --git a/lib/internal/Magento/Framework/App/Area/FrontNameResolverInterface.php b/lib/internal/Magento/Framework/App/Area/FrontNameResolverInterface.php
index bbdd3787b1825ffa9c35882776a9173c03b9607a..e8a3e92263e7d9b50226911e4d445b1a663171f7 100644
--- a/lib/internal/Magento/Framework/App/Area/FrontNameResolverInterface.php
+++ b/lib/internal/Magento/Framework/App/Area/FrontNameResolverInterface.php
@@ -7,6 +7,10 @@
  */
 namespace Magento\Framework\App\Area;
 
+/**
+ * Interface FrontNameResolverInterface
+ * @api
+ */
 interface FrontNameResolverInterface
 {
     /**
diff --git a/lib/internal/Magento/Framework/App/AreaInterface.php b/lib/internal/Magento/Framework/App/AreaInterface.php
index 806a7983424599690e3b7f02443fb7e9b4b328a5..544ac56e19e6f10dd13c5a284d56dba2d6e4b010 100644
--- a/lib/internal/Magento/Framework/App/AreaInterface.php
+++ b/lib/internal/Magento/Framework/App/AreaInterface.php
@@ -6,6 +6,9 @@
  */
 namespace Magento\Framework\App;
 
+/**
+ * Interface AreaInterface
+ */
 interface AreaInterface
 {
     const PART_CONFIG = 'config';
diff --git a/lib/internal/Magento/Framework/App/AreaList.php b/lib/internal/Magento/Framework/App/AreaList.php
index 270fb22e36675b08576b06500e7cd6da38f39466..c010388797d870fa25e7aec9a192edef8ed0a73b 100644
--- a/lib/internal/Magento/Framework/App/AreaList.php
+++ b/lib/internal/Magento/Framework/App/AreaList.php
@@ -63,6 +63,7 @@ class AreaList
      *
      * @param string $frontName
      * @return null|string
+     * @api
      */
     public function getCodeByFrontName($frontName)
     {
@@ -84,6 +85,7 @@ class AreaList
      *
      * @param string $areaCode
      * @return string
+     * @api
      */
     public function getFrontName($areaCode)
     {
@@ -94,6 +96,7 @@ class AreaList
      * Retrieve area codes
      *
      * @return string[]
+     * @api
      */
     public function getCodes()
     {
@@ -105,6 +108,7 @@ class AreaList
      *
      * @param string $areaCode
      * @return string
+     * @api
      */
     public function getDefaultRouter($areaCode)
     {
diff --git a/lib/internal/Magento/Framework/App/Cache/Type/Config.php b/lib/internal/Magento/Framework/App/Cache/Type/Config.php
index ded73329969b9f7faec6409ed73715cab06390eb..506eff32a8e099edc9a4a9193b7e42bafdc2ac58 100644
--- a/lib/internal/Magento/Framework/App/Cache/Type/Config.php
+++ b/lib/internal/Magento/Framework/App/Cache/Type/Config.php
@@ -25,10 +25,40 @@ class Config extends TagScope implements CacheInterface
     const CACHE_TAG = 'CONFIG';
 
     /**
-     * @param FrontendPool $cacheFrontendPool
+     * @var \Magento\Framework\App\Cache\Type\FrontendPool
      */
-    public function __construct(FrontendPool $cacheFrontendPool)
+    private $cacheFrontendPool;
+
+    /**
+     * @param \Magento\Framework\App\Cache\Type\FrontendPool $cacheFrontendPool
+     */
+    public function __construct(\Magento\Framework\App\Cache\Type\FrontendPool $cacheFrontendPool)
+    {
+        $this->cacheFrontendPool = $cacheFrontendPool;
+    }
+
+    /**
+     * Retrieve cache frontend instance being decorated
+     *
+     * @return \Magento\Framework\Cache\FrontendInterface
+     */
+    protected function _getFrontend()
+    {
+        $frontend = parent::_getFrontend();
+        if (!$frontend) {
+            $frontend = $this->cacheFrontendPool->get(self::TYPE_IDENTIFIER);
+            $this->setFrontend($frontend);
+        }
+        return $frontend;
+    }
+
+    /**
+     * Retrieve cache tag name
+     *
+     * @return string
+     */
+    public function getTag()
     {
-        parent::__construct($cacheFrontendPool->get(self::TYPE_IDENTIFIER), self::CACHE_TAG);
+        return self::CACHE_TAG;
     }
 }
diff --git a/lib/internal/Magento/Framework/App/Config.php b/lib/internal/Magento/Framework/App/Config.php
index 047849f0034bde6164c2a054c81817e2daccdd2a..898a19a00ea5f20ff98bce5a7cb5eaa322972869 100644
--- a/lib/internal/Magento/Framework/App/Config.php
+++ b/lib/internal/Magento/Framework/App/Config.php
@@ -7,6 +7,8 @@
  */
 namespace Magento\Framework\App;
 
+use Magento\Framework\App\Config\ScopeConfigInterface;
+
 class Config implements \Magento\Framework\App\Config\ScopeConfigInterface
 {
     /**
@@ -37,7 +39,7 @@ class Config implements \Magento\Framework\App\Config\ScopeConfigInterface
      */
     public function getValue(
         $path = null,
-        $scope = \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT,
+        $scope = ScopeConfigInterface::SCOPE_TYPE_DEFAULT,
         $scopeCode = null
     ) {
         return $this->_scopePool->getScope($scope, $scopeCode)->getValue($path);
@@ -51,7 +53,7 @@ class Config implements \Magento\Framework\App\Config\ScopeConfigInterface
      * @param null|string $scopeCode
      * @return bool
      */
-    public function isSetFlag($path, $scope = \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT, $scopeCode = null)
+    public function isSetFlag($path, $scope = ScopeConfigInterface::SCOPE_TYPE_DEFAULT, $scopeCode = null)
     {
         return (bool) $this->getValue($path, $scope, $scopeCode);
     }
diff --git a/lib/internal/Magento/Framework/App/Config/Data.php b/lib/internal/Magento/Framework/App/Config/Data.php
index 3b5f17fe71639559575a77bc431fccc7071388f0..38389e71e40aaf297d4983bdde8377db615d5493 100644
--- a/lib/internal/Magento/Framework/App/Config/Data.php
+++ b/lib/internal/Magento/Framework/App/Config/Data.php
@@ -42,10 +42,7 @@ class Data implements DataInterface
     }
 
     /**
-     * Retrieve configuration value by path
-     *
-     * @param null|string $path
-     * @return array|string
+     * @inheritdoc
      */
     public function getValue($path = null)
     {
@@ -65,11 +62,7 @@ class Data implements DataInterface
     }
 
     /**
-     * Set configuration value
-     *
-     * @param string $path
-     * @param mixed $value
-     * @return void
+     * @inheritdoc
      */
     public function setValue($path, $value)
     {
diff --git a/lib/internal/Magento/Framework/App/Config/Data/ProcessorFactory.php b/lib/internal/Magento/Framework/App/Config/Data/ProcessorFactory.php
index 8f473e2a37b2ba3c9cf3a0e707dd43f9bbe70902..8084dcd5d08f45c755a9c5b0490bf1fea78f8894 100644
--- a/lib/internal/Magento/Framework/App/Config/Data/ProcessorFactory.php
+++ b/lib/internal/Magento/Framework/App/Config/Data/ProcessorFactory.php
@@ -30,21 +30,22 @@ class ProcessorFactory
     /**
      * Get concrete Processor Interface instance
      *
-     * @param string $model
+     * @param string $processorModel Classname of the instance to get
      * @return ProcessorInterface
-     * @throws \InvalidArgumentException
+     * @throws \InvalidArgumentException In case the given classname is not an instance of ProcessorInterface
+     * @api
      */
-    public function get($model)
+    public function get($processorModel)
     {
-        if (!isset($this->_pool[$model])) {
-            $instance = $this->_objectManager->create($model);
+        if (!isset($this->_pool[$processorModel])) {
+            $instance = $this->_objectManager->create($processorModel);
             if (!$instance instanceof ProcessorInterface) {
                 throw new \InvalidArgumentException(
-                    $model . ' is not instance of \Magento\Framework\App\Config\Data\ProcessorInterface'
+                    $processorModel . ' is not instance of \Magento\Framework\App\Config\Data\ProcessorInterface'
                 );
             }
-            $this->_pool[$model] = $instance;
+            $this->_pool[$processorModel] = $instance;
         }
-        return $this->_pool[$model];
+        return $this->_pool[$processorModel];
     }
 }
diff --git a/lib/internal/Magento/Framework/App/Config/Data/ProcessorInterface.php b/lib/internal/Magento/Framework/App/Config/Data/ProcessorInterface.php
index 71102131f42cf4071b6d213d225ac8178956945a..d4467339676739d2e92250b986d992458772cc68 100644
--- a/lib/internal/Magento/Framework/App/Config/Data/ProcessorInterface.php
+++ b/lib/internal/Magento/Framework/App/Config/Data/ProcessorInterface.php
@@ -1,19 +1,22 @@
 <?php
 /**
- * Processor interface
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
 namespace Magento\Framework\App\Config\Data;
 
+/**
+ * Processes data from admin store configuration fields
+ *
+ * @api
+ */
 interface ProcessorInterface
 {
     /**
      * Process config value
      *
-     * @param string $value
-     * @return string
+     * @param string $value Raw value of the configuration field
+     * @return string Processed value
      */
     public function processValue($value);
 }
diff --git a/lib/internal/Magento/Framework/App/Config/DataInterface.php b/lib/internal/Magento/Framework/App/Config/DataInterface.php
index bbdaf54d1c342a11803527f92160ebacef27a0a6..b07ca0e0df1fc3ce8085227057148619c371f0f9 100644
--- a/lib/internal/Magento/Framework/App/Config/DataInterface.php
+++ b/lib/internal/Magento/Framework/App/Config/DataInterface.php
@@ -5,11 +5,27 @@
  */
 namespace Magento\Framework\App\Config;
 
+/**
+ * Configuration data storage
+ *
+ * @api
+ */
 interface DataInterface
 {
     /**
+     * Retrieve configuration value by path
+     *
      * @param string|null $path
-     * @return string|array
+     * @return mixed
      */
     public function getValue($path);
+
+    /**
+     * Set configuration value by path
+     *
+     * @param string $path
+     * @param mixed $value
+     * @return void
+     */
+    public function setValue($path, $value);
 }
diff --git a/lib/internal/Magento/Framework/App/Config/Initial.php b/lib/internal/Magento/Framework/App/Config/Initial.php
index 68db7b1eb84d42c669f3874b180038292a087983..3b2beb5ca37423ee054d94d2d3289bdacd21bca5 100644
--- a/lib/internal/Magento/Framework/App/Config/Initial.php
+++ b/lib/internal/Magento/Framework/App/Config/Initial.php
@@ -7,6 +7,8 @@
  */
 namespace Magento\Framework\App\Config;
 
+use Magento\Framework\App\Config\ScopeConfigInterface;
+
 class Initial
 {
     /**
@@ -50,14 +52,14 @@ class Initial
     /**
      * Get initial data by given scope
      *
-     * @param string $scope
+     * @param string $scope Format is scope type and scope code separated by pipe: e.g. "type|code"
      * @return array
      */
     public function getData($scope)
     {
         list($scopeType, $scopeCode) = array_pad(explode('|', $scope), 2, null);
 
-        if (\Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT == $scopeType) {
+        if (ScopeConfigInterface::SCOPE_TYPE_DEFAULT == $scopeType) {
             return isset($this->_data[$scopeType]) ? $this->_data[$scopeType] : [];
         } elseif ($scopeCode) {
             return isset($this->_data[$scopeType][$scopeCode]) ? $this->_data[$scopeType][$scopeCode] : [];
diff --git a/lib/internal/Magento/Framework/App/Config/MutableScopeConfigInterface.php b/lib/internal/Magento/Framework/App/Config/MutableScopeConfigInterface.php
index 37a371b547f40439addcfad205d29dd9c178fb07..f68048ddc94611267e17df9c85eb203bf28097a2 100644
--- a/lib/internal/Magento/Framework/App/Config/MutableScopeConfigInterface.php
+++ b/lib/internal/Magento/Framework/App/Config/MutableScopeConfigInterface.php
@@ -8,6 +8,9 @@
 
 namespace Magento\Framework\App\Config;
 
+/**
+ * @api
+ */
 interface MutableScopeConfigInterface extends \Magento\Framework\App\Config\ScopeConfigInterface
 {
     /**
@@ -15,14 +18,14 @@ interface MutableScopeConfigInterface extends \Magento\Framework\App\Config\Scop
      *
      * @param string $path
      * @param mixed $value
-     * @param string $scope
+     * @param string $scopeType
      * @param null|string $scopeCode
      * @return void
      */
     public function setValue(
         $path,
         $value,
-        $scope = \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT,
+        $scopeType = \Magento\Framework\App\Config\ScopeConfigInterface::SCOPE_TYPE_DEFAULT,
         $scopeCode = null
     );
 }
diff --git a/lib/internal/Magento/Framework/App/Config/ReinitableConfigInterface.php b/lib/internal/Magento/Framework/App/Config/ReinitableConfigInterface.php
index 5b9d9d78eb3b4789a2ac6477e5e686ff3e4f0c6f..f9fc887a878e0ec0b73e2ad956ae0ff3b1ae166a 100644
--- a/lib/internal/Magento/Framework/App/Config/ReinitableConfigInterface.php
+++ b/lib/internal/Magento/Framework/App/Config/ReinitableConfigInterface.php
@@ -8,6 +8,9 @@
 
 namespace Magento\Framework\App\Config;
 
+/**
+ * @api
+ */
 interface ReinitableConfigInterface extends \Magento\Framework\App\Config\MutableScopeConfigInterface
 {
     /**
diff --git a/lib/internal/Magento/Framework/App/Config/Resource/ConfigInterface.php b/lib/internal/Magento/Framework/App/Config/Resource/ConfigInterface.php
index aa0e06048980767a44d1f0688ebe6956bbb13355..8084c21ab0d9cd26be2319dd9cfad4e00992dae7 100644
--- a/lib/internal/Magento/Framework/App/Config/Resource/ConfigInterface.php
+++ b/lib/internal/Magento/Framework/App/Config/Resource/ConfigInterface.php
@@ -6,12 +6,12 @@
 namespace Magento\Framework\App\Config\Resource;
 
 /**
- * Resource Config Interface
+ * Resource for storing store configuration values
  */
 interface ConfigInterface
 {
     /**
-     * Save config value
+     * Save config value to the storage resource
      *
      * @param string $path
      * @param string $value
@@ -22,7 +22,7 @@ interface ConfigInterface
     public function saveConfig($path, $value, $scope, $scopeId);
 
     /**
-     * Delete config value
+     * Delete config value from the storage resource
      *
      * @param string $path
      * @param string $scope
diff --git a/lib/internal/Magento/Framework/App/Config/Scope/ReaderInterface.php b/lib/internal/Magento/Framework/App/Config/Scope/ReaderInterface.php
index bf20ecd1d530881e76749275afcff6dbd87939d1..cdcbb42828e51d4ff2f3e13c9449037c64ac9ad5 100644
--- a/lib/internal/Magento/Framework/App/Config/Scope/ReaderInterface.php
+++ b/lib/internal/Magento/Framework/App/Config/Scope/ReaderInterface.php
@@ -12,7 +12,9 @@ interface ReaderInterface
     /**
      * Read configuration scope
      *
+     * @param string|null $scopeType
+     * @throws \Exception May throw an exception if the given scope is invalid
      * @return array
      */
-    public function read();
+    public function read($scopeType = null);
 }
diff --git a/lib/internal/Magento/Framework/App/Config/ScopeConfigInterface.php b/lib/internal/Magento/Framework/App/Config/ScopeConfigInterface.php
index ac84e7358b5d2599a531ea45047d92626370bd44..e98fe284024f1780d731500d810516011b7528ba 100644
--- a/lib/internal/Magento/Framework/App/Config/ScopeConfigInterface.php
+++ b/lib/internal/Magento/Framework/App/Config/ScopeConfigInterface.php
@@ -8,25 +8,33 @@
 
 namespace Magento\Framework\App\Config;
 
+/**
+ * @api
+ */
 interface ScopeConfigInterface
 {
     /**
-     * Retrieve config value by path and scope
+     * Default scope type
+     */
+    const SCOPE_TYPE_DEFAULT = 'default';
+
+    /**
+     * Retrieve config value by path and scope.
      *
-     * @param string $path
-     * @param string $scope
+     * @param string $path The path through the tree of configuration values, e.g., 'general/store_information/name'
+     * @param string $scopeType The scope to use to determine config value, e.g., 'store' or 'default'
      * @param null|string $scopeCode
      * @return mixed
      */
-    public function getValue($path, $scope = \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT, $scopeCode = null);
+    public function getValue($path, $scopeType = ScopeConfigInterface::SCOPE_TYPE_DEFAULT, $scopeCode = null);
 
     /**
      * Retrieve config flag by path and scope
      *
-     * @param string $path
-     * @param string $scope
+     * @param string $path The path through the tree of configuration values, e.g., 'general/store_information/name'
+     * @param string $scopeType The scope to use to determine config value, e.g., 'store' or 'default'
      * @param null|string $scopeCode
      * @return bool
      */
-    public function isSetFlag($path, $scope = \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT, $scopeCode = null);
+    public function isSetFlag($path, $scopeType = ScopeConfigInterface::SCOPE_TYPE_DEFAULT, $scopeCode = null);
 }
diff --git a/lib/internal/Magento/Framework/App/Config/ScopePool.php b/lib/internal/Magento/Framework/App/Config/ScopePool.php
index 34b24deb0028b63402dc2d169f2dbb47566dae9d..1a15575b1a514a0a0a04b728e454c2c18ef0645e 100644
--- a/lib/internal/Magento/Framework/App/Config/ScopePool.php
+++ b/lib/internal/Magento/Framework/App/Config/ScopePool.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\Framework\App\Config;
 
+use Magento\Framework\App\Config\ScopeConfigInterface;
+
 class ScopePool
 {
     const CACHE_TAG = 'config_scopes';
@@ -78,7 +80,7 @@ class ScopePool
                 $data = unserialize($data);
             } else {
                 $reader = $this->_readerPool->getReader($scopeType);
-                if ($scopeType === \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT) {
+                if ($scopeType === ScopeConfigInterface::SCOPE_TYPE_DEFAULT) {
                     $data = $reader->read();
                 } else {
                     $data = $reader->read($scopeCode);
@@ -111,7 +113,7 @@ class ScopePool
     protected function _getScopeCode($scopeType, $scopeCode)
     {
         if (($scopeCode === null || is_numeric($scopeCode))
-            && $scopeType !== \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT
+            && $scopeType !== ScopeConfigInterface::SCOPE_TYPE_DEFAULT
         ) {
             $scopeResolver = $this->_scopeResolverPool->get($scopeType);
             $scopeCode = $scopeResolver->getScope($scopeCode);
diff --git a/lib/internal/Magento/Framework/App/Config/Storage/Writer.php b/lib/internal/Magento/Framework/App/Config/Storage/Writer.php
index b98e4074efa1b953fac38e02be2bbe435568d8c5..63b5ae83dfec68c85f61ebf17ae11396b485373e 100644
--- a/lib/internal/Magento/Framework/App/Config/Storage/Writer.php
+++ b/lib/internal/Magento/Framework/App/Config/Storage/Writer.php
@@ -7,6 +7,8 @@
  */
 namespace Magento\Framework\App\Config\Storage;
 
+use Magento\Framework\App\Config\ScopeConfigInterface;
+
 class Writer implements \Magento\Framework\App\Config\Storage\WriterInterface
 {
     /**
@@ -32,7 +34,7 @@ class Writer implements \Magento\Framework\App\Config\Storage\WriterInterface
      * @param   int $scopeId
      * @return  void
      */
-    public function delete($path, $scope = \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT, $scopeId = 0)
+    public function delete($path, $scope = ScopeConfigInterface::SCOPE_TYPE_DEFAULT, $scopeId = 0)
     {
         $this->_resource->deleteConfig(rtrim($path, '/'), $scope, $scopeId);
     }
@@ -46,7 +48,7 @@ class Writer implements \Magento\Framework\App\Config\Storage\WriterInterface
      * @param int $scopeId
      * @return void
      */
-    public function save($path, $value, $scope = \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT, $scopeId = 0)
+    public function save($path, $value, $scope = ScopeConfigInterface::SCOPE_TYPE_DEFAULT, $scopeId = 0)
     {
         $this->_resource->saveConfig(rtrim($path, '/'), $value, $scope, $scopeId);
     }
diff --git a/lib/internal/Magento/Framework/App/Config/Storage/WriterInterface.php b/lib/internal/Magento/Framework/App/Config/Storage/WriterInterface.php
index 3a3a3af6241361ca757699bf1d1e37ecfab6ad45..67b2aebd5d4a6da8d19eaad74175ca26726a57e0 100644
--- a/lib/internal/Magento/Framework/App/Config/Storage/WriterInterface.php
+++ b/lib/internal/Magento/Framework/App/Config/Storage/WriterInterface.php
@@ -7,6 +7,8 @@
  */
 namespace Magento\Framework\App\Config\Storage;
 
+use Magento\Framework\App\Config\ScopeConfigInterface;
+
 interface WriterInterface
 {
     /**
@@ -17,7 +19,7 @@ interface WriterInterface
      * @param   int $scopeId
      * @return void
      */
-    public function delete($path, $scope = \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT, $scopeId = 0);
+    public function delete($path, $scope = ScopeConfigInterface::SCOPE_TYPE_DEFAULT, $scopeId = 0);
 
     /**
      * Save config value to storage
@@ -28,5 +30,5 @@ interface WriterInterface
      * @param int $scopeId
      * @return void
      */
-    public function save($path, $value, $scope = \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT, $scopeId = 0);
+    public function save($path, $value, $scope = ScopeConfigInterface::SCOPE_TYPE_DEFAULT, $scopeId = 0);
 }
diff --git a/lib/internal/Magento/Framework/App/Config/Value.php b/lib/internal/Magento/Framework/App/Config/Value.php
index 17c50d20b8b3a854cb7f61a319ba5d21b21e1dac..92ee527a9c48eb77a35f527c2c471c2507d1b546 100644
--- a/lib/internal/Magento/Framework/App/Config/Value.php
+++ b/lib/internal/Magento/Framework/App/Config/Value.php
@@ -91,7 +91,7 @@ class Value extends \Magento\Framework\Model\AbstractModel implements \Magento\F
     {
         return (string)$this->_config->getValue(
             $this->getPath(),
-            $this->getScope() ?: \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT,
+            $this->getScope() ?: ScopeConfigInterface::SCOPE_TYPE_DEFAULT,
             $this->getScopeCode()
         );
     }
diff --git a/lib/internal/Magento/Framework/App/MutableScopeConfig.php b/lib/internal/Magento/Framework/App/MutableScopeConfig.php
index c94fb73f9d5e4cb35ddf246710bf464a932a25ad..418817465bd6f11af59b2ae5f4eaf53eea7559cd 100644
--- a/lib/internal/Magento/Framework/App/MutableScopeConfig.php
+++ b/lib/internal/Magento/Framework/App/MutableScopeConfig.php
@@ -9,6 +9,7 @@
 namespace Magento\Framework\App;
 
 use Magento\Framework\App\Config\MutableScopeConfigInterface;
+use Magento\Framework\App\Config\ScopeConfigInterface;
 
 class MutableScopeConfig extends Config implements MutableScopeConfigInterface
 {
@@ -24,7 +25,7 @@ class MutableScopeConfig extends Config implements MutableScopeConfigInterface
     public function setValue(
         $path,
         $value,
-        $scope = \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT,
+        $scope = ScopeConfigInterface::SCOPE_TYPE_DEFAULT,
         $scopeCode = null
     ) {
         if (empty($scopeCode)) {
diff --git a/lib/internal/Magento/Framework/App/Request/Http.php b/lib/internal/Magento/Framework/App/Request/Http.php
index c09ead13054e791d5e6bff403623545b4e24f9e6..e6e502cf38171387aef13cdf606845d082f8664d 100644
--- a/lib/internal/Magento/Framework/App/Request/Http.php
+++ b/lib/internal/Magento/Framework/App/Request/Http.php
@@ -7,6 +7,7 @@
  */
 namespace Magento\Framework\App\Request;
 
+use Magento\Framework\App\Config\ScopeConfigInterface;
 use Magento\Framework\App\RequestInterface;
 use Magento\Framework\App\Route\ConfigInterface\Proxy as ConfigInterface;
 use Magento\Framework\HTTP\PhpEnvironment\Request;
@@ -384,7 +385,7 @@ class Http extends Request implements RequestInterface
         $offLoaderHeader = trim(
             (string)$config->getValue(
                 self::XML_PATH_OFFLOADER_HEADER,
-                \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT
+                ScopeConfigInterface::SCOPE_TYPE_DEFAULT
             )
         );
 
diff --git a/lib/internal/Magento/Framework/App/Resource.php b/lib/internal/Magento/Framework/App/Resource.php
index b38629a460a4fa8a7ed78c1a9e77450ec23c1c8a..b498ec9d349fea88b942b42d2ff6277c23a2449a 100644
--- a/lib/internal/Magento/Framework/App/Resource.php
+++ b/lib/internal/Magento/Framework/App/Resource.php
@@ -126,6 +126,7 @@ class Resource
      * @param   string|string[] $modelEntity
      * @param   string $connectionName
      * @return  string
+     * @api
      */
     public function getTableName($modelEntity, $connectionName = self::DEFAULT_READ_RESOURCE)
     {
diff --git a/lib/internal/Magento/Framework/App/Route/ConfigInterface.php b/lib/internal/Magento/Framework/App/Route/ConfigInterface.php
index c6798f7ce4ab659e813488a155d0aa467ac41449..d96a4af89eac0d2a4c3932995643c1cbccec25e5 100644
--- a/lib/internal/Magento/Framework/App/Route/ConfigInterface.php
+++ b/lib/internal/Magento/Framework/App/Route/ConfigInterface.php
@@ -1,12 +1,15 @@
 <?php
 /**
- * Routes configuration interface
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
 namespace Magento\Framework\App\Route;
 
+/**
+ * Routes configuration interface
+ *
+ * @api
+ */
 interface ConfigInterface
 {
     /**
@@ -32,7 +35,7 @@ interface ConfigInterface
      *
      * @param string $frontName
      * @param string $scope
-     * @return array
+     * @return string[]
      */
     public function getModulesByFrontName($frontName, $scope = null);
 }
diff --git a/lib/internal/Magento/Framework/App/ScopeInterface.php b/lib/internal/Magento/Framework/App/ScopeInterface.php
index d244ec5bf3a1f612722795b72e938fef77f1102f..77c8a8b890ac209400fdf8005636ee869d8ecfd0 100644
--- a/lib/internal/Magento/Framework/App/ScopeInterface.php
+++ b/lib/internal/Magento/Framework/App/ScopeInterface.php
@@ -7,11 +7,6 @@ namespace Magento\Framework\App;
 
 interface ScopeInterface
 {
-    /**
-     * Default scope type
-     */
-    const SCOPE_DEFAULT = 'default';
-
     /**
      * Retrieve scope code
      *
diff --git a/lib/internal/Magento/Framework/App/Test/Unit/Cache/Type/ConfigTest.php b/lib/internal/Magento/Framework/App/Test/Unit/Cache/Type/ConfigTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..c6887709da50fbd2bf4fdb303f3e256749a4e197
--- /dev/null
+++ b/lib/internal/Magento/Framework/App/Test/Unit/Cache/Type/ConfigTest.php
@@ -0,0 +1,169 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\App\Test\Unit\Cache\Type;
+
+use Magento\Framework\App\Cache\Type\FrontendPool;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+
+class ConfigTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\App\Cache\Type\Config
+     */
+    protected $model;
+
+    /**
+     * @var \Magento\Framework\Cache\FrontendInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $frontendMock;
+
+    protected function setUp()
+    {
+        $cacheFrontendPoolMock = $this->getMockBuilder('Magento\Framework\App\Cache\Type\FrontendPool')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->model = (new ObjectManager($this))->getObject(
+            'Magento\Framework\App\Cache\Type\Config',
+            ['cacheFrontendPool' => $cacheFrontendPoolMock]
+        );
+        $this->frontendMock = $this->getMock('Magento\Framework\Cache\FrontendInterface');
+        $cacheFrontendPoolMock->expects($this->once())
+            ->method('get')
+            ->with(\Magento\Framework\App\Cache\Type\Config::TYPE_IDENTIFIER)
+            ->willReturn($this->frontendMock);
+    }
+
+    /**
+     * @param string $method
+     * @param array $params
+     * @param mixed $expectedResult
+     * @dataProvider proxyMethodDataProvider
+     */
+    public function testProxyMethod($method, $params, $expectedResult)
+    {
+        $helper = new \Magento\Framework\TestFramework\Unit\Helper\ProxyTesting();
+        $result = $helper->invokeWithExpectations($this->model, $this->frontendMock, $method, $params, $expectedResult);
+        $this->assertSame($expectedResult, $result);
+    }
+
+    /**
+     * @return array
+     */
+    public function proxyMethodDataProvider()
+    {
+        return [
+            ['test', ['record_id'], 111],
+            ['load', ['record_id'], '111'],
+            ['remove', ['record_id'], true],
+            ['getBackend', [], $this->getMock('Zend_Cache_Backend')],
+            ['getLowLevelFrontend', [], $this->getMock('Zend_Cache_Core')],
+        ];
+    }
+
+    public function testSave()
+    {
+        $expectedResult = new \stdClass();
+        $this->frontendMock->expects(
+            $this->once()
+        )->method(
+            'save'
+        )->with(
+            'test_value',
+            'test_id',
+            ['test_tag_one', 'test_tag_two', \Magento\Framework\App\Cache\Type\Config::CACHE_TAG],
+            111
+        )->will(
+            $this->returnValue($expectedResult)
+        );
+        $actualResult = $this->model->save('test_value', 'test_id', ['test_tag_one', 'test_tag_two'], 111);
+        $this->assertSame($expectedResult, $actualResult);
+    }
+
+    public function testCleanModeAll()
+    {
+        $expectedResult = new \stdClass();
+        $this->frontendMock->expects(
+            $this->once()
+        )->method(
+            'clean'
+        )->with(
+            \Zend_Cache::CLEANING_MODE_MATCHING_TAG,
+            [\Magento\Framework\App\Cache\Type\Config::CACHE_TAG]
+        )->will(
+            $this->returnValue($expectedResult)
+        );
+        $actualResult = $this->model->clean(
+            \Zend_Cache::CLEANING_MODE_ALL,
+            ['ignored_tag_one', 'ignored_tag_two']
+        );
+        $this->assertSame($expectedResult, $actualResult);
+    }
+
+    public function testCleanModeMatchingTag()
+    {
+        $expectedResult = new \stdClass();
+        $this->frontendMock->expects(
+            $this->once()
+        )->method(
+            'clean'
+        )->with(
+            \Zend_Cache::CLEANING_MODE_MATCHING_TAG,
+            ['test_tag_one', 'test_tag_two', \Magento\Framework\App\Cache\Type\Config::CACHE_TAG]
+        )->will(
+            $this->returnValue($expectedResult)
+        );
+        $actualResult = $this->model->clean(
+            \Zend_Cache::CLEANING_MODE_MATCHING_TAG,
+            ['test_tag_one', 'test_tag_two']
+        );
+        $this->assertSame($expectedResult, $actualResult);
+    }
+
+    /**
+     * @param bool $fixtureResultOne
+     * @param bool $fixtureResultTwo
+     * @param bool $expectedResult
+     * @dataProvider cleanModeMatchingAnyTagDataProvider
+     */
+    public function testCleanModeMatchingAnyTag($fixtureResultOne, $fixtureResultTwo, $expectedResult)
+    {
+        $this->frontendMock->expects(
+            $this->at(0)
+        )->method(
+            'clean'
+        )->with(
+            \Zend_Cache::CLEANING_MODE_MATCHING_TAG,
+            ['test_tag_one', \Magento\Framework\App\Cache\Type\Config::CACHE_TAG]
+        )->will(
+            $this->returnValue($fixtureResultOne)
+        );
+        $this->frontendMock->expects(
+            $this->at(1)
+        )->method(
+            'clean'
+        )->with(
+            \Zend_Cache::CLEANING_MODE_MATCHING_TAG,
+            ['test_tag_two', \Magento\Framework\App\Cache\Type\Config::CACHE_TAG]
+        )->will(
+            $this->returnValue($fixtureResultTwo)
+        );
+        $actualResult = $this->model->clean(
+            \Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG,
+            ['test_tag_one', 'test_tag_two']
+        );
+        $this->assertEquals($expectedResult, $actualResult);
+    }
+
+    public function cleanModeMatchingAnyTagDataProvider()
+    {
+        return [
+            'failure, failure' => [false, false, false],
+            'failure, success' => [false, true, true],
+            'success, failure' => [true, false, true],
+            'success, success' => [true, true, true]
+        ];
+    }
+}
diff --git a/lib/internal/Magento/Framework/App/Test/Unit/Config/Storage/WriterTest.php b/lib/internal/Magento/Framework/App/Test/Unit/Config/Storage/WriterTest.php
index 57040f09ee4dd82eb4ec80df99f0b827cc859573..887a1cf477663f00253816aed0bfdd273cd6fe5f 100644
--- a/lib/internal/Magento/Framework/App/Test/Unit/Config/Storage/WriterTest.php
+++ b/lib/internal/Magento/Framework/App/Test/Unit/Config/Storage/WriterTest.php
@@ -5,6 +5,7 @@
  */
 namespace Magento\Framework\App\Test\Unit\Config\Storage;
 
+use Magento\Framework\App\Config\ScopeConfigInterface;
 use Magento\Framework\App\ScopeInterface;
 
 class WriterTest extends \PHPUnit_Framework_TestCase
@@ -40,7 +41,7 @@ class WriterTest extends \PHPUnit_Framework_TestCase
     {
         $this->resource->expects($this->once())
             ->method('deleteConfig')
-            ->with('path', ScopeInterface::SCOPE_DEFAULT, 0);
+            ->with('path', ScopeConfigInterface::SCOPE_TYPE_DEFAULT, 0);
         $this->model->delete('path');
     }
 
@@ -58,7 +59,7 @@ class WriterTest extends \PHPUnit_Framework_TestCase
     {
         $this->resource->expects($this->once())
             ->method('saveConfig')
-            ->with('path', 'value', ScopeInterface::SCOPE_DEFAULT, 0);
+            ->with('path', 'value', ScopeConfigInterface::SCOPE_TYPE_DEFAULT, 0);
         $this->model->save('path', 'value');
     }
 }
diff --git a/lib/internal/Magento/Framework/App/Test/Unit/Request/HttpTest.php b/lib/internal/Magento/Framework/App/Test/Unit/Request/HttpTest.php
index 090580da2726653983a7ed76ec9f16405393092f..8bfb9be2f3bb253932ba96c59d11d9819b704b50 100644
--- a/lib/internal/Magento/Framework/App/Test/Unit/Request/HttpTest.php
+++ b/lib/internal/Magento/Framework/App/Test/Unit/Request/HttpTest.php
@@ -9,6 +9,7 @@
 
 namespace Magento\Framework\App\Test\Unit\Request;
 
+use Magento\Framework\App\Config\ScopeConfigInterface;
 use \Magento\Framework\App\Request\Http;
 use Magento\Framework\App\ScopeInterface;
 use Zend\Stdlib\Parameters;
@@ -325,7 +326,7 @@ class HttpTest extends \PHPUnit_Framework_TestCase
             ->getMock();
         $configMock->expects($this->exactly($configCall))
             ->method('getValue')
-            ->with(\Magento\Framework\App\Request\Http::XML_PATH_OFFLOADER_HEADER, ScopeInterface::SCOPE_DEFAULT)
+            ->with(\Magento\Framework\App\Request\Http::XML_PATH_OFFLOADER_HEADER, ScopeConfigInterface::SCOPE_TYPE_DEFAULT)
             ->willReturn($configOffloadHeader);
         $this->objectManager->expects($this->exactly($configCall))
             ->method('get')
diff --git a/lib/internal/Magento/Framework/App/Test/Unit/View/Deployment/VersionTest.php b/lib/internal/Magento/Framework/App/Test/Unit/View/Deployment/VersionTest.php
old mode 100755
new mode 100644
index 65e059a58a3158ec6e5a627ad6ed85923a0317ac..092aeecbeff26912c6eec7d5070801c9f87312cb
--- a/lib/internal/Magento/Framework/App/Test/Unit/View/Deployment/VersionTest.php
+++ b/lib/internal/Magento/Framework/App/Test/Unit/View/Deployment/VersionTest.php
@@ -3,11 +3,13 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-
 namespace Magento\Framework\App\Test\Unit\View\Deployment;
 
 use \Magento\Framework\App\View\Deployment\Version;
 
+/**
+ * Class VersionTest
+ */
 class VersionTest extends \PHPUnit_Framework_TestCase
 {
     /**
diff --git a/lib/internal/Magento/Framework/AppInterface.php b/lib/internal/Magento/Framework/AppInterface.php
index 7bf9c70ada1b61682217450ee8aa846de7e01943..b363aff3a23479b3d3820e4055c2d4368450ffad 100644
--- a/lib/internal/Magento/Framework/AppInterface.php
+++ b/lib/internal/Magento/Framework/AppInterface.php
@@ -17,7 +17,7 @@ interface AppInterface
     /**
      * Magento version
      */
-    const VERSION = '0.74.0-beta6';
+    const VERSION = '0.74.0-beta7';
 
     /**
      * Launch application
diff --git a/lib/internal/Magento/Framework/Cache/Frontend/Decorator/Bare.php b/lib/internal/Magento/Framework/Cache/Frontend/Decorator/Bare.php
index b856e8608aa726ebf0f32e07ecb01ad7ac8d7d6f..cae35e66ff83d2b40b562b77aaaeaed4d030221e 100644
--- a/lib/internal/Magento/Framework/Cache/Frontend/Decorator/Bare.php
+++ b/lib/internal/Magento/Framework/Cache/Frontend/Decorator/Bare.php
@@ -27,6 +27,18 @@ class Bare implements \Magento\Framework\Cache\FrontendInterface
         $this->_frontend = $frontend;
     }
 
+    /**
+     * Set frontend
+     *
+     * @param \Magento\Framework\Cache\FrontendInterface $frontend
+     * @return $this
+     */
+    protected function setFrontend(\Magento\Framework\Cache\FrontendInterface $frontend)
+    {
+        $this->_frontend = $frontend;
+        return $this;
+    }
+
     /**
      * Retrieve cache frontend instance being decorated
      *
@@ -42,7 +54,7 @@ class Bare implements \Magento\Framework\Cache\FrontendInterface
      */
     public function test($identifier)
     {
-        return $this->_frontend->test($identifier);
+        return $this->_getFrontend()->test($identifier);
     }
 
     /**
@@ -50,7 +62,7 @@ class Bare implements \Magento\Framework\Cache\FrontendInterface
      */
     public function load($identifier)
     {
-        return $this->_frontend->load($identifier);
+        return $this->_getFrontend()->load($identifier);
     }
 
     /**
@@ -60,7 +72,7 @@ class Bare implements \Magento\Framework\Cache\FrontendInterface
      */
     public function save($data, $identifier, array $tags = [], $lifeTime = null)
     {
-        return $this->_frontend->save($data, $identifier, $tags, $lifeTime);
+        return $this->_getFrontend()->save($data, $identifier, $tags, $lifeTime);
     }
 
     /**
@@ -68,7 +80,7 @@ class Bare implements \Magento\Framework\Cache\FrontendInterface
      */
     public function remove($identifier)
     {
-        return $this->_frontend->remove($identifier);
+        return $this->_getFrontend()->remove($identifier);
     }
 
     /**
@@ -76,7 +88,7 @@ class Bare implements \Magento\Framework\Cache\FrontendInterface
      */
     public function clean($mode = \Zend_Cache::CLEANING_MODE_ALL, array $tags = [])
     {
-        return $this->_frontend->clean($mode, $tags);
+        return $this->_getFrontend()->clean($mode, $tags);
     }
 
     /**
@@ -84,7 +96,7 @@ class Bare implements \Magento\Framework\Cache\FrontendInterface
      */
     public function getBackend()
     {
-        return $this->_frontend->getBackend();
+        return $this->_getFrontend()->getBackend();
     }
 
     /**
@@ -92,6 +104,6 @@ class Bare implements \Magento\Framework\Cache\FrontendInterface
      */
     public function getLowLevelFrontend()
     {
-        return $this->_frontend->getLowLevelFrontend();
+        return $this->_getFrontend()->getLowLevelFrontend();
     }
 }
diff --git a/lib/internal/Magento/Framework/Cache/Frontend/Decorator/TagScope.php b/lib/internal/Magento/Framework/Cache/Frontend/Decorator/TagScope.php
index 32c9e4422417cf220a28db98137ef954a26ba705..0f74b1894865754521bd9b595f0b14a5572e1e8c 100644
--- a/lib/internal/Magento/Framework/Cache/Frontend/Decorator/TagScope.php
+++ b/lib/internal/Magento/Framework/Cache/Frontend/Decorator/TagScope.php
@@ -45,7 +45,7 @@ class TagScope extends \Magento\Framework\Cache\Frontend\Decorator\Bare
      */
     public function save($data, $identifier, array $tags = [], $lifeTime = null)
     {
-        $tags[] = $this->_tag;
+        $tags[] = $this->getTag();
         return parent::save($data, $identifier, $tags, $lifeTime);
     }
 
@@ -59,16 +59,16 @@ class TagScope extends \Magento\Framework\Cache\Frontend\Decorator\Bare
         if ($mode == \Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG) {
             $result = false;
             foreach ($tags as $tag) {
-                if (parent::clean(\Zend_Cache::CLEANING_MODE_MATCHING_TAG, [$tag, $this->_tag])) {
+                if (parent::clean(\Zend_Cache::CLEANING_MODE_MATCHING_TAG, [$tag, $this->getTag()])) {
                     $result = true;
                 }
             }
         } else {
             if ($mode == \Zend_Cache::CLEANING_MODE_ALL) {
                 $mode = \Zend_Cache::CLEANING_MODE_MATCHING_TAG;
-                $tags = [$this->_tag];
+                $tags = [$this->getTag()];
             } else {
-                $tags[] = $this->_tag;
+                $tags[] = $this->getTag();
             }
             $result = parent::clean($mode, $tags);
         }
diff --git a/lib/internal/Magento/Framework/Config/ConfigOptionsList.php b/lib/internal/Magento/Framework/Config/ConfigOptionsList.php
index ac1a90652f40c07dc382b094e655a4cd289a5700..a520389a24a748a8379f9cb7ae6163da7ffb1b62 100644
--- a/lib/internal/Magento/Framework/Config/ConfigOptionsList.php
+++ b/lib/internal/Magento/Framework/Config/ConfigOptionsList.php
@@ -32,20 +32,20 @@ class ConfigOptionsList implements ConfigOptionsListInterface
      * Input keys for the options
      */
     const INPUT_KEY_ENCRYPTION_KEY = 'key';
-    const INPUT_KEY_SESSION_SAVE = 'session_save';
-    const INPUT_KEY_DEFINITION_FORMAT = 'definition_format';
-    const INPUT_KEY_DB_HOST = 'db_host';
-    const INPUT_KEY_DB_NAME = 'db_name';
-    const INPUT_KEY_DB_USER = 'db_user';
-    const INPUT_KEY_DB_PASSWORD = 'db_password';
-    const INPUT_KEY_DB_PREFIX = 'db_prefix';
-    const INPUT_KEY_DB_MODEL = 'db_model';
-    const INPUT_KEY_DB_INIT_STATEMENTS = 'db_init_statements';
+    const INPUT_KEY_SESSION_SAVE = 'session-save';
+    const INPUT_KEY_DEFINITION_FORMAT = 'definition-format';
+    const INPUT_KEY_DB_HOST = 'db-host';
+    const INPUT_KEY_DB_NAME = 'db-name';
+    const INPUT_KEY_DB_USER = 'db-user';
+    const INPUT_KEY_DB_PASSWORD = 'db-password';
+    const INPUT_KEY_DB_PREFIX = 'db-prefix';
+    const INPUT_KEY_DB_MODEL = 'db-model';
+    const INPUT_KEY_DB_INIT_STATEMENTS = 'db-init-statements';
     const INPUT_KEY_RESOURCE = 'resource';
     /**#@-*/
 
     /**#@+
-     * Values for session_save
+     * Values for session-save
      */
     const SESSION_SAVE_FILES = 'files';
     const SESSION_SAVE_DB = 'db';
diff --git a/lib/internal/Magento/Framework/Data/Collection/Filesystem.php b/lib/internal/Magento/Framework/Data/Collection/Filesystem.php
index 817c4b420519697de1ad27984ca0d286e151a125..cec62bc94a82b655866f71fe5118c13336868bef 100644
--- a/lib/internal/Magento/Framework/Data/Collection/Filesystem.php
+++ b/lib/internal/Magento/Framework/Data/Collection/Filesystem.php
@@ -284,6 +284,7 @@ class Filesystem extends \Magento\Framework\Data\Collection
      * @param bool $printQuery
      * @param bool $logQuery
      * @return $this
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      * @throws \Exception
      */
     public function loadData($printQuery = false, $logQuery = false)
@@ -668,6 +669,7 @@ class Filesystem extends \Magento\Framework\Data\Collection
      * @param string $value
      * @param string $type
      * @return $this
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      */
     public function addFilter($field, $value, $type = 'and')
     {
@@ -696,7 +698,7 @@ class Filesystem extends \Magento\Framework\Data\Collection
      */
     public function filterCallbackLike($field, $filterValue, $row)
     {
-        $filterValueRegex = str_replace('%', '(.*?)', preg_quote($filterValue, '/'));
+        $filterValueRegex = str_replace('%', '(.*?)', str_replace('\'', '', preg_quote($filterValue, '/')));
         return (bool)preg_match("/^{$filterValueRegex}\$/i", $row[$field]);
     }
 
diff --git a/lib/internal/Magento/Framework/Data/Test/Unit/Collection/FilesystemTest.php b/lib/internal/Magento/Framework/Data/Test/Unit/Collection/FilesystemTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..b764079a841b7f07f35dc9a692b9ffeb6968fe5f
--- /dev/null
+++ b/lib/internal/Magento/Framework/Data/Test/Unit/Collection/FilesystemTest.php
@@ -0,0 +1,30 @@
+<?php
+/***
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Framework\Data\Test\Unit\Collection;
+
+class FilesystemTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\Framework\Data\Collection\Filesystem */
+    private $model;
+
+    public function setUp()
+    {
+        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $this->model = $objectManager->getObject('Magento\Framework\Data\Collection\Filesystem');
+    }
+
+    public function testFilterCallbackLike()
+    {
+        $field = 'field';
+        $row = [$field => 'beginning_filter_target_end',];
+        $filterValueSuccess = new \Zend_Db_Expr('%filter_target%');
+        $filterValueFailure = new \Zend_Db_Expr('%not_found_in_the_row%');
+
+        $this->assertTrue($this->model->filterCallbackLike($field, $filterValueSuccess, $row));
+        $this->assertFalse($this->model->filterCallbackLike($field, $filterValueFailure, $row));
+    }
+}
diff --git a/lib/internal/Magento/Framework/Data/etc/argument/types.xsd b/lib/internal/Magento/Framework/Data/etc/argument/types.xsd
index 5b6b6cedf73ce0d6d6d61ca840ba4ccd6018c115..065e8de3d18029677614bc5cc90855d53727c18e 100644
--- a/lib/internal/Magento/Framework/Data/etc/argument/types.xsd
+++ b/lib/internal/Magento/Framework/Data/etc/argument/types.xsd
@@ -46,6 +46,21 @@
         </xs:complexContent>
     </xs:complexType>
 
+    <xs:complexType name="configurableObject" mixed="true">
+        <xs:complexContent>
+            <xs:extension base="argumentType">
+                <xs:sequence>
+                    <xs:element name="argument" type="argumentType" minOccurs="1" maxOccurs="unbounded">
+                        <xs:key name="argumentConfigurableObjectName">
+                            <xs:selector xpath="argument"/>
+                            <xs:field xpath="@name"/>
+                        </xs:key>
+                    </xs:element>
+                </xs:sequence>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+
     <xs:complexType name="number">
         <xs:complexContent>
             <xs:extension base="argumentType"/>
diff --git a/lib/internal/Magento/Framework/Locale/ConfigInterface.php b/lib/internal/Magento/Framework/Locale/ConfigInterface.php
index 3539f09409a800e83665f16d58871797f96161d0..e0f28fd015c33675eaed0445956c7a728a5e0d84 100644
--- a/lib/internal/Magento/Framework/Locale/ConfigInterface.php
+++ b/lib/internal/Magento/Framework/Locale/ConfigInterface.php
@@ -5,19 +5,24 @@
  */
 namespace Magento\Framework\Locale;
 
+/**
+ * Provides access to locale-related config information
+ *
+ * @api
+ */
 interface ConfigInterface
 {
     /**
      * Get list pre-configured allowed locales
      *
-     * @return array
+     * @return string[]
      */
     public function getAllowedLocales();
 
     /**
      * Get list pre-configured allowed currencies
      *
-     * @return array
+     * @return string[]
      */
     public function getAllowedCurrencies();
 }
diff --git a/lib/internal/Magento/Framework/Locale/Currency.php b/lib/internal/Magento/Framework/Locale/Currency.php
index 5d3c5a9ec9b7e961d870e4a458bc4b3fa69b5b89..f0be6c12172278b8e3a32b86848f296cd606d96a 100644
--- a/lib/internal/Magento/Framework/Locale/Currency.php
+++ b/lib/internal/Magento/Framework/Locale/Currency.php
@@ -7,6 +7,10 @@ namespace Magento\Framework\Locale;
 
 class Currency implements \Magento\Framework\Locale\CurrencyInterface
 {
+    /**
+     * Default currency
+     */
+    const DEFAULT_CURRENCY = 'USD';
     /**
      * @var array
      */
@@ -45,20 +49,15 @@ class Currency implements \Magento\Framework\Locale\CurrencyInterface
     }
 
     /**
-     * Retrieve currency code
-     *
-     * @return string
+     * @inheritdoc
      */
     public function getDefaultCurrency()
     {
-        return \Magento\Framework\Locale\CurrencyInterface::DEFAULT_CURRENCY;
+        return self::DEFAULT_CURRENCY;
     }
 
     /**
-     * Create \Zend_Currency object for current locale
-     *
-     * @param   string $currency
-     * @return  \Magento\Framework\Currency
+     * @inheritdoc
      */
     public function getCurrency($currency)
     {
diff --git a/lib/internal/Magento/Framework/Locale/CurrencyInterface.php b/lib/internal/Magento/Framework/Locale/CurrencyInterface.php
index 774f7d5120f3cead8f11e9d7545928e62634faa2..00bbc4452eedd604d19cb9144d1f38e9417e9568 100644
--- a/lib/internal/Magento/Framework/Locale/CurrencyInterface.php
+++ b/lib/internal/Magento/Framework/Locale/CurrencyInterface.php
@@ -5,27 +5,22 @@
  */
 namespace Magento\Framework\Locale;
 
+/**
+ * Provides access to currency config information
+ *
+ * @api
+ */
 interface CurrencyInterface
 {
     /**
-     * Default currency
-     */
-    const DEFAULT_CURRENCY = 'USD';
-
-    /**
-     * XML path to installed currencies
-     */
-    const XML_PATH_ALLOW_CURRENCIES_INSTALLED = 'system/currency/installed';
-
-    /**
-     * Retrieve currency code
+     * Retrieve default currency code
      *
      * @return string
      */
     public function getDefaultCurrency();
 
     /**
-     * Create \Magento\Framework\Currency object for current locale
+     * Create Currency object for current locale
      *
      * @param   string $currency
      * @return  \Magento\Framework\Currency
diff --git a/lib/internal/Magento/Framework/Locale/Resolver.php b/lib/internal/Magento/Framework/Locale/Resolver.php
index b78be470920ec0638dd4a8a786d13b97470277f3..6a81f60cc5a0cda5d7d55a31f7f9b599e905c94a 100644
--- a/lib/internal/Magento/Framework/Locale/Resolver.php
+++ b/lib/internal/Magento/Framework/Locale/Resolver.php
@@ -9,6 +9,10 @@ use Magento\Framework\App\Config\ScopeConfigInterface;
 
 class Resolver implements ResolverInterface
 {
+    /**
+     * Default locale
+     */
+    const DEFAULT_LOCALE = 'en_US';
     /**
      * Default locale code
      *
@@ -85,7 +89,7 @@ class Resolver implements ResolverInterface
         if (!$this->defaultLocale) {
             $locale = $this->scopeConfig->getValue($this->getDefaultLocalePath(), $this->scopeType);
             if (!$locale) {
-                $locale = ResolverInterface::DEFAULT_LOCALE;
+                $locale = self::DEFAULT_LOCALE;
             }
             $this->defaultLocale = $locale;
         }
diff --git a/lib/internal/Magento/Framework/Locale/ResolverInterface.php b/lib/internal/Magento/Framework/Locale/ResolverInterface.php
index 08add444266f073aaa354935b6857be2c7edd34f..a17932ed8628870f7ce9f086946807498c836807 100644
--- a/lib/internal/Magento/Framework/Locale/ResolverInterface.php
+++ b/lib/internal/Magento/Framework/Locale/ResolverInterface.php
@@ -5,13 +5,13 @@
  */
 namespace Magento\Framework\Locale;
 
+/**
+ * Manages locale config information
+ *
+ * @api
+ */
 interface ResolverInterface
 {
-    /**
-     * Default locale
-     */
-    const DEFAULT_LOCALE = 'en_US';
-
     /**
      * Return path to default locale
      *
diff --git a/lib/internal/Magento/Framework/Locale/Test/Unit/CurrencyTest.php b/lib/internal/Magento/Framework/Locale/Test/Unit/CurrencyTest.php
index 01552d3a972294bd649141074cc91f985829743b..226e8d4d8508be64e2a9a9454aeaa94cbb3de243 100644
--- a/lib/internal/Magento/Framework/Locale/Test/Unit/CurrencyTest.php
+++ b/lib/internal/Magento/Framework/Locale/Test/Unit/CurrencyTest.php
@@ -8,6 +8,7 @@
 
 namespace Magento\Framework\Locale\Test\Unit;
 
+use Magento\Framework\Locale\Currency;
 use Magento\Framework\Locale\CurrencyInterface;
 
 class CurrencyTest extends \PHPUnit_Framework_TestCase
@@ -68,7 +69,7 @@ class CurrencyTest extends \PHPUnit_Framework_TestCase
 
     public function testGetDefaultCurrency()
     {
-        $expectedDefaultCurrency = CurrencyInterface::DEFAULT_CURRENCY;
+        $expectedDefaultCurrency = Currency::DEFAULT_CURRENCY;
         $retrievedDefaultCurrency = $this->testCurrencyObject->getDefaultCurrency();
         $this->assertEquals($expectedDefaultCurrency, $retrievedDefaultCurrency);
     }
diff --git a/lib/internal/Magento/Framework/Locale/Validator.php b/lib/internal/Magento/Framework/Locale/Validator.php
index b30727562c45755db8b67dfb00be40c18bae09fc..0cdf265af01b329f3a87eca97ac8de8c723902b6 100644
--- a/lib/internal/Magento/Framework/Locale/Validator.php
+++ b/lib/internal/Magento/Framework/Locale/Validator.php
@@ -29,10 +29,12 @@ class Validator
     }
 
     /**
-     * Validate locale code
+     * Validate locale code. Code must be in the list of allowed locales.
      *
      * @param string $localeCode
      * @return bool
+     *
+     * @api
      */
     public function isValid($localeCode)
     {
diff --git a/lib/internal/Magento/Framework/Message/Factory.php b/lib/internal/Magento/Framework/Message/Factory.php
index 4c16064b5b6599dbb98f48307601dfff7eda1ee3..be7e3c9bb566a041c026a5916f4e51364e06b07d 100644
--- a/lib/internal/Magento/Framework/Message/Factory.php
+++ b/lib/internal/Magento/Framework/Message/Factory.php
@@ -45,11 +45,12 @@ class Factory
     }
 
     /**
-     * Create message instance with specified parameters
+     * Create a message instance of a given type with given text.
      *
-     * @param string $type
-     * @param string $text
-     * @throws \InvalidArgumentException
+     * @param string $type The message type to create, must correspond to a message type under the
+     * namespace Magento\Framework\Message\
+     * @param string $text The text to inject into the message
+     * @throws \InvalidArgumentException Exception gets thrown if type does not correspond to a valid Magento message
      * @return MessageInterface
      */
     public function create($type, $text)
diff --git a/lib/internal/Magento/Framework/Message/Manager.php b/lib/internal/Magento/Framework/Message/Manager.php
index 73b212a58e3ee88769bd653a815c15ecafde2578..815296c80bad2d8453564f10797ade913a2e5c7f 100644
--- a/lib/internal/Magento/Framework/Message/Manager.php
+++ b/lib/internal/Magento/Framework/Message/Manager.php
@@ -14,6 +14,10 @@ use Psr\Log\LoggerInterface as Logger;
  */
 class Manager implements ManagerInterface
 {
+    /**
+     * Default message group
+     */
+    const DEFAULT_GROUP = 'default';
     /**
      * @var Session
      */
@@ -74,9 +78,7 @@ class Manager implements ManagerInterface
     }
 
     /**
-     * Retrieve default message group
-     *
-     * @return string
+     * {@inheritdoc}
      */
     public function getDefaultGroup()
     {
@@ -95,7 +97,7 @@ class Manager implements ManagerInterface
     }
 
     /**
-     * Retrieve messages
+     * @inheritdoc
      *
      * @param string|null $group
      * @param bool $clear
@@ -118,7 +120,7 @@ class Manager implements ManagerInterface
     }
 
     /**
-     * Adding new message to message collection
+     * @inheritdoc
      *
      * @param MessageInterface $message
      * @param string|null $group
@@ -133,7 +135,7 @@ class Manager implements ManagerInterface
     }
 
     /**
-     * Adding messages array to message collection
+     * @inheritdoc
      *
      * @param MessageInterface[] $messages
      * @param string|null $group
@@ -148,7 +150,7 @@ class Manager implements ManagerInterface
     }
 
     /**
-     * Adding new error message
+     * @inheritdoc
      *
      * @param string $message
      * @param string|null $group
@@ -161,7 +163,7 @@ class Manager implements ManagerInterface
     }
 
     /**
-     * Adding new warning message
+     * @inheritdoc
      *
      * @param string $message
      * @param string|null $group
@@ -174,7 +176,7 @@ class Manager implements ManagerInterface
     }
 
     /**
-     * Adding new notice message
+     * @inheritdoc
      *
      * @param string $message
      * @param string|null $group
@@ -187,7 +189,7 @@ class Manager implements ManagerInterface
     }
 
     /**
-     * Adding new success message
+     * @inheritdoc
      *
      * @param string $message
      * @param string|null $group
@@ -200,7 +202,7 @@ class Manager implements ManagerInterface
     }
 
     /**
-     * Adds messages array to message collection, but doesn't add duplicates to it
+     * @inheritdoc
      *
      * @param MessageInterface[]|MessageInterface $messages
      * @param string|null $group
@@ -244,7 +246,7 @@ class Manager implements ManagerInterface
     }
 
     /**
-     * Not Magento exception handling
+     * @inheritdoc
      *
      * @param \Exception $exception
      * @param string $alternativeText
diff --git a/lib/internal/Magento/Framework/Message/ManagerInterface.php b/lib/internal/Magento/Framework/Message/ManagerInterface.php
index 36851dc866c49be7c9e0f0ea15490c79b776db4a..dd73d2a2fcfbc8acbd9aabdef42a3f5d59616f4d 100644
--- a/lib/internal/Magento/Framework/Message/ManagerInterface.php
+++ b/lib/internal/Magento/Framework/Message/ManagerInterface.php
@@ -6,15 +6,12 @@
 namespace Magento\Framework\Message;
 
 /**
- * Message manager interface
+ * Adds different types of messages to the session, and allows access to existing messages.
+ *
+ * @api
  */
 interface ManagerInterface
 {
-    /**
-     * Default message group
-     */
-    const DEFAULT_GROUP = 'default';
-
     /**
      * Retrieve messages
      *
@@ -32,7 +29,7 @@ interface ManagerInterface
     public function getDefaultGroup();
 
     /**
-     * Adding new message to message collection
+     * Adds new message to message collection
      *
      * @param MessageInterface $message
      * @param string|null $group
@@ -41,7 +38,7 @@ interface ManagerInterface
     public function addMessage(MessageInterface $message, $group = null);
 
     /**
-     * Adding messages array to message collection
+     * Adds messages array to message collection
      *
      * @param array $messages
      * @param string|null $group
@@ -50,7 +47,7 @@ interface ManagerInterface
     public function addMessages(array $messages, $group = null);
 
     /**
-     * Adding new error message
+     * Adds new error message
      *
      * @param string $message
      * @param string|null $group
@@ -59,7 +56,7 @@ interface ManagerInterface
     public function addError($message, $group = null);
 
     /**
-     * Adding new warning message
+     * Adds new warning message
      *
      * @param string $message
      * @param string|null $group
@@ -68,7 +65,7 @@ interface ManagerInterface
     public function addWarning($message, $group = null);
 
     /**
-     * Adding new notice message
+     * Adds new notice message
      *
      * @param string $message
      * @param string|null $group
@@ -77,7 +74,7 @@ interface ManagerInterface
     public function addNotice($message, $group = null);
 
     /**
-     * Adding new success message
+     * Adds new success message
      *
      * @param string $message
      * @param string|null $group
@@ -86,7 +83,7 @@ interface ManagerInterface
     public function addSuccess($message, $group = null);
 
     /**
-     * Adds messages array to message collection, but doesn't add duplicates to it
+     * Adds messages array to message collection, without adding duplicate messages
      *
      * @param array|MessageInterface $messages
      * @param string|null $group
@@ -95,7 +92,7 @@ interface ManagerInterface
     public function addUniqueMessages($messages, $group = null);
 
     /**
-     * Not Magento exception handling
+     * Adds a message describing an exception. Does not contain Exception handling logic.
      *
      * @param \Exception $exception
      * @param string $alternativeText
diff --git a/lib/internal/Magento/Framework/Message/MessageInterface.php b/lib/internal/Magento/Framework/Message/MessageInterface.php
index e5342f49ac042e79fb0b572fca328a1285ab8b22..d9d60e047b1713fd6a6288a86b2a7b74b8ddae0a 100644
--- a/lib/internal/Magento/Framework/Message/MessageInterface.php
+++ b/lib/internal/Magento/Framework/Message/MessageInterface.php
@@ -6,7 +6,9 @@
 namespace Magento\Framework\Message;
 
 /**
- * Interface for message
+ * Represent a message with a type, content text, and an isSticky attribute to prevent message from being cleared.
+ *
+ * @api
  */
 interface MessageInterface
 {
diff --git a/lib/internal/Magento/Framework/Message/Session.php b/lib/internal/Magento/Framework/Message/Session.php
index da86d172577a4f0ae18dce396deaf6688cd42d2e..8ceb66543e370ccf34321cef02be325bedb2cf85 100644
--- a/lib/internal/Magento/Framework/Message/Session.php
+++ b/lib/internal/Magento/Framework/Message/Session.php
@@ -8,6 +8,6 @@ namespace Magento\Framework\Message;
 /**
  * Message session model
  */
-class Session extends \Magento\Framework\Session\Generic
+class Session extends \Magento\Framework\Session\SessionManager
 {
 }
diff --git a/lib/internal/Magento/Framework/Message/Test/Unit/ManagerTest.php b/lib/internal/Magento/Framework/Message/Test/Unit/ManagerTest.php
index c4980974bc289f00167474eb50040197e020cb66..d65a5459a4ee92dae76a266743cb03d39c3220b6 100644
--- a/lib/internal/Magento/Framework/Message/Test/Unit/ManagerTest.php
+++ b/lib/internal/Magento/Framework/Message/Test/Unit/ManagerTest.php
@@ -5,6 +5,7 @@
  */
 namespace Magento\Framework\Message\Test\Unit;
 
+use Magento\Framework\Message\Manager;
 use Magento\Framework\Message\MessageInterface;
 use Magento\Framework\Message\ManagerInterface;
 
@@ -86,7 +87,7 @@ class ManagerTest extends \PHPUnit_Framework_TestCase
 
     public function testGetDefaultGroup()
     {
-        $this->assertEquals(ManagerInterface::DEFAULT_GROUP, $this->model->getDefaultGroup());
+        $this->assertEquals(Manager::DEFAULT_GROUP, $this->model->getDefaultGroup());
 
         $customDefaultGroup = 'some_group';
         $customManager = $this->objectManager->getObject(
@@ -117,7 +118,7 @@ class ManagerTest extends \PHPUnit_Framework_TestCase
         )->method(
             'getData'
         )->with(
-            ManagerInterface::DEFAULT_GROUP
+            Manager::DEFAULT_GROUP
         )->will(
             $this->returnValue(null)
         );
@@ -126,7 +127,7 @@ class ManagerTest extends \PHPUnit_Framework_TestCase
         )->method(
             'setData'
         )->with(
-            ManagerInterface::DEFAULT_GROUP,
+            Manager::DEFAULT_GROUP,
             $messageCollection
         )->will(
             $this->returnValue($this->session)
@@ -136,7 +137,7 @@ class ManagerTest extends \PHPUnit_Framework_TestCase
         )->method(
             'getData'
         )->with(
-            ManagerInterface::DEFAULT_GROUP
+            Manager::DEFAULT_GROUP
         )->will(
             $this->returnValue($messageCollection)
         );
@@ -161,7 +162,7 @@ class ManagerTest extends \PHPUnit_Framework_TestCase
         )->method(
             'getData'
         )->with(
-            ManagerInterface::DEFAULT_GROUP
+            Manager::DEFAULT_GROUP
         )->will(
             $this->returnValue($messageCollection)
         );
@@ -209,7 +210,7 @@ class ManagerTest extends \PHPUnit_Framework_TestCase
         )->method(
             'getData'
         )->with(
-            ManagerInterface::DEFAULT_GROUP
+            Manager::DEFAULT_GROUP
         )->will(
             $this->returnValue($messageCollection)
         );
diff --git a/lib/internal/Magento/Framework/Model/Resource/AbstractResource.php b/lib/internal/Magento/Framework/Model/Resource/AbstractResource.php
index 831dcf5ae71fb2f832a7372efd8abdfe49a0ac40..c2a9bd81aad960e498303fae9f00a0f333a26272 100644
--- a/lib/internal/Magento/Framework/Model/Resource/AbstractResource.php
+++ b/lib/internal/Magento/Framework/Model/Resource/AbstractResource.php
@@ -61,6 +61,7 @@ abstract class AbstractResource
      * Start resource transaction
      *
      * @return $this
+     * @api
      */
     public function beginTransaction()
     {
@@ -73,6 +74,7 @@ abstract class AbstractResource
      *
      * @param array $callback
      * @return $this
+     * @api
      */
     public function addCommitCallback($callback)
     {
@@ -85,6 +87,7 @@ abstract class AbstractResource
      * Commit resource transaction
      *
      * @return $this
+     * @api
      */
     public function commit()
     {
@@ -109,6 +112,7 @@ abstract class AbstractResource
      * Roll back resource transaction
      *
      * @return $this
+     * @api
      */
     public function rollBack()
     {
diff --git a/lib/internal/Magento/Framework/Model/Resource/Db/AbstractDb.php b/lib/internal/Magento/Framework/Model/Resource/Db/AbstractDb.php
index 351365b08d9eb57d45b6b65a50c53edbb93d482c..ba80e64a256222d7d02ac7eaae6cd95f7ec3717a 100644
--- a/lib/internal/Magento/Framework/Model/Resource/Db/AbstractDb.php
+++ b/lib/internal/Magento/Framework/Model/Resource/Db/AbstractDb.php
@@ -233,6 +233,7 @@ abstract class AbstractDb extends \Magento\Framework\Model\Resource\AbstractReso
      *
      * @throws LocalizedException
      * @return string
+     * @api
      */
     public function getIdFieldName()
     {
@@ -248,6 +249,7 @@ abstract class AbstractDb extends \Magento\Framework\Model\Resource\AbstractReso
      *
      * @throws LocalizedException
      * @return string
+     * @api
      */
     public function getMainTable()
     {
@@ -262,6 +264,7 @@ abstract class AbstractDb extends \Magento\Framework\Model\Resource\AbstractReso
      *
      * @param string $tableName
      * @return string
+     * @api
      */
     public function getTable($tableName)
     {
@@ -391,6 +394,7 @@ abstract class AbstractDb extends \Magento\Framework\Model\Resource\AbstractReso
      * @param \Magento\Framework\Model\AbstractModel $object
      * @return $this
      * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+     * @api
      */
     public function save(\Magento\Framework\Model\AbstractModel $object)
     {
diff --git a/lib/internal/Magento/Framework/Object/Copy.php b/lib/internal/Magento/Framework/Object/Copy.php
index 9145e0aba3bc9b9a106863967d2b7c5a3bd8b124..c0d87722872490ec10c4b15efb33fc3f2385fd33 100644
--- a/lib/internal/Magento/Framework/Object/Copy.php
+++ b/lib/internal/Magento/Framework/Object/Copy.php
@@ -47,6 +47,8 @@ class Copy
      * @param array|\Magento\Framework\Object $target
      * @param string $root
      * @return array|\Magento\Framework\Object|null the value of $target
+     *
+     * @api
      */
     public function copyFieldsetToTarget($fieldset, $aspect, $source, $target, $root = 'global')
     {
@@ -91,6 +93,8 @@ class Copy
      * @param array|\Magento\Framework\Object $source
      * @param string $root
      * @return array $data
+     *
+     * @api
      */
     public function getDataFromFieldset($fieldset, $aspect, $source, $root = 'global')
     {
diff --git a/lib/internal/Magento/Framework/Object/Copy/Config/Data/Proxy.php b/lib/internal/Magento/Framework/Object/Copy/Config/Data/Proxy.php
new file mode 100644
index 0000000000000000000000000000000000000000..ea974307333d3da54ea344c57d8b72331f30a44f
--- /dev/null
+++ b/lib/internal/Magento/Framework/Object/Copy/Config/Data/Proxy.php
@@ -0,0 +1,124 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\Object\Copy\Config\Data;
+
+/**
+ * Proxy class for @see \Magento\Framework\Object\Copy\Config\Data
+ */
+class Proxy extends \Magento\Framework\Object\Copy\Config\Data
+{
+    /**
+     * Object Manager instance
+     *
+     * @var \Magento\Framework\ObjectManagerInterface
+     */
+    protected $_objectManager = null;
+
+    /**
+     * Proxied instance name
+     *
+     * @var string
+     */
+    protected $_instanceName = null;
+
+    /**
+     * Proxied instance
+     *
+     * @var \Magento\Framework\Object\Copy\Config\Data
+     */
+    protected $_subject = null;
+
+    /**
+     * Instance shareability flag
+     *
+     * @var bool
+     */
+    protected $_isShared = null;
+
+    /**
+     * Proxy constructor
+     *
+     * @param \Magento\Framework\ObjectManagerInterface $objectManager
+     * @param string $instanceName
+     * @param bool $shared
+     */
+    public function __construct(
+        \Magento\Framework\ObjectManagerInterface $objectManager,
+        $instanceName = '\\Magento\\Framework\\Object\\Copy\\Config\\Data',
+        $shared = true
+    ) {
+        $this->_objectManager = $objectManager;
+        $this->_instanceName = $instanceName;
+        $this->_isShared = $shared;
+    }
+
+    /**
+     * @return array
+     */
+    public function __sleep()
+    {
+        return ['_subject', '_isShared'];
+    }
+
+    /**
+     * Retrieve ObjectManager from global scope
+     *
+     * @return void
+     */
+    public function __wakeup()
+    {
+        $this->_objectManager = \Magento\Framework\App\ObjectManager::getInstance();
+    }
+
+    /**
+     * Clone proxied instance
+     *
+     * @return void
+     */
+    public function __clone()
+    {
+        $this->_subject = clone $this->_getSubject();
+    }
+
+    /**
+     * Get proxied instance
+     *
+     * @return \Magento\Framework\Object\Copy\Config\Data
+     */
+    protected function _getSubject()
+    {
+        if (!$this->_subject) {
+            $this->_subject = true === $this->_isShared
+                ? $this->_objectManager->get($this->_instanceName)
+                : $this->_objectManager->create($this->_instanceName);
+        }
+        return $this->_subject;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function merge(array $config)
+    {
+        return $this->_getSubject()->merge($config);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function get($path = null, $default = null)
+    {
+        return $this->_getSubject()->get($path, $default);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function reset()
+    {
+        return $this->_getSubject()->reset();
+    }
+}
diff --git a/lib/internal/Magento/Framework/ObjectManager/Profiler/FactoryDecorator.php b/lib/internal/Magento/Framework/ObjectManager/Profiler/FactoryDecorator.php
index ad3864500bbc9502a1d8d6ecbaa296c76ac82d19..895377327281b908c2a8d0944a9415bbdb400275 100644
--- a/lib/internal/Magento/Framework/ObjectManager/Profiler/FactoryDecorator.php
+++ b/lib/internal/Magento/Framework/ObjectManager/Profiler/FactoryDecorator.php
@@ -8,6 +8,11 @@ namespace Magento\Framework\ObjectManager\Profiler;
 
 class FactoryDecorator implements \Magento\Framework\ObjectManager\FactoryInterface
 {
+    /**
+     * Name of the class that generates logging wrappers
+     */
+    const GENERATOR_NAME = 'Magento\Framework\ObjectManager\Profiler\Code\Generator\Logger';
+
     /**
      * @var \Magento\Framework\ObjectManager\FactoryInterface
      */
@@ -45,9 +50,12 @@ class FactoryDecorator implements \Magento\Framework\ObjectManager\FactoryInterf
     {
         $this->log->startCreating($requestedType);
         $result = $this->subject->create($requestedType, $arguments);
-        $loggerClassName = get_class($result) . "\\Logger";
-        $wrappedResult = new $loggerClassName($result, $this->log);
-        $this->log->stopCreating($result);
-        return $wrappedResult;
+        if ($requestedType !== self::GENERATOR_NAME) {
+            $loggerClassName = get_class($result) . "\\Logger";
+            $wrappedResult = new $loggerClassName($result, $this->log);
+            $this->log->stopCreating($result);
+            $result = $wrappedResult;
+        }
+        return $result;
     }
 }
diff --git a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Profiler/FactoryDecoratorTest.php b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Profiler/FactoryDecoratorTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..1d0fa91e42286c72588946788f40491de72e925e
--- /dev/null
+++ b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Profiler/FactoryDecoratorTest.php
@@ -0,0 +1,75 @@
+<?php
+/***
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Framework\ObjectManager\Test\Unit\Profiler;
+
+class FactoryDecoratorTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * Name of the base class to wrap in logger
+     */
+    const CLASS_NAME = 'Magento\Test\Di\WrappedClass';
+
+    /**
+     * Name of the wrapper class that does logging
+     */
+    const LOGGER_NAME = 'Magento\Test\Di\WrappedClass\Logger';
+
+    /**
+     * Name of the class that generates wrappers - should not be wrapped by logger
+     */
+    const GENERATOR_NAME = 'Magento\Framework\ObjectManager\Profiler\Code\Generator\Logger';
+
+    /** @var  \PHPUnit_Framework_MockObject_MockObject | \Magento\Framework\ObjectManager\FactoryInterface*/
+    private $objectManagerMock;
+
+    /** @var  \Magento\Framework\ObjectManager\Profiler\FactoryDecorator */
+    private $model;
+
+    public function setUp()
+    {
+        require_once __DIR__ . '/../_files/logger_classes.php';
+        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+
+        $this->objectManagerMock = $this->getMockBuilder('Magento\Framework\ObjectManager\FactoryInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        // Instantiate SUT
+        $this->model = $objectManager->getObject(
+            'Magento\Framework\ObjectManager\Profiler\FactoryDecorator',
+            ['subject' => $this->objectManagerMock]
+        );
+    }
+
+    public function testCreate()
+    {
+        $baseObjectName = self::CLASS_NAME;
+        $baseObject = new $baseObjectName();
+
+        $arguments = [1, 2, 3];
+
+        $this->objectManagerMock->expects($this->once())
+            ->method('create')
+            ->with(self::CLASS_NAME, $arguments)
+            ->willReturn($baseObject);
+
+        $this->assertInstanceOf(self::LOGGER_NAME, $this->model->create(self::CLASS_NAME, $arguments));
+    }
+
+    public function testCreateNeglectGenerator()
+    {
+        $arguments = [1, 2, 3];
+        $loggerMock = $this->getMockBuilder(self::GENERATOR_NAME)->disableOriginalConstructor()->getMock();
+
+        $this->objectManagerMock->expects($this->once())
+            ->method('create')
+            ->with(self::GENERATOR_NAME, $arguments)
+            ->willReturn($loggerMock);
+
+        $this->assertSame($loggerMock, $this->model->create(self::GENERATOR_NAME, $arguments));
+    }
+}
diff --git a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/_files/logger_classes.php b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/_files/logger_classes.php
new file mode 100644
index 0000000000000000000000000000000000000000..da593225f2079af53a730190a56afc0cb7715400
--- /dev/null
+++ b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/_files/logger_classes.php
@@ -0,0 +1,26 @@
+<?php
+/***
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+//@codingStandardsIgnoreStart
+namespace Magento\Test\Di {
+
+    /**
+     * Test classes used for \Magento\Framework\ObjectManager\Test\Unit\Profiler\FactoryDecoratorTest
+     */
+    class WrappedClass
+    {
+
+    }
+}
+
+namespace Magento\Test\Di\WrappedClass {
+
+    class Logger
+    {
+
+    }
+}
+//@codingStandardsIgnoreEnd
diff --git a/lib/internal/Magento/Framework/Phrase.php b/lib/internal/Magento/Framework/Phrase.php
index 992834a4816e1c14f8a56c488a739ed97c3d70f4..f4194f69b02d8c46e2907d43dc8574a2f503044f 100644
--- a/lib/internal/Magento/Framework/Phrase.php
+++ b/lib/internal/Magento/Framework/Phrase.php
@@ -9,7 +9,7 @@ namespace Magento\Framework;
 
 use Zend\Stdlib\JsonSerializable;
 use Magento\Framework\Phrase\RendererInterface;
-use Magento\Framework\Phrase\Renderer\Placeholder;
+use Magento\Framework\Phrase\Renderer\Placeholder as RendererPlaceholder;
 
 class Phrase implements JsonSerializable
 {
@@ -52,11 +52,10 @@ class Phrase implements JsonSerializable
      */
     public static function getRenderer()
     {
-        if (self::$renderer) {
-            return self::$renderer;
-        } else {
-            self::$renderer = new \Magento\Framework\Phrase\Renderer\Placeholder();
+        if (!self::$renderer) {
+            self::$renderer = new RendererPlaceholder();
         }
+        return self::$renderer;
     }
 
     /**
@@ -98,7 +97,11 @@ class Phrase implements JsonSerializable
      */
     public function render()
     {
-        return self::getRenderer() ? self::getRenderer()->render([$this->text], $this->arguments) : $this->text;
+        try {
+            return self::getRenderer()->render([$this->text], $this->getArguments());
+        } catch (\Exception $e) {
+            return $this->getText();
+        }
     }
 
     /**
diff --git a/lib/internal/Magento/Framework/Phrase/Renderer/Composite.php b/lib/internal/Magento/Framework/Phrase/Renderer/Composite.php
index 4b93aee4b42b041e4b09e75a7e1355258168a371..91d8f40139887d3323815a11570418482beb3750 100644
--- a/lib/internal/Magento/Framework/Phrase/Renderer/Composite.php
+++ b/lib/internal/Magento/Framework/Phrase/Renderer/Composite.php
@@ -17,7 +17,7 @@ class Composite implements RendererInterface
     protected $_renderers;
 
     /**
-     * @param RendererInterface[] $renderers
+     * @param \Magento\Framework\Phrase\RendererInterface[] $renderers
      * @throws \InvalidArgumentException
      */
     public function __construct(array $renderers)
diff --git a/lib/internal/Magento/Framework/Phrase/Renderer/Inline.php b/lib/internal/Magento/Framework/Phrase/Renderer/Inline.php
index 5d3f094d859909e5e105b3466afb1bf9335be1d0..0cb074943f9b7a352e7062fded30cd1d406e4280 100644
--- a/lib/internal/Magento/Framework/Phrase/Renderer/Inline.php
+++ b/lib/internal/Magento/Framework/Phrase/Renderer/Inline.php
@@ -7,7 +7,12 @@
  */
 namespace Magento\Framework\Phrase\Renderer;
 
-class Inline implements \Magento\Framework\Phrase\RendererInterface
+use Magento\Framework\Phrase\RendererInterface;
+use Magento\Framework\TranslateInterface;
+use Magento\Framework\Translate\Inline\ProviderInterface;
+use Psr\Log\LoggerInterface;
+
+class Inline implements RendererInterface
 {
     /**
      * @var \Magento\Framework\TranslateInterface
@@ -19,16 +24,24 @@ class Inline implements \Magento\Framework\Phrase\RendererInterface
      */
     protected $inlineProvider;
 
+    /**
+     * @var \Psr\Log\LoggerInterface
+     */
+    protected $logger;
+
     /**
      * @param \Magento\Framework\TranslateInterface $translator
      * @param \Magento\Framework\Translate\Inline\ProviderInterface $inlineProvider
+     * @param \Psr\Log\LoggerInterface $logger
      */
     public function __construct(
-        \Magento\Framework\TranslateInterface $translator,
-        \Magento\Framework\Translate\Inline\ProviderInterface $inlineProvider
+        TranslateInterface $translator,
+        ProviderInterface $inlineProvider,
+        LoggerInterface $logger
     ) {
         $this->translator = $translator;
         $this->inlineProvider = $inlineProvider;
+        $this->logger = $logger;
     }
 
     /**
@@ -37,22 +50,29 @@ class Inline implements \Magento\Framework\Phrase\RendererInterface
      * @param [] $source
      * @param [] $arguments
      * @return string
+     * @throws \Exception
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      */
     public function render(array $source, array $arguments)
     {
         $text = end($source);
 
-        if (!$this->inlineProvider->get()->isAllowed()) {
-            return $text;
-        }
+        try {
+            if (!$this->inlineProvider->get()->isAllowed()) {
+                return $text;
+            }
 
-        if (strpos($text, '{{{') === false
-            || strpos($text, '}}}') === false
-            || strpos($text, '}}{{') === false
-        ) {
-            $text = '{{{'
-                . implode('}}{{', array_reverse($source))
-                . '}}{{' . $this->translator->getTheme() . '}}}';
+            if (strpos($text, '{{{') === false
+                || strpos($text, '}}}') === false
+                || strpos($text, '}}{{') === false
+            ) {
+                $text = '{{{'
+                    . implode('}}{{', array_reverse($source))
+                    . '}}{{' . $this->translator->getTheme() . '}}}';
+            }
+        } catch (\Exception $e) {
+            $this->logger->critical($e->getMessage());
+            throw $e;
         }
 
         return $text;
diff --git a/lib/internal/Magento/Framework/Phrase/Renderer/Placeholder.php b/lib/internal/Magento/Framework/Phrase/Renderer/Placeholder.php
index a9e6ed62f35216dfef1549983e020221f5dc593b..db2551a0157465783a74bb8b17e0291a4c290a09 100644
--- a/lib/internal/Magento/Framework/Phrase/Renderer/Placeholder.php
+++ b/lib/internal/Magento/Framework/Phrase/Renderer/Placeholder.php
@@ -7,7 +7,9 @@
  */
 namespace Magento\Framework\Phrase\Renderer;
 
-class Placeholder implements \Magento\Framework\Phrase\RendererInterface
+use Magento\Framework\Phrase\RendererInterface;
+
+class Placeholder implements RendererInterface
 {
     /**
      * Render source text
@@ -23,7 +25,7 @@ class Placeholder implements \Magento\Framework\Phrase\RendererInterface
         if ($arguments) {
             $placeholders = [];
             foreach (array_keys($arguments) as $key) {
-                $placeholders[] = "%" . (is_int($key) ? strval($key + 1) : $key);
+                $placeholders[] = '%' . (is_int($key) ? strval($key + 1) : $key);
             }
             $text = str_replace($placeholders, $arguments, $text);
         }
diff --git a/lib/internal/Magento/Framework/Phrase/Renderer/Translate.php b/lib/internal/Magento/Framework/Phrase/Renderer/Translate.php
index 6f981a679377e57c5924b16230d24d0ac1393f47..449b34d61c094435b6b1eb448b5d1ff7c6f3260f 100644
--- a/lib/internal/Magento/Framework/Phrase/Renderer/Translate.php
+++ b/lib/internal/Magento/Framework/Phrase/Renderer/Translate.php
@@ -7,21 +7,34 @@
  */
 namespace Magento\Framework\Phrase\Renderer;
 
-class Translate implements \Magento\Framework\Phrase\RendererInterface
+use Magento\Framework\Phrase\RendererInterface;
+use Magento\Framework\TranslateInterface;
+use Psr\Log\LoggerInterface;
+
+class Translate implements RendererInterface
 {
     /**
      * @var \Magento\Framework\TranslateInterface
      */
     protected $translator;
 
+    /**
+     * @var \Psr\Log\LoggerInterface
+     */
+    protected $logger;
+
     /**
      * Renderer construct
      *
      * @param \Magento\Framework\TranslateInterface $translator
+     * @param \Psr\Log\LoggerInterface $logger
      */
-    public function __construct(\Magento\Framework\TranslateInterface $translator)
-    {
+    public function __construct(
+        TranslateInterface $translator,
+        LoggerInterface $logger
+    ) {
         $this->translator = $translator;
+        $this->logger = $logger;
     }
 
     /**
@@ -30,12 +43,19 @@ class Translate implements \Magento\Framework\Phrase\RendererInterface
      * @param [] $source
      * @param [] $arguments
      * @return string
+     * @throws \Exception
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      */
     public function render(array $source, array $arguments)
     {
         $text = end($source);
 
-        $data = $this->translator->getData();
+        try {
+            $data = $this->translator->getData();
+        } catch (\Exception $e) {
+            $this->logger->critical($e->getMessage());
+            throw $e;
+        }
 
         return array_key_exists($text, $data) ? $data[$text] : $text;
     }
diff --git a/lib/internal/Magento/Framework/Phrase/Test/Unit/Renderer/CompositeTest.php b/lib/internal/Magento/Framework/Phrase/Test/Unit/Renderer/CompositeTest.php
index ebb58aeade6b561ed1216a06b92a3e7e3a9c635f..b3fccdee663776d2bebeb6622907a57c263bcb5f 100644
--- a/lib/internal/Magento/Framework/Phrase/Test/Unit/Renderer/CompositeTest.php
+++ b/lib/internal/Magento/Framework/Phrase/Test/Unit/Renderer/CompositeTest.php
@@ -77,4 +77,17 @@ class CompositeTest extends \PHPUnit_Framework_TestCase
 
         $this->assertEquals($resultAfterSecond, $this->object->render([$text], $arguments));
     }
+
+    public function testRenderException()
+    {
+        $message = 'something went wrong';
+        $exception = new \Exception($message);
+
+        $this->rendererOne->expects($this->once())
+            ->method('render')
+            ->willThrowException($exception);
+
+        $this->setExpectedException('Exception', $message);
+        $this->object->render(['text'], []);
+    }
 }
diff --git a/lib/internal/Magento/Framework/Phrase/Test/Unit/Renderer/InlineTest.php b/lib/internal/Magento/Framework/Phrase/Test/Unit/Renderer/InlineTest.php
index 59174a88a4e90dd8e97cce09d590eeab03eb6fce..68be45b7e99b7cb17065a5ed5208c3ece0a0cc38 100644
--- a/lib/internal/Magento/Framework/Phrase/Test/Unit/Renderer/InlineTest.php
+++ b/lib/internal/Magento/Framework/Phrase/Test/Unit/Renderer/InlineTest.php
@@ -8,28 +8,36 @@ namespace Magento\Framework\Phrase\Test\Unit\Renderer;
 class InlineTest extends \PHPUnit_Framework_TestCase
 {
     /**
-     * @var \Magento\Framework\TranslateInterface
+     * @var \Magento\Framework\TranslateInterface|\PHPUnit_Framework_MockObject_MockObject
      */
     protected $translator;
 
     /**
      * @var \Magento\Framework\Phrase\Renderer\Translate
      */
-    protected $_renderer;
+    protected $renderer;
 
     /**
-     * @var \Magento\Framework\Translate\Inline\ProviderInterface
+     * @var \Magento\Framework\Translate\Inline\ProviderInterface|\PHPUnit_Framework_MockObject_MockObject
      */
     protected $provider;
 
+    /**
+     * @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $loggerMock;
+
     protected function setUp()
     {
         $this->translator = $this->getMock('Magento\Framework\TranslateInterface', [], [], '', false);
         $this->provider = $this->getMock('Magento\Framework\Translate\Inline\ProviderInterface', [], [], '', false);
+        $this->loggerMock = $this->getMockBuilder('Psr\Log\LoggerInterface')
+            ->getMock();
 
         $this->renderer = new \Magento\Framework\Phrase\Renderer\Inline(
             $this->translator,
-            $this->provider
+            $this->provider,
+            $this->loggerMock
         );
     }
 
@@ -70,4 +78,17 @@ class InlineTest extends \PHPUnit_Framework_TestCase
 
         $this->assertEquals($text, $this->renderer->render([$text], []));
     }
+
+    public function testRenderException()
+    {
+        $message = 'something went wrong';
+        $exception = new \Exception($message);
+
+        $this->provider->expects($this->once())
+            ->method('get')
+            ->willThrowException($exception);
+
+        $this->setExpectedException('Exception', $message);
+        $this->renderer->render(['text'], []);
+    }
 }
diff --git a/lib/internal/Magento/Framework/Phrase/Test/Unit/Renderer/TranslateTest.php b/lib/internal/Magento/Framework/Phrase/Test/Unit/Renderer/TranslateTest.php
index 61d541127514c236838f4cb0e7ad01f0c8491c1a..e6581ae4825ed7d39bc43d47f4761fa2fbb3e60d 100644
--- a/lib/internal/Magento/Framework/Phrase/Test/Unit/Renderer/TranslateTest.php
+++ b/lib/internal/Magento/Framework/Phrase/Test/Unit/Renderer/TranslateTest.php
@@ -17,14 +17,24 @@ class TranslateTest extends \PHPUnit_Framework_TestCase
      */
     protected $_renderer;
 
+    /**
+     * @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $loggerMock;
+
     protected function setUp()
     {
         $this->_translator = $this->getMock('Magento\Framework\TranslateInterface', [], [], '', false);
+        $this->loggerMock = $this->getMockBuilder('Psr\Log\LoggerInterface')
+            ->getMock();
 
         $objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
         $this->_renderer = $objectManagerHelper->getObject(
             'Magento\Framework\Phrase\Renderer\Translate',
-            ['translator' => $this->_translator]
+            [
+                'translator' => $this->_translator,
+                'logger' => $this->loggerMock
+            ]
         );
     }
 
@@ -41,4 +51,17 @@ class TranslateTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals($translate, $this->_renderer->render([$translatedText], []));
         $this->assertEquals($text, $this->_renderer->render([$text], []));
     }
+
+    public function testRenderException()
+    {
+        $message = 'something went wrong';
+        $exception = new \Exception($message);
+
+        $this->_translator->expects($this->once())
+            ->method('getData')
+            ->willThrowException($exception);
+
+        $this->setExpectedException('Exception', $message);
+        $this->_renderer->render(['text'], []);
+    }
 }
diff --git a/lib/internal/Magento/Framework/Pricing/PriceCurrencyInterface.php b/lib/internal/Magento/Framework/Pricing/PriceCurrencyInterface.php
index 9a0c8b2925b027ea2f72dfe536820fe2d3888181..980a8ff079c9b6f7c369099d801144ada04fdcee 100644
--- a/lib/internal/Magento/Framework/Pricing/PriceCurrencyInterface.php
+++ b/lib/internal/Magento/Framework/Pricing/PriceCurrencyInterface.php
@@ -89,4 +89,11 @@ interface PriceCurrencyInterface
      * @return \Magento\Framework\Model\AbstractModel
      */
     public function getCurrency($scope = null, $currency = null);
+
+    /**
+     * @param null|string|bool|int|\Magento\Framework\App\ScopeInterface $scope
+     * @param \Magento\Framework\Model\AbstractModel|string|null $currency
+     * @return string
+     */
+    public function getCurrencySymbol($scope = null, $currency = null);
 }
diff --git a/lib/internal/Magento/Framework/Pricing/Render/Amount.php b/lib/internal/Magento/Framework/Pricing/Render/Amount.php
index f58510aaf55fcbe87f23b80bcd733fcd614117de..a17c6d08af4c5bf66afd4e9832f5b237c9858ba7 100644
--- a/lib/internal/Magento/Framework/Pricing/Render/Amount.php
+++ b/lib/internal/Magento/Framework/Pricing/Render/Amount.php
@@ -142,6 +142,14 @@ class Amount extends Template implements AmountRenderInterface
         return $this->priceCurrency->getCurrency()->getCurrencyCode();
     }
 
+    /**
+     * @return string
+     */
+    public function getDisplayCurrencySymbol()
+    {
+        return $this->priceCurrency->getCurrencySymbol();
+    }
+
     /**
      * @return bool
      */
diff --git a/lib/internal/Magento/Framework/Pricing/Render/AmountRenderInterface.php b/lib/internal/Magento/Framework/Pricing/Render/AmountRenderInterface.php
index 66d0dc84a169876c2a7b025697b75fd93194eb4d..3779c69dd31ca6781a6a75b44f78c907518640df 100644
--- a/lib/internal/Magento/Framework/Pricing/Render/AmountRenderInterface.php
+++ b/lib/internal/Magento/Framework/Pricing/Render/AmountRenderInterface.php
@@ -50,6 +50,11 @@ interface AmountRenderInterface
      */
     public function getDisplayCurrencyCode();
 
+    /**
+     * @return string
+     */
+    public function getDisplayCurrencySymbol();
+
     /**
      * @return string
      */
diff --git a/lib/internal/Magento/Framework/Pricing/Test/Unit/Render/AmountTest.php b/lib/internal/Magento/Framework/Pricing/Test/Unit/Render/AmountTest.php
index 552cee4846656bd5fcdc6ce7d996bcadc0cb9535..fbf8d4f834f2fb7b1cc54af8ac75c6aad527c174 100644
--- a/lib/internal/Magento/Framework/Pricing/Test/Unit/Render/AmountTest.php
+++ b/lib/internal/Magento/Framework/Pricing/Test/Unit/Render/AmountTest.php
@@ -127,6 +127,15 @@ class AmountTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals($result, $this->model->formatCurrency($amount, $includeContainer, $precision));
     }
 
+    public function testGetDisplayCurrencySymbol()
+    {
+        $currencySymbol = '$';
+        $this->priceCurrency->expects($this->once())
+            ->method('getCurrencySymbol')
+            ->willReturn($currencySymbol);
+        $this->assertEquals($currencySymbol, $this->model->getDisplayCurrencySymbol());
+    }
+
     /**
      * Test case for getAdjustmentRenders method through toHtml()
      */
diff --git a/lib/internal/Magento/Framework/Reflection/AttributeTypeResolver.php b/lib/internal/Magento/Framework/Reflection/AttributeTypeResolver.php
index 8552cba5a5d2458014a60e259857fc5c01becf90..6824dca09e58c813d114dba3f3c720dad27a710d 100644
--- a/lib/internal/Magento/Framework/Reflection/AttributeTypeResolver.php
+++ b/lib/internal/Magento/Framework/Reflection/AttributeTypeResolver.php
@@ -44,7 +44,7 @@ class AttributeTypeResolver implements AttributeTypeResolverInterface
         $config = isset($data[$context]) ? $data[$context] : [];
         $output = get_class($value);
         if (isset($config[$attributeCode])) {
-            $type = $config[$attributeCode];
+            $type = $config[$attributeCode]['type'];
             $output = $this->typeProcessor->getArrayItemType($type);
             if (!(class_exists($output) || interface_exists($output))) {
                 throw new \LogicException(
diff --git a/lib/internal/Magento/Framework/Reflection/CustomAttributesProcessor.php b/lib/internal/Magento/Framework/Reflection/CustomAttributesProcessor.php
new file mode 100644
index 0000000000000000000000000000000000000000..0a98c9e39e8c2f135b962bfbf0ef51d44924c183
--- /dev/null
+++ b/lib/internal/Magento/Framework/Reflection/CustomAttributesProcessor.php
@@ -0,0 +1,99 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Framework\Reflection;
+
+use Magento\Framework\Phrase;
+use Magento\Framework\Api\AttributeInterface;
+use Magento\Framework\Api\AttributeValue;
+use Magento\Framework\Api\SimpleDataObjectConverter;
+use Zend\Code\Reflection\MethodReflection;
+use Magento\Framework\Api\CustomAttributesDataInterface;
+use Magento\Framework\Api\AttributeTypeResolverInterface;
+
+/**
+ * Processes custom attributes and produces an array for the data.
+ */
+class CustomAttributesProcessor
+{
+    /**
+     * @var DataObjectProcessor
+     */
+    private $dataObjectProcessor;
+
+    /**
+     * @var AttributeTypeResolverInterface
+     */
+    private $attributeTypeResolver;
+
+    /**
+     * @param DataObjectProcessor $dataObjectProcessor
+     * @param AttributeTypeResolverInterface $typeResolver
+     */
+    public function __construct(
+        DataObjectProcessor $dataObjectProcessor,
+        AttributeTypeResolverInterface $typeResolver
+    ) {
+        $this->dataObjectProcessor = $dataObjectProcessor;
+        $this->attributeTypeResolver = $typeResolver;
+    }
+
+    /**
+     * Writes out the custom attributes for a given object into an array.
+     *
+     * @param CustomAttributesDataInterface $objectWithCustomAttributes
+     * @param string $dataObjectType
+     * @return array
+     */
+    public function buildOutputDataArray(CustomAttributesDataInterface $objectWithCustomAttributes, $dataObjectType)
+    {
+        $customAttributes = $objectWithCustomAttributes->getCustomAttributes();
+        $result = [];
+        foreach ($customAttributes as $customAttribute) {
+            $result[] = $this->convertCustomAttribute($customAttribute, $dataObjectType);
+        }
+        return $result;
+    }
+
+    /**
+     * Convert custom_attribute object to use flat array structure
+     *
+     * @param AttributeInterface $customAttribute
+     * @param string $dataObjectType
+     * @return array
+     */
+    private function convertCustomAttribute(AttributeInterface $customAttribute, $dataObjectType)
+    {
+        $data = [];
+        $data[AttributeValue::ATTRIBUTE_CODE] = $customAttribute->getAttributeCode();
+        $value = $customAttribute->getValue();
+        if (is_object($value)) {
+            $type = $this->attributeTypeResolver->resolveObjectType(
+                $customAttribute->getAttributeCode(),
+                $value,
+                $dataObjectType
+            );
+            $value = $this->dataObjectProcessor->buildOutputDataArray($value, $type);
+        } elseif (is_array($value)) {
+            $valueResult = [];
+            foreach ($value as $singleValue) {
+                if (is_object($singleValue)) {
+                    $type = $this->attributeTypeResolver->resolveObjectType(
+                        $customAttribute->getAttributeCode(),
+                        $singleValue,
+                        $dataObjectType
+                    );
+                    $singleValue = $this->dataObjectProcessor->buildOutputDataArray($singleValue, $type);
+                }
+                // Cannot cast to a type because the type is unknown
+                $valueResult[] = $singleValue;
+            }
+            $value = $valueResult;
+        }
+        $data[AttributeValue::VALUE] = $value;
+        return $data;
+    }
+}
diff --git a/lib/internal/Magento/Framework/Reflection/DataObjectProcessor.php b/lib/internal/Magento/Framework/Reflection/DataObjectProcessor.php
index 2b9977d7355f565e808b15cc539c7c892f38afa6..4adceb83c7720be26a310fe8d7dea3f19726219c 100644
--- a/lib/internal/Magento/Framework/Reflection/DataObjectProcessor.php
+++ b/lib/internal/Magento/Framework/Reflection/DataObjectProcessor.php
@@ -14,54 +14,54 @@ use Zend\Code\Reflection\ClassReflection;
 use Zend\Code\Reflection\MethodReflection;
 
 /**
- * Data object processor for de-serialization using class reflection
+ * Data object processor for array serialization using class reflection
  */
 class DataObjectProcessor
 {
-    const IS_METHOD_PREFIX = 'is';
-    const HAS_METHOD_PREFIX = 'has';
-    const GETTER_PREFIX = 'get';
-    const SERVICE_INTERFACE_METHODS_CACHE_PREFIX = 'serviceInterfaceMethodsMap';
-    const BASE_MODEL_CLASS = 'Magento\Framework\Model\AbstractExtensibleModel';
-
     /**
-     * @var \Magento\Framework\Cache\FrontendInterface
+     * @var MethodsMap
      */
-    protected $cache;
+    private $methodsMapProcessor;
 
     /**
-     * @var TypeProcessor
+     * @var TypeCaster
      */
-    protected $typeProcessor;
+    private $typeCaster;
 
     /**
-     * @var array
+     * @var FieldNamer
      */
-    protected $dataInterfaceMethodsMap = [];
+    private $fieldNamer;
 
     /**
-     * @var array
+     * @var ExtensionAttributesProcessor
      */
-    protected $serviceInterfaceMethodsMap = [];
+    private $extensionAttributesProcessor;
 
     /**
-     * @var \Magento\Framework\Api\AttributeTypeResolverInterface
+     * @var CustomAttributesProcessor
      */
-    protected $attributeTypeResolver;
+    private $customAttributesProcessor;
 
     /**
-     * @param \Magento\Framework\Cache\FrontendInterface $cache
-     * @param TypeProcessor $typeProcessor
-     * @param \Magento\Framework\Api\AttributeTypeResolverInterface $typeResolver
+     * @param MethodsMap $methodsMapProcessor
+     * @param TypeCaster $typeCaster
+     * @param FieldNamer $fieldNamer
+     * @param CustomAttributesProcessor $customAttributesProcessor
+     * @param ExtensionAttributesProcessor $extensionAttributesProcessor
      */
     public function __construct(
-        \Magento\Framework\Cache\FrontendInterface $cache,
-        TypeProcessor $typeProcessor,
-        \Magento\Framework\Api\AttributeTypeResolverInterface $typeResolver
+        MethodsMap $methodsMapProcessor,
+        TypeCaster $typeCaster,
+        FieldNamer $fieldNamer,
+        CustomAttributesProcessor $customAttributesProcessor,
+        ExtensionAttributesProcessor $extensionAttributesProcessor
     ) {
-        $this->cache = $cache;
-        $this->typeProcessor = $typeProcessor;
-        $this->attributeTypeResolver = $typeResolver;
+        $this->methodsMapProcessor = $methodsMapProcessor;
+        $this->typeCaster = $typeCaster;
+        $this->fieldNamer = $fieldNamer;
+        $this->extensionAttributesProcessor = $extensionAttributesProcessor;
+        $this->customAttributesProcessor = $customAttributesProcessor;
     }
 
     /**
@@ -74,43 +74,36 @@ class DataObjectProcessor
      */
     public function buildOutputDataArray($dataObject, $dataObjectType)
     {
-        $methods = $this->getMethodsMap($dataObjectType);
+        $methods = $this->methodsMapProcessor->getMethodsMap($dataObjectType);
         $outputData = [];
 
         /** @var MethodReflection $method */
-        foreach ($methods as $methodName => $methodReflectionData) {
-            // any method with parameter(s) gets ignored because we do not know the type and value of
-            // the parameter(s), so we are not able to process
-            if ($methodReflectionData['parameterCount'] > 0) {
+        foreach (array_keys($methods) as $methodName) {
+            if (!$this->methodsMapProcessor->isMethodValidForDataField($dataObjectType, $methodName)) {
                 continue;
             }
-            $returnType = $methodReflectionData['type'];
-            if (substr($methodName, 0, 2) === self::IS_METHOD_PREFIX) {
-                $value = $dataObject->{$methodName}();
-                if ($value === null && !$methodReflectionData['isRequired']) {
-                    continue;
-                }
-                $key = SimpleDataObjectConverter::camelCaseToSnakeCase(substr($methodName, 2));
-                $outputData[$key] = $this->castValueToType($value, $returnType);
-            } elseif (substr($methodName, 0, 3) === self::HAS_METHOD_PREFIX) {
-                $value = $dataObject->{$methodName}();
-                if ($value === null && !$methodReflectionData['isRequired']) {
-                    continue;
-                }
-                $key = SimpleDataObjectConverter::camelCaseToSnakeCase(substr($methodName, 3));
-                $outputData[$key] = $this->castValueToType($value, $returnType);
-            } elseif (substr($methodName, 0, 3) === self::GETTER_PREFIX) {
-                $value = $dataObject->{$methodName}();
-                if ($methodName === 'getCustomAttributes' && $value === []) {
-                    continue;
-                }
-                if ($value === null && !$methodReflectionData['isRequired']) {
-                    continue;
-                }
-                $key = SimpleDataObjectConverter::camelCaseToSnakeCase(substr($methodName, 3));
-                if ($key === CustomAttributesDataInterface::CUSTOM_ATTRIBUTES) {
-                    $value = $this->convertCustomAttributes($value, $dataObjectType);
-                } elseif (is_object($value) && !($value instanceof Phrase)) {
+
+            $value = $dataObject->{$methodName}();
+            $isMethodReturnValueRequired = $this->methodsMapProcessor->isMethodReturnValueRequired(
+                $dataObjectType,
+                $methodName
+            );
+            if ($value === null && !$isMethodReturnValueRequired) {
+                continue;
+            }
+
+            $returnType = $this->methodsMapProcessor->getMethodReturnType($dataObjectType, $methodName);
+            $key = $this->fieldNamer->getFieldNameForMethodName($methodName);
+            if ($key === CustomAttributesDataInterface::CUSTOM_ATTRIBUTES && $value === []) {
+                continue;
+            }
+
+            if ($key === CustomAttributesDataInterface::CUSTOM_ATTRIBUTES) {
+                $value = $this->customAttributesProcessor->buildOutputDataArray($dataObject, $dataObjectType);
+            } elseif ($key === "extension_attributes") {
+                $value = $this->extensionAttributesProcessor->buildOutputDataArray($value, $returnType);
+            } else {
+                if (is_object($value) && !($value instanceof Phrase)) {
                     $value = $this->buildOutputDataArray($value, $returnType);
                 } elseif (is_array($value)) {
                     $valueResult = [];
@@ -119,192 +112,16 @@ class DataObjectProcessor
                         if (is_object($singleValue) && !($singleValue instanceof Phrase)) {
                             $singleValue = $this->buildOutputDataArray($singleValue, $arrayElementType);
                         }
-                        $valueResult[] = $this->castValueToType($singleValue, $arrayElementType);
+                        $valueResult[] = $this->typeCaster->castValueToType($singleValue, $arrayElementType);
                     }
                     $value = $valueResult;
+                } else {
+                    $value = $this->typeCaster->castValueToType($value, $returnType);
                 }
-                $outputData[$key] = $this->castValueToType($value, $returnType);
             }
-        }
-        return $outputData;
-    }
 
-    /**
-     * Cast the output type to the documented type. This helps for output purposes.
-     *
-     * @param mixed $value
-     * @param string $type
-     * @return mixed
-     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
-     * @SuppressWarnings(PHPMD.NPathComplexity)
-     */
-    protected function castValueToType($value, $type)
-    {
-        if ($value === null) {
-            return null;
+            $outputData[$key] = $value;
         }
-
-        if ($type === "int" || $type === "integer") {
-            return (int)$value;
-        }
-
-        if ($type === "string") {
-            return (string)$value;
-        }
-
-        if ($type === "bool" || $type === "boolean" || $type === "true" || $type == "false") {
-            return (bool)$value;
-        }
-
-        if ($type === "float") {
-            return (float)$value;
-        }
-
-        if ($type === "double") {
-            return (double)$value;
-        }
-
-        return $value;
-    }
-
-    /**
-     * Get return type by interface name and method
-     *
-     * @param string $interfaceName
-     * @param string $methodName
-     * @return string
-     */
-    public function getMethodReturnType($interfaceName, $methodName)
-    {
-        return $this->getMethodsMap($interfaceName)[$methodName]['type'];
-    }
-
-    /**
-     * Convert array of custom_attributes to use flat array structure
-     *
-     * @param \Magento\Framework\Api\AttributeInterface[] $customAttributes
-     * @param string $dataObjectType
-     * @return array
-     */
-    protected function convertCustomAttributes($customAttributes, $dataObjectType)
-    {
-        $result = [];
-        foreach ((array)$customAttributes as $customAttribute) {
-            $result[] = $this->convertCustomAttribute($customAttribute, $dataObjectType);
-        }
-        return $result;
-    }
-
-    /**
-     * Convert custom_attribute object to use flat array structure
-     *
-     * @param \Magento\Framework\Api\AttributeInterface $customAttribute
-     * @param string $dataObjectType
-     * @return array
-     */
-    protected function convertCustomAttribute($customAttribute, $dataObjectType)
-    {
-        $data = [];
-        $data[AttributeValue::ATTRIBUTE_CODE] = $customAttribute->getAttributeCode();
-        $value = $customAttribute->getValue();
-        if (is_object($value)) {
-            $type = $this->attributeTypeResolver->resolveObjectType(
-                $customAttribute->getAttributeCode(),
-                $value,
-                $dataObjectType
-            );
-            $value = $this->buildOutputDataArray($value, $type);
-        } elseif (is_array($value)) {
-            $valueResult = [];
-            foreach ($value as $singleValue) {
-                if (is_object($singleValue)) {
-                    $type = $this->attributeTypeResolver->resolveObjectType(
-                        $customAttribute->getAttributeCode(),
-                        $singleValue,
-                        $dataObjectType
-                    );
-                    $singleValue = $this->buildOutputDataArray($singleValue, $type);
-                }
-                // Cannot cast to a type because the type is unknown
-                $valueResult[] = $singleValue;
-            }
-            $value = $valueResult;
-        }
-        $data[AttributeValue::VALUE] = $value;
-        return $data;
-    }
-
-    /**
-     * Return service interface or Data interface methods loaded from cache
-     *
-     * @param string $interfaceName
-     * @return array
-     * <pre>
-     * Service methods' reflection data stored in cache as 'methodName' => 'returnType'
-     * ex.
-     * [
-     *  'create' => '\Magento\Customer\Api\Data\Customer',
-     *  'validatePassword' => 'boolean'
-     * ]
-     * </pre>
-     */
-    public function getMethodsMap($interfaceName)
-    {
-        $key = self::SERVICE_INTERFACE_METHODS_CACHE_PREFIX . "-" . md5($interfaceName);
-        if (!isset($this->serviceInterfaceMethodsMap[$key])) {
-            $methodMap = $this->cache->load($key);
-            if ($methodMap) {
-                $this->serviceInterfaceMethodsMap[$key] = unserialize($methodMap);
-            } else {
-                $methodMap = $this->getMethodMapViaReflection($interfaceName);
-                $this->serviceInterfaceMethodsMap[$key] = $methodMap;
-                $this->cache->save(serialize($this->serviceInterfaceMethodsMap[$key]), $key);
-            }
-        }
-        return $this->serviceInterfaceMethodsMap[$key];
-    }
-
-    /**
-     * Use reflection to load the method information
-     *
-     * @param string $interfaceName
-     * @return array
-     */
-    protected function getMethodMapViaReflection($interfaceName)
-    {
-        $methodMap = [];
-        $class = new ClassReflection($interfaceName);
-        $baseClassMethods = false;
-        foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) {
-            // Include all the methods of classes inheriting from AbstractExtensibleObject.
-            // Ignore all the methods of AbstractExtensibleModel's parent classes
-            if ($method->class === self::BASE_MODEL_CLASS) {
-                $baseClassMethods = true;
-            } elseif ($baseClassMethods) {
-                // ReflectionClass::getMethods() sorts the methods by class (lowest in inheritance tree first)
-                // then by the order they are defined in the class definition
-                break;
-            }
-
-            if ($this->isSuitableMethod($method)) {
-                $methodMap[$method->getName()] = $this->typeProcessor->getGetterReturnType($method);
-            }
-        }
-        return $methodMap;
-    }
-
-    /**
-     * Determines if the method is suitable to be used by the processor.
-     *
-     * @param \ReflectionMethod $method
-     * @return bool
-     */
-    protected function isSuitableMethod($method)
-    {
-        $isSuitableMethodType = !($method->isConstructor() || $method->isFinal()
-            || $method->isStatic() || $method->isDestructor());
-
-        $isExcludedMagicMethod = strpos($method->getName(), '__') === 0;
-        return $isSuitableMethodType && !$isExcludedMagicMethod;
+        return $outputData;
     }
 }
diff --git a/lib/internal/Magento/Framework/Reflection/ExtensionAttributesProcessor.php b/lib/internal/Magento/Framework/Reflection/ExtensionAttributesProcessor.php
new file mode 100644
index 0000000000000000000000000000000000000000..c2d2d69c758f8b4676da91027080fb5736d5c880
--- /dev/null
+++ b/lib/internal/Magento/Framework/Reflection/ExtensionAttributesProcessor.php
@@ -0,0 +1,189 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Framework\Reflection;
+
+use Magento\Framework\Api\Config\Reader as ExtensionAttributesConfigReader;
+use Magento\Framework\Api\Config\Converter;
+use Magento\Framework\AuthorizationInterface;
+use Magento\Framework\Phrase;
+use Magento\Framework\Api\SimpleDataObjectConverter;
+use Magento\Framework\Api\ExtensionAttributesInterface;
+use Magento\Framework\Reflection\MethodsMap;
+use Zend\Code\Reflection\MethodReflection;
+
+/**
+ * Processes extension attributes and produces an array for the data.
+ */
+class ExtensionAttributesProcessor
+{
+    /**
+     * @var DataObjectProcessor
+     */
+    private $dataObjectProcessor;
+
+    /**
+     * @var MethodsMap
+     */
+    private $methodsMapProcessor;
+
+    /**
+     * @var AuthorizationInterface
+     */
+    private $authorization;
+
+    /**
+     * @var ExtensionAttributesConfigReader
+     */
+    private $configReader;
+
+    /**
+     * @var bool
+     */
+    private $isPermissionChecked;
+
+    /**
+     * @var FieldNamer
+     */
+    private $fieldNamer;
+
+    /**
+     * @var TypeCaster
+     */
+    private $typeCaster;
+
+    /**
+     * @param DataObjectProcessor $dataObjectProcessor
+     * @param MethodsMap $methodsMapProcessor
+     * @param TypeCaster $typeCaster
+     * @param FieldNamer $fieldNamer
+     * @param AuthorizationInterface $authorization
+     * @param ExtensionAttributesConfigReader $configReader
+     * @param bool $isPermissionChecked
+     */
+    public function __construct(
+        DataObjectProcessor $dataObjectProcessor,
+        MethodsMap $methodsMapProcessor,
+        TypeCaster $typeCaster,
+        FieldNamer $fieldNamer,
+        AuthorizationInterface $authorization,
+        ExtensionAttributesConfigReader $configReader,
+        $isPermissionChecked = false
+    ) {
+        $this->dataObjectProcessor = $dataObjectProcessor;
+        $this->methodsMapProcessor = $methodsMapProcessor;
+        $this->typeCaster = $typeCaster;
+        $this->fieldNamer = $fieldNamer;
+        $this->authorization = $authorization;
+        $this->configReader = $configReader;
+        $this->isPermissionChecked = $isPermissionChecked;
+    }
+
+    /**
+     * Writes out the extension attributes in an array.
+     *
+     * @param ExtensionAttributeInterface $dataObject
+     * @param string $dataObjectType
+     * @return array
+     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+     */
+    public function buildOutputDataArray(ExtensionAttributesInterface $dataObject, $dataObjectType)
+    {
+        $methods = $this->methodsMapProcessor->getMethodsMap($dataObjectType);
+        $outputData = [];
+
+        /** @var MethodReflection $method */
+        foreach (array_keys($methods) as $methodName) {
+            if (!$this->methodsMapProcessor->isMethodValidForDataField($dataObjectType, $methodName)) {
+                continue;
+            }
+
+            $key = $this->fieldNamer->getFieldNameForMethodName($methodName);
+            if ($this->isPermissionChecked && !$this->isAttributePermissionValid($dataObjectType, $key)) {
+                continue;
+            }
+
+            $value = $dataObject->{$methodName}();
+            if ($value === null) {
+                // all extension attributes are optional so don't need to check if isRequired
+                continue;
+            }
+
+            $returnType = $this->methodsMapProcessor->getMethodReturnType($dataObjectType, $methodName);
+
+            if (is_object($value) && !($value instanceof Phrase)) {
+                $value = $this->dataObjectProcessor->buildOutputDataArray($value, $returnType);
+            } elseif (is_array($value)) {
+                $valueResult = [];
+                $arrayElementType = substr($returnType, 0, -2);
+                foreach ($value as $singleValue) {
+                    if (is_object($singleValue) && !($singleValue instanceof Phrase)) {
+                        $singleValue = $this->dataObjectProcessor->buildOutputDataArray(
+                            $singleValue,
+                            $arrayElementType
+                        );
+                    }
+                    $valueResult[] = $this->typeCaster->castValueToType($singleValue, $arrayElementType);
+                }
+                $value = $valueResult;
+            } else {
+                $value = $this->typeCaster->castValueToType($value, $returnType);
+            }
+
+            $outputData[$key] = $value;
+        }
+
+        return $outputData;
+    }
+
+    /**
+     * @param string $dataObjectType
+     * @param string $attributeCode
+     * @return bool
+     */
+    private function isAttributePermissionValid($dataObjectType, $attributeCode)
+    {
+        $typeName = $this->getRegularTypeForExtensionAttributesType($dataObjectType);
+        $permissions = $this->getPermissionsForTypeAndMethod($typeName, $attributeCode);
+        foreach ($permissions as $permission) {
+            if (!$this->authorization->isAllowed($permission)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * @param string $name
+     * @return string
+     */
+    private function getRegularTypeForExtensionAttributesType($name)
+    {
+        return ltrim(str_replace('ExtensionInterface', 'Interface', $name), '\\');
+    }
+
+    /**
+     * @param string $typeName
+     * @param string $attributeCode
+     * @return string[] A list of permissions
+     */
+    private function getPermissionsForTypeAndMethod($typeName, $attributeCode)
+    {
+        // TODO: Move function to the Config and hope this is cached
+        $attributes = $this->configReader->read();
+        if (isset($attributes[$typeName]) && isset($attributes[$typeName][$attributeCode])) {
+            $attributeMetadata = $attributes[$typeName][$attributeCode];
+            $permissions = [];
+            foreach ($attributeMetadata[Converter::RESOURCE_PERMISSIONS] as $permission) {
+                $permissions[] = $permission;
+            }
+            return $permissions;
+        }
+
+        return [];
+    }
+}
diff --git a/lib/internal/Magento/Framework/Reflection/FieldNamer.php b/lib/internal/Magento/Framework/Reflection/FieldNamer.php
new file mode 100644
index 0000000000000000000000000000000000000000..2e105b9a4f666e2073124e8817a9208762740389
--- /dev/null
+++ b/lib/internal/Magento/Framework/Reflection/FieldNamer.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Framework\Reflection;
+
+use Magento\Framework\Phrase;
+use Magento\Framework\Api\AttributeValue;
+use Magento\Framework\Api\CustomAttributesDataInterface;
+use Magento\Framework\Api\SimpleDataObjectConverter;
+use Zend\Code\Reflection\ClassReflection;
+use Zend\Code\Reflection\MethodReflection;
+
+/**
+ * Determines the name to use for fields in a data output array given method metadata.
+ */
+class FieldNamer
+{
+    const IS_METHOD_PREFIX = 'is';
+    const HAS_METHOD_PREFIX = 'has';
+    const GETTER_PREFIX = 'get';
+    
+    /**
+     * Converts a method's name into a data field name.
+     *
+     * @param string $methodName
+     * @return string|null
+     */
+    public function getFieldNameForMethodName($methodName)
+    {
+        if (substr($methodName, 0, 2) === self::IS_METHOD_PREFIX) {
+            return SimpleDataObjectConverter::camelCaseToSnakeCase(substr($methodName, 2));
+        } elseif (substr($methodName, 0, 3) === self::HAS_METHOD_PREFIX) {
+            return SimpleDataObjectConverter::camelCaseToSnakeCase(substr($methodName, 3));
+        } elseif (substr($methodName, 0, 3) === self::GETTER_PREFIX) {
+            return SimpleDataObjectConverter::camelCaseToSnakeCase(substr($methodName, 3));
+        }
+
+        return null;
+    }
+}
diff --git a/lib/internal/Magento/Framework/Reflection/MethodsMap.php b/lib/internal/Magento/Framework/Reflection/MethodsMap.php
new file mode 100644
index 0000000000000000000000000000000000000000..36b446d1b870a32d6f468bf77b293a63b024fabe
--- /dev/null
+++ b/lib/internal/Magento/Framework/Reflection/MethodsMap.php
@@ -0,0 +1,180 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Framework\Reflection;
+
+use Zend\Code\Reflection\ClassReflection;
+use Zend\Code\Reflection\MethodReflection;
+
+/**
+ * Gathers method metadata information.
+ */
+class MethodsMap
+{
+    const SERVICE_INTERFACE_METHODS_CACHE_PREFIX = 'serviceInterfaceMethodsMap';
+    const BASE_MODEL_CLASS = 'Magento\Framework\Model\AbstractExtensibleModel';
+
+    /**
+     * @var \Magento\Framework\Cache\FrontendInterface
+     */
+    private $cache;
+
+    /**
+     * @var TypeProcessor
+     */
+    private $typeProcessor;
+
+    /**
+     * @var array
+     */
+    private $serviceInterfaceMethodsMap = [];
+
+    /**
+     * @var FieldNamer
+     */
+    private $fieldNamer;
+
+    /**
+     * @param \Magento\Framework\Cache\FrontendInterface $cache
+     * @param TypeProcessor $typeProcessor
+     * @param \Magento\Framework\Api\AttributeTypeResolverInterface $typeResolver
+     * @param FieldNamer $fieldNamer
+     */
+    public function __construct(
+        \Magento\Framework\Cache\FrontendInterface $cache,
+        TypeProcessor $typeProcessor,
+        \Magento\Framework\Api\AttributeTypeResolverInterface $typeResolver,
+        FieldNamer $fieldNamer
+    ) {
+        $this->cache = $cache;
+        $this->typeProcessor = $typeProcessor;
+        $this->attributeTypeResolver = $typeResolver;
+        $this->fieldNamer = $fieldNamer;
+    }
+
+    /**
+     * Get return type by type name and method name.
+     *
+     * @param string $typeName
+     * @param string $methodName
+     * @return string
+     */
+    public function getMethodReturnType($typeName, $methodName)
+    {
+        return $this->getMethodsMap($typeName)[$methodName]['type'];
+    }
+
+    /**
+     * Return service interface or Data interface methods loaded from cache
+     *
+     * @param string $interfaceName
+     * @return array
+     * <pre>
+     * Service methods' reflection data stored in cache as 'methodName' => 'returnType'
+     * ex.
+     * [
+     *  'create' => '\Magento\Customer\Api\Data\Customer',
+     *  'validatePassword' => 'boolean'
+     * ]
+     * </pre>
+     */
+    public function getMethodsMap($interfaceName)
+    {
+        $key = self::SERVICE_INTERFACE_METHODS_CACHE_PREFIX . "-" . md5($interfaceName);
+        if (!isset($this->serviceInterfaceMethodsMap[$key])) {
+            $methodMap = $this->cache->load($key);
+            if ($methodMap) {
+                $this->serviceInterfaceMethodsMap[$key] = unserialize($methodMap);
+            } else {
+                $methodMap = $this->getMethodMapViaReflection($interfaceName);
+                $this->serviceInterfaceMethodsMap[$key] = $methodMap;
+                $this->cache->save(serialize($this->serviceInterfaceMethodsMap[$key]), $key);
+            }
+        }
+        return $this->serviceInterfaceMethodsMap[$key];
+    }
+
+    /**
+     * Use reflection to load the method information
+     *
+     * @param string $interfaceName
+     * @return array
+     */
+    private function getMethodMapViaReflection($interfaceName)
+    {
+        $methodMap = [];
+        $class = new ClassReflection($interfaceName);
+        $baseClassMethods = false;
+        foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) {
+            // Include all the methods of classes inheriting from AbstractExtensibleObject.
+            // Ignore all the methods of AbstractExtensibleModel's parent classes
+            if ($method->class === self::BASE_MODEL_CLASS) {
+                $baseClassMethods = true;
+            } elseif ($baseClassMethods) {
+                // ReflectionClass::getMethods() sorts the methods by class (lowest in inheritance tree first)
+                // then by the order they are defined in the class definition
+                break;
+            }
+
+            if ($this->isSuitableMethod($method)) {
+                $methodMap[$method->getName()] = $this->typeProcessor->getGetterReturnType($method);
+            }
+        }
+        return $methodMap;
+    }
+
+    /**
+     * Determines if the method is suitable to be used by the processor.
+     *
+     * @param \ReflectionMethod $method
+     * @return bool
+     */
+    private function isSuitableMethod($method)
+    {
+        $isSuitableMethodType = !($method->isConstructor() || $method->isFinal()
+            || $method->isStatic() || $method->isDestructor());
+
+        $isExcludedMagicMethod = strpos($method->getName(), '__') === 0;
+        return $isSuitableMethodType && !$isExcludedMagicMethod;
+    }
+
+    /**
+     * Determines if the given method's on the given type is suitable for an output data array.
+     *
+     * @param string $type
+     * @param string $methodName
+     * @return bool
+     */
+    public function isMethodValidForDataField($type, $methodName)
+    {
+        $methods = $this->getMethodsMap($type);
+        if (isset($methods[$methodName])) {
+            $methodMetadata = $methods[$methodName];
+            // any method with parameter(s) gets ignored because we do not know the type and value of
+            // the parameter(s), so we are not able to process
+            if ($methodMetadata['parameterCount'] > 0) {
+                return false;
+            }
+
+            return $this->fieldNamer->getFieldNameForMethodName($methodName) !== null;
+        }
+
+        return false;
+    }
+
+    /**
+     * If the method has only non-null return types
+     *
+     * @param string $type
+     * @param string $methodName
+     * @return bool
+     */
+    public function isMethodReturnValueRequired($type, $methodName)
+    {
+        $methods = $this->getMethodsMap($type);
+        return $methods[$methodName]['isRequired'];
+    }
+}
diff --git a/lib/internal/Magento/Framework/Reflection/Test/Unit/AttributeTypeResolverTest.php b/lib/internal/Magento/Framework/Reflection/Test/Unit/AttributeTypeResolverTest.php
index 8391d4643482d17da3c717dbbc732b7c43002b19..68902f3851380d368c88ca8e2357bada00a2de7d 100644
--- a/lib/internal/Magento/Framework/Reflection/Test/Unit/AttributeTypeResolverTest.php
+++ b/lib/internal/Magento/Framework/Reflection/Test/Unit/AttributeTypeResolverTest.php
@@ -62,7 +62,13 @@ class AttributeTypeResolverTest extends \PHPUnit_Framework_TestCase
         $code = 'some_code';
         $value = new \stdClass();
         $context = '\Some\Class';
-        $config = ['Some\Class' => ['some_code' => '\Magento\Framework\Object']];
+        $config = [
+            'Some\Class' => [
+                'some_code' => [
+                    'type' => '\Magento\Framework\Object',
+                ],
+            ]
+        ];
 
         $this->typeProcessor->expects($this->once())
             ->method('getArrayItemType')
@@ -82,7 +88,13 @@ class AttributeTypeResolverTest extends \PHPUnit_Framework_TestCase
         $code = 'some_code';
         $value = new \stdClass();
         $context = '\Some\Class';
-        $config = ['Some\Class' => ['some_code' => '\Some\Class']];
+        $config = [
+            'Some\Class' => [
+                'some_code' => [
+                    'type' => '\Some\Class',
+                ]
+            ]
+        ];
 
         $this->typeProcessor->expects($this->once())
             ->method('getArrayItemType')
diff --git a/lib/internal/Magento/Framework/Reflection/Test/Unit/ExtensionAttributesObject.php b/lib/internal/Magento/Framework/Reflection/Test/Unit/ExtensionAttributesObject.php
new file mode 100644
index 0000000000000000000000000000000000000000..66077712a43b337238402748fe9ccf9c4b0db5f2
--- /dev/null
+++ b/lib/internal/Magento/Framework/Reflection/Test/Unit/ExtensionAttributesObject.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\Reflection\Test\Unit;
+
+use Magento\Framework\Api\ExtensionAttributesInterface;
+
+/**
+ * Dummy data object to be used by ExtensionAttributesProcessorTest
+ */
+class ExtensionAttributesObject implements ExtensionAttributesInterface
+{
+    /**
+     * @return string
+     */
+    public function getAttrName()
+    {
+        return 'attrName';
+    }
+
+    /**
+     * @return bool
+     */
+    public function isActive()
+    {
+        return false;
+    }
+}
diff --git a/lib/internal/Magento/Framework/Reflection/Test/Unit/ExtensionAttributesProcessorTest.php b/lib/internal/Magento/Framework/Reflection/Test/Unit/ExtensionAttributesProcessorTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..8da0c1f734f710da1c69d28c9e9f4ac02999db86
--- /dev/null
+++ b/lib/internal/Magento/Framework/Reflection/Test/Unit/ExtensionAttributesProcessorTest.php
@@ -0,0 +1,172 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Framework\Reflection\Test\Unit;
+
+use Magento\Framework\Api\Config\Converter;
+use Magento\Framework\Api\Config\Reader;
+use Magento\Framework\AuthorizationInterface;
+use Magento\Framework\Reflection\DataObjectProcessor;
+use Magento\Framework\Reflection\ExtensionAttributesProcessor;
+use Magento\Framework\Reflection\FieldNamer;
+use Magento\Framework\Reflection\MethodsMap;
+use Magento\Framework\Reflection\TypeCaster;
+
+/**
+ * ExtensionAttributesProcessor test
+ */
+class ExtensionAttributesProcessorTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var ExtensionAttributesProcessor
+     */
+    private $model;
+
+    /**
+     * @var DataObjectProcessor
+     */
+    private $dataObjectProcessorMock;
+
+    /**
+     * @var MethodsMap
+     */
+    private $methodsMapProcessorMock;
+
+    /**
+     * @var FieldNamer
+     */
+    private $fieldNamerMock;
+
+    /**
+     * @var TypeCaster
+     */
+    private $typeCasterMock;
+
+    /**
+     * @var Reader
+     */
+    private $configReaderMock;
+
+    /**
+     * @var AuthorizationInterface
+     */
+    private $authorizationMock;
+    /**
+     * Set up helper.
+     */
+    public function setUp()
+    {
+        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+
+        $this->dataObjectProcessorMock = $this->getMockBuilder('Magento\Framework\Reflection\DataObjectProcessor')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->methodsMapProcessorMock = $this->getMockBuilder('Magento\Framework\Reflection\MethodsMap')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->typeCasterMock = $this->getMockBuilder('Magento\Framework\Reflection\TypeCaster')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->fieldNamerMock = $this->getMockBuilder('Magento\Framework\Reflection\FieldNamer')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->configReaderMock = $this->getMockBuilder('Magento\Framework\Api\Config\Reader')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->authorizationMock = $this->getMockBuilder('Magento\Framework\AuthorizationInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->model = $objectManager->getObject(
+            'Magento\Framework\Reflection\ExtensionAttributesProcessor',
+            [
+                'dataObjectProcessor' => $this->dataObjectProcessorMock,
+                'methodsMapProcessor' => $this->methodsMapProcessorMock,
+                'typeCaster' => $this->typeCasterMock,
+                'fieldNamer' => $this->fieldNamerMock,
+                'authorization' => $this->authorizationMock,
+                'configReader' => $this->configReaderMock,
+                'isPermissionChecked' => true,
+            ]
+        );
+    }
+
+    /**
+     * @param bool $isPermissionAllowed
+     * @param array $expectedValue
+     * @dataProvider buildOutputDataArrayWithPermissionProvider
+     */
+    public function testBuildOutputDataArrayWithPermission($isPermissionAllowed, $expectedValue)
+    {
+        $dataObject = new \Magento\Framework\Reflection\Test\Unit\ExtensionAttributesObject();
+        $dataObjectType = 'Magento\Framework\Reflection\Test\Unit\ExtensionAttributesObject';
+        $methodName = 'getAttrName';
+        $attributeName = 'attr_name';
+        $attributeValue = 'attrName';
+
+        $this->methodsMapProcessorMock->expects($this->once())
+            ->method('getMethodsMap')
+            ->with($dataObjectType)
+            ->will($this->returnValue([$methodName => []]));
+        $this->methodsMapProcessorMock->expects($this->once())
+            ->method('isMethodValidForDataField')
+            ->with($dataObjectType, $methodName)
+            ->will($this->returnValue(true));
+        $this->fieldNamerMock->expects($this->once())
+            ->method('getFieldNameForMethodName')
+            ->with($methodName)
+            ->will($this->returnValue($attributeName));
+        $permissionName = 'Magento_Permission';
+        $this->configReaderMock->expects($this->once())
+            ->method('read')
+            ->will($this->returnValue([
+                $dataObjectType => [
+                    $attributeName => [ Converter::RESOURCE_PERMISSIONS => [ $permissionName ] ]
+                ]
+              ]));
+        $this->authorizationMock->expects($this->once())
+            ->method('isAllowed')
+            ->with($permissionName)
+            ->will($this->returnValue($isPermissionAllowed));
+
+        if ($isPermissionAllowed) {
+            $this->methodsMapProcessorMock->expects($this->once())
+                ->method('getMethodReturnType')
+                ->with($dataObjectType, $methodName)
+                ->will($this->returnValue('string'));
+            $this->typeCasterMock->expects($this->once())
+                ->method('castValueToType')
+                ->with($attributeValue, 'string')
+                ->will($this->returnValue($attributeValue));
+        }
+
+        $value = $this->model->buildOutputDataArray(
+            $dataObject,
+            $dataObjectType
+        );
+
+        $this->assertEquals(
+            $value,
+            $expectedValue
+        );
+    }
+
+    public function buildOutputDataArrayWithPermissionProvider()
+    {
+        return [
+            'permission allowed' => [
+                true,
+                [
+                    'attr_name' => 'attrName',
+                ],
+            ],
+            'permission not allowed' => [
+                false,
+                [],
+            ],
+        ];
+    }
+}
diff --git a/lib/internal/Magento/Framework/Reflection/Test/Unit/FieldNamerTest.php b/lib/internal/Magento/Framework/Reflection/Test/Unit/FieldNamerTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..1d498a940ec1a437ccc546e3629df37767748eeb
--- /dev/null
+++ b/lib/internal/Magento/Framework/Reflection/Test/Unit/FieldNamerTest.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\Reflection\Test\Unit;
+
+use Magento\Framework\Reflection\FieldNamer;
+
+/**
+ * Field namer Test
+ */
+class FieldNamerTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var FieldNamer
+     */
+    private $model;
+
+    /**
+     * Set up helper.
+     */
+    public function setUp()
+    {
+        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $this->model = $objectManager->getObject('Magento\Framework\Reflection\FieldNamer');
+    }
+
+    /**
+     * @param string $methodName
+     * @param string $expectedName
+     * @dataProvider methodNameProvider
+     */
+    public function testGetFieldNameForMethodName($methodName, $expectedName)
+    {
+        $value = $this->model->getFieldNameForMethodName($methodName);
+        $this->assertEquals($value, $expectedName);
+    }
+
+    /**
+     * @return array
+     */
+    public function methodNameProvider()
+    {
+        return [
+            'isMethod' => ['isValid', 'valid'],
+            'getMethod' => ['getValue', 'value'],
+            'hasMethod' => ['hasStuff', 'stuff'],
+            'randomMethod' => ['randomMethod', null],
+        ];
+    }
+}
diff --git a/lib/internal/Magento/Framework/Reflection/Test/Unit/MethodsMapTest.php b/lib/internal/Magento/Framework/Reflection/Test/Unit/MethodsMapTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..82f859897da9bfdcdd8f26de0ef7d3201712f699
--- /dev/null
+++ b/lib/internal/Magento/Framework/Reflection/Test/Unit/MethodsMapTest.php
@@ -0,0 +1,174 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Framework\Reflection\Test\Unit;
+
+use Magento\Framework\Reflection\MethodsMap;
+use Magento\Framework\Reflection\TypeProcessor;
+use Magento\Framework\Reflection\FieldNamer;
+
+/**
+ * MethodsMap test
+ */
+class MethodsMapTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var MethodsMap
+     */
+    private $model;
+
+    /**
+     * Set up helper.
+     */
+    public function setUp()
+    {
+        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+
+        $cacheMock = $this->getMockBuilder('Magento\Framework\Cache\FrontendInterface')
+            ->getMockForAbstractClass();
+        $cacheMock->expects($this->any())
+            ->method('save');
+        $cacheMock->expects($this->any())
+            ->method('load')
+            ->will($this->returnValue(null));
+
+        $attributeTypeResolverMock = $this->getMockBuilder('Magento\Framework\Api\AttributeTypeResolverInterface')
+            ->getMockForAbstractClass();
+        $fieldNamerMock = $this->getMockBuilder('Magento\Framework\Reflection\FieldNamer')
+            ->getMockForAbstractClass();
+        $this->model = $objectManager->getObject(
+            'Magento\Framework\Reflection\MethodsMap',
+            [
+                'cache' => $cacheMock,
+                'typeProcessor' => new TypeProcessor(),
+                'typeResolver' => $attributeTypeResolverMock,
+                'fieldNamer' => $fieldNamerMock,
+            ]
+        );
+    }
+
+    public function testGetMethodReturnType()
+    {
+        $this->assertEquals(
+            'string',
+            $this->model->getMethodReturnType('Magento\Framework\Reflection\FieldNamer', 'getFieldNameForMethodName')
+        );
+        $this->assertEquals(
+            'mixed',
+            $this->model->getMethodReturnType('Magento\Framework\Reflection\TypeCaster', 'castValueToType')
+        );
+        $this->assertEquals(
+            'array',
+            $this->model->getMethodReturnType('Magento\Framework\Reflection\MethodsMap', 'getMethodsMap')
+        );
+    }
+
+    public function testGetMethodsMap()
+    {
+        $methodsMap = $this->model->getMethodsMap('Magento\Framework\Reflection\MethodsMap');
+        $this->assertEquals(
+            $methodsMap,
+            [
+                'getMethodReturnType' => [
+                    'type' => 'string',
+                    'isRequired' => true,
+                    'description' => null,
+                    'parameterCount' => 2,
+                ],
+                'getMethodsMap' => [
+                    'type' => 'array',
+                    'isRequired' => true,
+                    'description' => "<pre> Service methods' reflection data stored in cache as 'methodName' => "
+                        . "'returnType' ex. [ 'create' => '\Magento\Customer\Api\Data\Customer', 'validatePassword' "
+                        . "=> 'boolean' ] </pre>",
+                    'parameterCount' => 1,
+                ],
+                'isMethodValidForDataField' => [
+                    'type' => 'bool',
+                    'isRequired' => true,
+                    'description' => null,
+                    'parameterCount' => 2,
+                ],
+                'isMethodReturnValueRequired' => [
+                    'type' => 'bool',
+                    'isRequired' => true,
+                    'description' => null,
+                    'parameterCount' => 2,
+                ],
+            ]
+        );
+    }
+
+    /**
+     * @param string $type
+     * @param string $methodName
+     * @param bool $expectedResult
+     * @dataProvider isMethodValidForDataFieldProvider
+     */
+    public function testIsMethodValidForDataField($type, $methodName, $expectedResult)
+    {
+        $this->assertEquals($this->model->isMethodValidForDataField($type, $methodName), $expectedResult);
+    }
+
+    /**
+     * @return array
+     */
+    public function isMethodValidForDataFieldProvider()
+    {
+        return [
+            'MethodsMap#isMethodValidForDataField' => [
+                'Magento\Framework\Reflection\MethodsMap',
+                'isMethodValidForDataField',
+                false,
+            ],
+            'DataObject#getAttrName' => [
+                'Magento\Framework\Reflection\Test\Unit\DataObject',
+                'getAttrName',
+                true,
+            ],
+            'DataObject#isActive' => [
+                'Magento\Framework\Reflection\Test\Unit\DataObject',
+                'isActive',
+                true,
+            ],
+        ];
+    }
+
+    /**
+     * @param string $type
+     * @param string $methodName
+     * @param bool $expectedResult
+     * @dataProvider isMethodReturnValueRequiredProvider
+     */
+    public function testIsMethodReturnValueRequired($type, $methodName, $expectedResult)
+    {
+        $this->assertEquals($this->model->isMethodValidForDataField($type, $methodName), $expectedResult);
+    }
+
+    /**
+     * @return array
+     */
+    public function isMethodReturnValueRequiredProvider()
+    {
+        return [
+            'DataObject#getAttrName' => [
+                'Magento\Framework\Reflection\Test\Unit\DataObject',
+                'getAttrName',
+                true,
+            ],
+            'DataObject#isActive' => [
+                'Magento\Framework\Reflection\Test\Unit\DataObject',
+                'isActive',
+                true,
+            ],
+            'FieldNamer#getFieldNameForMethodName' => [
+                'Magento\Framework\Reflection\FieldNamer',
+                'getFieldNameForMethodName',
+                false,
+            ],
+        ];
+    }
+}
diff --git a/lib/internal/Magento/Framework/Reflection/Test/Unit/TypeCasterTest.php b/lib/internal/Magento/Framework/Reflection/Test/Unit/TypeCasterTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..8f7afdbbedcb05e103f92c6c982d5a0686cf7481
--- /dev/null
+++ b/lib/internal/Magento/Framework/Reflection/Test/Unit/TypeCasterTest.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\Reflection\Test\Unit;
+
+use Magento\Framework\Reflection\TypeCaster;
+
+/**
+ * Type caster Test
+ */
+class TypeCasterTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var TypeCaster
+     */
+    private $model;
+
+    /**
+     * Set up helper.
+     */
+    public function setUp()
+    {
+        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $this->model = $objectManager->getObject('Magento\Framework\Reflection\TypeCaster');
+    }
+
+    /**
+     * @param mixed $origValue
+     * @param string $typeToCast
+     * @param mixed $expectedValue
+     * @dataProvider typeCastValueProvider
+     */
+    public function testCastValues($origValue, $typeToCast, $expectedValue)
+    {
+        $value = $this->model->castValueToType($origValue, $typeToCast);
+        $this->assertTrue($value === $expectedValue);
+    }
+
+    /**
+     * @return array
+     */
+    public function typeCastValueProvider()
+    {
+        return [
+            'null' => [null, 'int', null],
+            'int' => ['1', 'int', 1],
+            'integer' => ['1', 'integer', 1],
+            'string' => ['1', 'string', '1'],
+            'bool 0' => ['0', 'bool', false],
+            'bool 1' => ['1', 'bool', true],
+            'boolean 0' => ['0', 'boolean', false],
+            'boolean 1' => ['1', 'boolean', true],
+            'true' => ['1', 'true', true],
+            'false' => ['0', 'false', false],
+            'float' => ['1.03', 'float', 1.03],
+            'double' => ['1.30', 'double', 1.30],
+        ];
+    }
+}
diff --git a/lib/internal/Magento/Framework/Reflection/TypeCaster.php b/lib/internal/Magento/Framework/Reflection/TypeCaster.php
new file mode 100644
index 0000000000000000000000000000000000000000..185b86c1d880b14061f3271da5de4885bf56cf29
--- /dev/null
+++ b/lib/internal/Magento/Framework/Reflection/TypeCaster.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Framework\Reflection;
+
+/**
+ * Casts values to the type given.
+ */
+class TypeCaster
+{
+    /**
+     * Cast the output type to the documented type. This helps for consistent output (e.g. JSON).
+     *
+     * @param mixed $value
+     * @param string $type
+     * @return mixed
+     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+     * @SuppressWarnings(PHPMD.NPathComplexity)
+     */
+    public function castValueToType($value, $type)
+    {
+        if ($value === null) {
+            return null;
+        }
+
+        if ($type === "int" || $type === "integer") {
+            return (int)$value;
+        }
+
+        if ($type === "string") {
+            return (string)$value;
+        }
+
+        if ($type === "bool" || $type === "boolean" || $type === "true" || $type == "false") {
+            return (bool)$value;
+        }
+
+        if ($type === "float") {
+            return (float)$value;
+        }
+
+        if ($type === "double") {
+            return (double)$value;
+        }
+
+        return $value;
+    }
+}
diff --git a/lib/internal/Magento/Framework/Search/Dynamic/DataProviderFactory.php b/lib/internal/Magento/Framework/Search/Dynamic/DataProviderFactory.php
index 1cfc1477a7957b46fe1f58f752749b3d8a4193a2..1b534b4dbf4991c3c5f71f2b8009bd6efd9f20df 100644
--- a/lib/internal/Magento/Framework/Search/Dynamic/DataProviderFactory.php
+++ b/lib/internal/Magento/Framework/Search/Dynamic/DataProviderFactory.php
@@ -33,7 +33,7 @@ class DataProviderFactory
         ScopeConfigInterface $scopeConfig,
         $configPath,
         $dataProviders,
-        $scope = ScopeInterface::SCOPE_DEFAULT
+        $scope = ScopeConfigInterface::SCOPE_TYPE_DEFAULT
     ) {
         $this->objectManager = $objectManager;
         $configValue = $scopeConfig->getValue($configPath, $scope);
diff --git a/lib/internal/Magento/Framework/Search/Dynamic/IntervalFactory.php b/lib/internal/Magento/Framework/Search/Dynamic/IntervalFactory.php
index bba9824e19083f82aa5c249338bf16d2d4da5575..80ac66bb04e62950ae6a7d4dedc4e0fd8dd148d4 100644
--- a/lib/internal/Magento/Framework/Search/Dynamic/IntervalFactory.php
+++ b/lib/internal/Magento/Framework/Search/Dynamic/IntervalFactory.php
@@ -33,7 +33,7 @@ class IntervalFactory
         ScopeConfigInterface $scopeConfig,
         $configPath,
         $intervals,
-        $scope = ScopeInterface::SCOPE_DEFAULT
+        $scope = ScopeConfigInterface::SCOPE_TYPE_DEFAULT
     ) {
         $this->objectManager = $objectManager;
         $configValue = $scopeConfig->getValue($configPath, $scope);
diff --git a/lib/internal/Magento/Framework/Search/Request/Mapper.php b/lib/internal/Magento/Framework/Search/Request/Mapper.php
index e2dcbef74cda6ab201ed6bdd7dc6b3dcda916cd7..d69d5e4e6d6689170096767166c1cc44fba09d6d 100644
--- a/lib/internal/Magento/Framework/Search/Request/Mapper.php
+++ b/lib/internal/Magento/Framework/Search/Request/Mapper.php
@@ -14,6 +14,11 @@ use Magento\Framework\Phrase;
  */
 class Mapper
 {
+    /**
+     * @var QueryInterface
+     */
+    private $rootQuery;
+
     /**
      * @var array
      */
@@ -45,9 +50,9 @@ class Mapper
     private $objectManager;
 
     /**
-     * @var QueryInterface
+     * @var string
      */
-    private $rootQuery = null;
+    private $rootQueryName;
 
     /**
      * @param \Magento\Framework\ObjectManagerInterface $objectManager
@@ -70,26 +75,26 @@ class Mapper
         $this->queries = $queries;
         $this->aggregations = $aggregations;
         $this->filters = $filters;
-
-        $this->rootQuery = $this->get($rootQueryName);
+        $this->rootQueryName = $rootQueryName;
     }
 
     /**
      * Get Query Interface by name
      *
-     * @param string $queryName
      * @return QueryInterface
      * @throws \Exception
      * @throws \InvalidArgumentException
      * @throws StateException
      */
-    private function get($queryName)
+    public function getRootQuery()
     {
-        $this->mappedQueries = [];
-        $this->mappedFilters = [];
-        $query = $this->mapQuery($queryName);
-        $this->validate();
-        return $query;
+        if (!$this->rootQuery) {
+            $this->mappedQueries = [];
+            $this->mappedFilters = [];
+            $this->rootQuery = $this->mapQuery($this->rootQueryName);
+            $this->validate();
+        }
+        return $this->rootQuery;
     }
 
     /**
@@ -304,14 +309,6 @@ class Mapper
         $this->validateNotUsed($this->filters, $this->mappedFilters, 'Filter %1 is not used in request hierarchy');
     }
 
-    /**
-     * @return QueryInterface
-     */
-    public function getRootQuery()
-    {
-        return $this->rootQuery;
-    }
-
     /**
      * Build BucketInterface[] from array
      *
diff --git a/lib/internal/Magento/Framework/Search/Test/Unit/Adapter/Mysql/DimensionsTest.php b/lib/internal/Magento/Framework/Search/Test/Unit/Adapter/Mysql/DimensionsTest.php
index 3b37a0bf3d574e10044e2bdea2f8c4b2c2eccebb..5b0736c5fa2ef890b1362bae14c6d9b70f38bf97 100644
--- a/lib/internal/Magento/Framework/Search/Test/Unit/Adapter/Mysql/DimensionsTest.php
+++ b/lib/internal/Magento/Framework/Search/Test/Unit/Adapter/Mysql/DimensionsTest.php
@@ -6,6 +6,7 @@
 
 namespace Magento\Framework\Search\Test\Unit\Adapter\Mysql;
 
+use Magento\Framework\App\Config\ScopeConfigInterface;
 use \Magento\Framework\Search\Adapter\Mysql\Dimensions;
 
 use Magento\Framework\Search\Adapter\Mysql\Dimensions as DimensionsBuilder;
@@ -103,7 +104,7 @@ class DimensionsTest extends \PHPUnit_Framework_TestCase
     {
         $tableAlias = 'search_index';
         $name = 'scope';
-        $value = \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT;
+        $value = ScopeConfigInterface::SCOPE_TYPE_DEFAULT;
         $scopeId = -123456;
 
         $this->dimension->expects($this->once())
diff --git a/lib/internal/Magento/Framework/Search/Test/Unit/Dynamic/IntervalFactoryTest.php b/lib/internal/Magento/Framework/Search/Test/Unit/Dynamic/IntervalFactoryTest.php
index 0d7b52e00630adde68df4600dd353d1d7e314207..232f789de3ae77014a26ee1e251dbcce6235d0e5 100644
--- a/lib/internal/Magento/Framework/Search/Test/Unit/Dynamic/IntervalFactoryTest.php
+++ b/lib/internal/Magento/Framework/Search/Test/Unit/Dynamic/IntervalFactoryTest.php
@@ -5,6 +5,7 @@
  */
 namespace Magento\Framework\Search\Test\Unit\Dynamic;
 
+use Magento\Framework\App\Config\ScopeConfigInterface;
 use Magento\Framework\Search\Dynamic\IntervalInterface;
 use Magento\Framework\App\ScopeInterface;
 use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
@@ -63,7 +64,7 @@ class IntervalFactoryTest extends \PHPUnit_Framework_TestCase
     {
         $this->scopeConfig->expects($this->once())
             ->method('getValue')
-            ->with(self::CONFIG_PATH, ScopeInterface::SCOPE_DEFAULT)
+            ->with(self::CONFIG_PATH, ScopeConfigInterface::SCOPE_TYPE_DEFAULT)
             ->willReturn(self::CONFIG_PATH . 't');
         $this->objectManager->expects($this->once())
             ->method('create')
@@ -83,7 +84,7 @@ class IntervalFactoryTest extends \PHPUnit_Framework_TestCase
     {
         $this->scopeConfig->expects($this->once())
             ->method('getValue')
-            ->with(self::CONFIG_PATH, ScopeInterface::SCOPE_DEFAULT)
+            ->with(self::CONFIG_PATH, ScopeConfigInterface::SCOPE_TYPE_DEFAULT)
             ->willReturn('t');
 
         $this->factoryCreate();
@@ -97,7 +98,7 @@ class IntervalFactoryTest extends \PHPUnit_Framework_TestCase
     {
         $this->scopeConfig->expects($this->once())
             ->method('getValue')
-            ->with(self::CONFIG_PATH, ScopeInterface::SCOPE_DEFAULT)
+            ->with(self::CONFIG_PATH, ScopeConfigInterface::SCOPE_TYPE_DEFAULT)
             ->willReturn(self::CONFIG_PATH . 't');
         $this->objectManager->expects($this->once())
             ->method('create')
diff --git a/lib/internal/Magento/Framework/Session/Generic.php b/lib/internal/Magento/Framework/Session/Generic.php
index dd7da87c933a3fff8be209f77e93b77c5eebea1a..bfaf48d74ee9d7f4851e181e8e69f06437da8993 100644
--- a/lib/internal/Magento/Framework/Session/Generic.php
+++ b/lib/internal/Magento/Framework/Session/Generic.php
@@ -7,38 +7,4 @@ namespace Magento\Framework\Session;
 
 class Generic extends SessionManager
 {
-    /**
-     * Constructor
-     *
-     * @param \Magento\Framework\App\Request\Http $request
-     * @param SidResolverInterface $sidResolver
-     * @param \Magento\Framework\Session\Config\ConfigInterface $sessionConfig
-     * @param SaveHandlerInterface $saveHandler
-     * @param ValidatorInterface $validator
-     * @param StorageInterface $storage
-     * @param \Magento\Framework\Stdlib\CookieManagerInterface $cookieManager
-     * @param \Magento\Framework\Stdlib\Cookie\CookieMetadataFactory $cookieMetadataFactory
-     */
-    public function __construct(
-        \Magento\Framework\App\Request\Http $request,
-        SidResolverInterface $sidResolver,
-        \Magento\Framework\Session\Config\ConfigInterface $sessionConfig,
-        SaveHandlerInterface $saveHandler,
-        ValidatorInterface $validator,
-        StorageInterface $storage,
-        \Magento\Framework\Stdlib\CookieManagerInterface $cookieManager,
-        \Magento\Framework\Stdlib\Cookie\CookieMetadataFactory $cookieMetadataFactory
-    ) {
-        parent::__construct(
-            $request,
-            $sidResolver,
-            $sessionConfig,
-            $saveHandler,
-            $validator,
-            $storage,
-            $cookieManager,
-            $cookieMetadataFactory
-        );
-        $this->start();
-    }
 }
diff --git a/lib/internal/Magento/Framework/Session/SessionManager.php b/lib/internal/Magento/Framework/Session/SessionManager.php
index 17636fa0776804b433129011dd25b2edaec33275..c66672e87ca8f6b7098a3ecf17a0df582dad6072 100644
--- a/lib/internal/Magento/Framework/Session/SessionManager.php
+++ b/lib/internal/Magento/Framework/Session/SessionManager.php
@@ -11,6 +11,7 @@ use Magento\Framework\Session\Config\ConfigInterface;
 
 /**
  * Session Manager
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
 class SessionManager implements SessionManagerInterface
 {
@@ -87,8 +88,11 @@ class SessionManager implements SessionManagerInterface
     protected $cookieMetadataFactory;
 
     /**
-     * Constructor
-     *
+     * @var \Magento\Framework\App\State
+     */
+    private $appState;
+
+    /**
      * @param \Magento\Framework\App\Request\Http $request
      * @param SidResolverInterface $sidResolver
      * @param ConfigInterface $sessionConfig
@@ -97,6 +101,8 @@ class SessionManager implements SessionManagerInterface
      * @param StorageInterface $storage
      * @param \Magento\Framework\Stdlib\CookieManagerInterface $cookieManager
      * @param \Magento\Framework\Stdlib\Cookie\CookieMetadataFactory $cookieMetadataFactory
+     * @param \Magento\Framework\App\State $appState
+     * @throws \Magento\Framework\Exception\SessionException
      */
     public function __construct(
         \Magento\Framework\App\Request\Http $request,
@@ -106,7 +112,8 @@ class SessionManager implements SessionManagerInterface
         ValidatorInterface $validator,
         StorageInterface $storage,
         \Magento\Framework\Stdlib\CookieManagerInterface $cookieManager,
-        \Magento\Framework\Stdlib\Cookie\CookieMetadataFactory $cookieMetadataFactory
+        \Magento\Framework\Stdlib\Cookie\CookieMetadataFactory $cookieMetadataFactory,
+        \Magento\Framework\App\State $appState
     ) {
         $this->request = $request;
         $this->sidResolver = $sidResolver;
@@ -116,9 +123,11 @@ class SessionManager implements SessionManagerInterface
         $this->storage = $storage;
         $this->cookieManager = $cookieManager;
         $this->cookieMetadataFactory = $cookieMetadataFactory;
+        $this->appState = $appState;
 
         // Enable session.use_only_cookies
         ini_set('session.use_only_cookies', '1');
+        $this->start();
     }
 
     /**
@@ -152,12 +161,25 @@ class SessionManager implements SessionManagerInterface
     /**
      * Configure session handler and start session
      *
+     * @throws \Magento\Framework\Exception\SessionException
      * @return $this
      */
     public function start()
     {
         if (!$this->isSessionExists()) {
             \Magento\Framework\Profiler::start('session_start');
+
+            try {
+                $this->appState->getAreaCode();
+            } catch (\Magento\Framework\Exception\LocalizedException $e) {
+                throw new \Magento\Framework\Exception\SessionException(
+                    new \Magento\Framework\Phrase(
+                        'Area code not set: Area code must be set before starting a session.'
+                    ),
+                    $e
+                );
+            }
+
             // Need to apply the config options so they can be ready by session_start
             $this->initIniOptions();
             $this->registerSaveHandler();
diff --git a/lib/internal/Magento/Framework/Shell.php b/lib/internal/Magento/Framework/Shell.php
index 0652d49d039e0c43d21375d3d87153db78b1e243..2372ba4088571c89d7865d4a9d2b7523fdd6e1eb 100644
--- a/lib/internal/Magento/Framework/Shell.php
+++ b/lib/internal/Magento/Framework/Shell.php
@@ -49,7 +49,7 @@ class Shell implements ShellInterface
         $command = $this->commandRenderer->render($command, $arguments);
         $this->log($command);
 
-        $disabled = explode(',', ini_get('disable_functions'));
+        $disabled = explode(',', str_replace(' ', ',', ini_get('disable_functions')));
         if (in_array('exec', $disabled)) {
             throw new Exception\LocalizedException(new \Magento\Framework\Phrase("exec function is disabled."));
         }
diff --git a/lib/internal/Magento/Framework/Simplexml/Config.php b/lib/internal/Magento/Framework/Simplexml/Config.php
index 4e1265ebd4a4c180d7bbc4a8b84b0334b5b1676a..2f45cd6550b87a9417f2e50355866765c26d2a2b 100644
--- a/lib/internal/Magento/Framework/Simplexml/Config.php
+++ b/lib/internal/Magento/Framework/Simplexml/Config.php
@@ -118,12 +118,12 @@ class Config
      */
     public function getNode($path = null)
     {
-        if (!$this->_xml instanceof Element) {
+        if (!$this->getXml() instanceof Element) {
             return false;
         } elseif ($path === null) {
-            return $this->_xml;
+            return $this->getXml();
         } else {
-            return $this->_xml->descend($path);
+            return $this->getXml()->descend($path);
         }
     }
 
@@ -135,11 +135,12 @@ class Config
      */
     public function getXpath($xpath)
     {
-        if (empty($this->_xml)) {
+        $xml = $this->getXml();
+        if (empty($xml)) {
             return false;
         }
 
-        if (!($result = @$this->_xml->xpath($xpath))) {
+        if (!($result = @$xml->xpath($xpath))) {
             return false;
         }
 
@@ -476,7 +477,7 @@ class Config
         if (!empty($string)) {
             $xml = simplexml_load_string($string, $this->_elementClass);
             if ($xml) {
-                $this->_xml = $xml;
+                $this->setXml($xml);
                 return true;
             }
         }
@@ -493,7 +494,7 @@ class Config
     {
         $xml = simplexml_import_dom($dom, $this->_elementClass);
         if ($xml) {
-            $this->_xml = $xml;
+            $this->setXml($xml);
             return true;
         }
 
@@ -510,7 +511,7 @@ class Config
      */
     public function setNode($path, $value, $overwrite = true)
     {
-        $this->_xml->setNode($path, $value, $overwrite);
+        $this->getXml()->setNode($path, $value, $overwrite);
         return $this;
     }
 
@@ -575,4 +576,14 @@ class Config
     {
         $this->_xml = null;
     }
+
+    /**
+     * Getter for xml element
+     *
+     * @return Element
+     */
+    protected function getXml()
+    {
+        return $this->_xml;
+    }
 }
diff --git a/lib/internal/Magento/Framework/Test/Unit/PhraseTest.php b/lib/internal/Magento/Framework/Test/Unit/PhraseTest.php
index f3e8c8d9e0195e9fd64d659d6a020d71c8f93f88..72bff033c0c7402e782aa7bd350afa041912e7fc 100755
--- a/lib/internal/Magento/Framework/Test/Unit/PhraseTest.php
+++ b/lib/internal/Magento/Framework/Test/Unit/PhraseTest.php
@@ -5,7 +5,7 @@
  */
 namespace Magento\Framework\Test\Unit;
 
-use \Magento\Framework\Phrase;
+use Magento\Framework\Phrase;
 
 class PhraseTest extends \PHPUnit_Framework_TestCase
 {
@@ -19,11 +19,6 @@ class PhraseTest extends \PHPUnit_Framework_TestCase
      */
     protected $rendererMock;
 
-    /**
-     * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager
-     */
-    protected $objectManager;
-
     /**
      * SetUp method
      *
@@ -34,7 +29,6 @@ class PhraseTest extends \PHPUnit_Framework_TestCase
         $this->defaultRenderer = Phrase::getRenderer();
         $this->rendererMock = $this->getMockBuilder('Magento\Framework\Phrase\RendererInterface')
             ->getMock();
-        $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
     }
 
     /**
@@ -57,10 +51,7 @@ class PhraseTest extends \PHPUnit_Framework_TestCase
         $text = 'some text';
         $arguments = ['arg1', 'arg2'];
         $result = 'rendered text';
-        $phrase = $this->objectManager->getObject('Magento\Framework\Phrase', [
-            'text' => $text,
-            'arguments' => $arguments,
-        ]);
+        $phrase = new Phrase($text, $arguments);
         Phrase::setRenderer($this->rendererMock);
 
         $this->rendererMock->expects($this->once())
@@ -81,9 +72,7 @@ class PhraseTest extends \PHPUnit_Framework_TestCase
         $this->rendererMock->expects($this->never())
             ->method('render');
 
-        $this->objectManager->getObject('Magento\Framework\Phrase', [
-            'text' => 'some text',
-        ]);
+        new Phrase('some text');
     }
 
     /**
@@ -96,10 +85,7 @@ class PhraseTest extends \PHPUnit_Framework_TestCase
         $text = 'some text';
         $arguments = ['arg1', 'arg2'];
         $result = 'rendered text';
-        $phrase = $this->objectManager->getObject('Magento\Framework\Phrase', [
-            'text' => $text,
-            'arguments' => $arguments,
-        ]);
+        $phrase = new Phrase($text, $arguments);
         Phrase::setRenderer($this->rendererMock);
 
         $this->rendererMock->expects($this->once())
@@ -119,9 +105,6 @@ class PhraseTest extends \PHPUnit_Framework_TestCase
     {
         $text = 'some text';
         $phrase = new Phrase($text);
-        $phrase = $this->objectManager->getObject('Magento\Framework\Phrase', [
-            'text' => $text,
-        ]);
 
         $this->assertEquals($text, $phrase->getText());
     }
@@ -135,36 +118,31 @@ class PhraseTest extends \PHPUnit_Framework_TestCase
     {
         $text = 'some text';
         $arguments = ['arg1', 'arg2'];
-        $phrase1 = $this->objectManager->getObject('Magento\Framework\Phrase', [
-            'text' => $text,
-        ]);
-        $phrase2 = $this->objectManager->getObject('Magento\Framework\Phrase', [
-            'text' => $text,
-            'arguments' => $arguments,
-        ]);
+        $phrase1 = new Phrase($text);
+        $phrase2 = new Phrase($text, $arguments);
 
         $this->assertEquals([], $phrase1->getArguments());
         $this->assertEquals($arguments, $phrase2->getArguments());
     }
 
+    public function testToStringWithExceptionOnRender()
+    {
+        $text = 'raw text';
+        $exception = new \Exception('something went wrong');
+        $phrase = new Phrase($text);
+
+        $this->rendererMock->expects($this->any())
+            ->method('render')
+            ->willThrowException($exception);
+
+        $this->assertEquals($text, (string)$phrase);
+    }
+
     /**
-     * Test default rendering
-     *
-     * @return void
+     * Test default renderer
      */
-    public function testDefaultRendering()
+    public function testDefaultRenderer()
     {
-        $text = 'parameter1 is replaced by %1 parameter2 is replaced by %2';
-        $arguments = ['arg1', 'arg2'];
-        $result = 'parameter1 is replaced by arg1 parameter2 is replaced by arg2';
-        $phrase = $this->objectManager->getObject('Magento\Framework\Phrase', [
-            'text' => $text,
-            'arguments' => $arguments,
-        ]);
-
-        $this->assertEquals($text, $phrase->getText());
-        $this->assertEquals($arguments, $phrase->getArguments());
-        $this->assertTrue($phrase->getRenderer() instanceof \Magento\Framework\Phrase\Renderer\Placeholder);
-        $this->assertEquals($result, $phrase->render());
+        $this->assertInstanceOf('Magento\Framework\Phrase\Renderer\Placeholder', Phrase::getRenderer());
     }
 }
diff --git a/lib/internal/Magento/Framework/Test/Unit/UrlTest.php b/lib/internal/Magento/Framework/Test/Unit/UrlTest.php
index 46d9a13f0bf0a5290fd6086d78aab72a9bf502ca..69e2260002ce05ff621e5b63baf613c7e30a879b 100644
--- a/lib/internal/Magento/Framework/Test/Unit/UrlTest.php
+++ b/lib/internal/Magento/Framework/Test/Unit/UrlTest.php
@@ -73,9 +73,10 @@ class UrlTest extends \PHPUnit_Framework_TestCase
     }
 
     /**
+     * @param bool $resolve
      * @return \Magento\Framework\Url\RouteParamsResolverFactory|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected function getRouteParamsResolver()
+    protected function getRouteParamsResolverFactory($resolve = true)
     {
         $routeParamsResolverFactoryMock = $this->getMock(
             'Magento\Framework\Url\RouteParamsResolverFactory',
@@ -84,8 +85,10 @@ class UrlTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
-        $routeParamsResolverFactoryMock->expects($this->once())->method('create')
-            ->will($this->returnValue($this->routeParamsResolverMock));
+        if ($resolve) {
+            $routeParamsResolverFactoryMock->expects($this->once())->method('create')
+                    ->will($this->returnValue($this->routeParamsResolverMock));
+        }
         return $routeParamsResolverFactoryMock;
     }
 
@@ -152,7 +155,10 @@ class UrlTest extends \PHPUnit_Framework_TestCase
     public function testGetBaseUrlNotLinkType()
     {
         $model = $this->getUrlModel(
-            ['scopeResolver' => $this->scopeResolverMock, 'routeParamsResolver' => $this->getRouteParamsResolver()]
+            [
+                'scopeResolver' => $this->scopeResolverMock,
+                'routeParamsResolverFactory' => $this->getRouteParamsResolverFactory()
+            ]
         );
 
         $baseUrl = 'base-url';
@@ -184,9 +190,12 @@ class UrlTest extends \PHPUnit_Framework_TestCase
         $requestMock = $this->getRequestMock();
         $routeConfigMock = $this->getMock('Magento\Framework\App\Route\ConfigInterface');
         $model = $this->getUrlModel(
-            ['scopeResolver' => $this->scopeResolverMock, 'routeParamsResolver' => $this->getRouteParamsResolver(),
+            [
+                'scopeResolver' => $this->scopeResolverMock,
+                'routeParamsResolverFactory' => $this->getRouteParamsResolverFactory(),
                 'queryParamsResolver' => $this->queryParamsResolverMock,
-                'request' => $requestMock, 'routeConfig' => $routeConfigMock, ]
+                'request' => $requestMock, 'routeConfig' => $routeConfigMock,
+            ]
         );
 
         $baseUrl = 'http://localhost/index.php/';
@@ -218,7 +227,7 @@ class UrlTest extends \PHPUnit_Framework_TestCase
     {
         $model = $this->getUrlModel([
             'scopeResolver' => $this->scopeResolverMock,
-            'routeParamsResolver' => $this->getRouteParamsResolver(),
+            'routeParamsResolverFactory' => $this->getRouteParamsResolverFactory(),
         ]);
         $model->setData('route_path', 'catalog/product/view');
 
@@ -233,7 +242,7 @@ class UrlTest extends \PHPUnit_Framework_TestCase
     {
         $model = $this->getUrlModel([
             'scopeResolver' => $this->scopeResolverMock,
-            'routeParamsResolver' => $this->getRouteParamsResolver(),
+            'routeParamsResolverFactory' => $this->getRouteParamsResolverFactory(),
             'request' => $this->getRequestMock()
         ]);
         $model->setData('route_name', 'catalog');
@@ -251,7 +260,7 @@ class UrlTest extends \PHPUnit_Framework_TestCase
             ->will($this->returnValue(['foo' => 'bar', 'true' => false]));
         $model = $this->getUrlModel([
             'scopeResolver' => $this->scopeResolverMock,
-            'routeParamsResolver' => $this->getRouteParamsResolver(),
+            'routeParamsResolverFactory' => $this->getRouteParamsResolverFactory(),
             'request' => $this->getRequestMock()
         ]);
 
@@ -270,7 +279,7 @@ class UrlTest extends \PHPUnit_Framework_TestCase
         $request->expects($this->once())->method('getAlias')->will($this->returnValue('/catalog/product/view/'));
         $model = $this->getUrlModel([
             'scopeResolver' => $this->scopeResolverMock,
-            'routeParamsResolver' => $this->getRouteParamsResolver(),
+            'routeParamsResolverFactory' => $this->getRouteParamsResolverFactory(),
             'request' => $request,
         ]);
 
@@ -299,9 +308,12 @@ class UrlTest extends \PHPUnit_Framework_TestCase
         $requestMock = $this->getRequestMock();
         $routeConfigMock = $this->getMock('Magento\Framework\App\Route\ConfigInterface');
         $model = $this->getUrlModel(
-            ['scopeResolver' => $this->scopeResolverMock, 'routeParamsResolver' => $this->getRouteParamsResolver(),
+            [
+                'scopeResolver' => $this->scopeResolverMock,
+                'routeParamsResolverFactory' => $this->getRouteParamsResolverFactory(),
                 'queryParamsResolver' => $this->queryParamsResolverMock,
-                'request' => $requestMock, 'routeConfig' => $routeConfigMock, ]
+                'request' => $requestMock, 'routeConfig' => $routeConfigMock,
+            ]
         );
 
         $baseUrl = 'http://localhost/index.php/';
@@ -332,9 +344,12 @@ class UrlTest extends \PHPUnit_Framework_TestCase
         $requestMock = $this->getRequestMock();
         $routeConfigMock = $this->getMock('Magento\Framework\App\Route\ConfigInterface');
         $model = $this->getUrlModel(
-            ['scopeResolver' => $this->scopeResolverMock, 'routeParamsResolver' => $this->getRouteParamsResolver(),
+            [
+                'scopeResolver' => $this->scopeResolverMock,
+                'routeParamsResolverFactory' => $this->getRouteParamsResolverFactory(),
                 'queryParamsResolver' => $this->queryParamsResolverMock,
-                'request' => $requestMock, 'routeConfig' => $routeConfigMock, ]
+                'request' => $requestMock, 'routeConfig' => $routeConfigMock,
+            ]
         );
 
         $baseUrl = 'http://localhost/index.php/';
@@ -363,7 +378,7 @@ class UrlTest extends \PHPUnit_Framework_TestCase
             'request' => $requestMock,
             'sidResolver' => $this->sidResolverMock,
             'scopeResolver' => $this->scopeResolverMock,
-            'routeParamsResolver' => $this->getRouteParamsResolver(),
+            'routeParamsResolverFactory' => $this->getRouteParamsResolverFactory(false),
             'queryParamsResolver' => $this->queryParamsResolverMock,
         ]);
 
@@ -376,8 +391,12 @@ class UrlTest extends \PHPUnit_Framework_TestCase
     public function testGetRedirectUrl()
     {
         $model = $this->getUrlModel(
-            ['routeParamsResolver' => $this->getRouteParamsResolver(), 'session' => $this->sessionMock,
-                'sidResolver' => $this->sidResolverMock, 'queryParamsResolver' => $this->queryParamsResolverMock, ]
+            [
+                'routeParamsResolverFactory' => $this->getRouteParamsResolverFactory(),
+                'session' => $this->sessionMock,
+                'sidResolver' => $this->sidResolverMock,
+                'queryParamsResolver' => $this->queryParamsResolverMock,
+            ]
         );
 
         $this->sidResolverMock->expects($this->once())->method('getUseSessionInUrl')->will($this->returnValue(true));
@@ -396,8 +415,12 @@ class UrlTest extends \PHPUnit_Framework_TestCase
     public function testGetRedirectUrlWithSessionId()
     {
         $model = $this->getUrlModel(
-            ['routeParamsResolver' => $this->getRouteParamsResolver(), 'session' => $this->sessionMock,
-                'sidResolver' => $this->sidResolverMock, 'queryParamsResolver' => $this->queryParamsResolverMock, ]
+            [
+                'routeParamsResolverFactory' => $this->getRouteParamsResolverFactory(false),
+                'session' => $this->sessionMock,
+                'sidResolver' => $this->sidResolverMock,
+                'queryParamsResolver' => $this->queryParamsResolverMock,
+            ]
         );
 
         $this->sidResolverMock->expects($this->once())->method('getUseSessionInUrl')->will($this->returnValue(true));
@@ -422,7 +445,7 @@ class UrlTest extends \PHPUnit_Framework_TestCase
 
     public function testGetRouteUrlWithValidUrl()
     {
-        $model = $this->getUrlModel(['routeParamsResolver' => $this->getRouteParamsResolver()]);
+        $model = $this->getUrlModel(['routeParamsResolverFactory' => $this->getRouteParamsResolverFactory(false)]);
 
         $this->routeParamsResolverMock->expects($this->never())->method('unsetData');
         $this->assertEquals('http://example.com', $model->getRouteUrl('http://example.com'));
@@ -485,7 +508,7 @@ class UrlTest extends \PHPUnit_Framework_TestCase
         $urlSecurityInfoMock = $this->getMock('Magento\Framework\Url\SecurityInfoInterface');
         $model = $this->getUrlModel([
             'urlSecurityInfo' => $urlSecurityInfoMock,
-            'routeParamsResolver' => $this->getRouteParamsResolver(),
+            'routeParamsResolverFactory' => $this->getRouteParamsResolverFactory(),
             'scopeResolver' => $this->scopeResolverMock,
             'scopeConfig' => $this->scopeConfig,
         ]);
@@ -530,7 +553,7 @@ class UrlTest extends \PHPUnit_Framework_TestCase
     public function testGetConfigDataWithSecureIsForcedParam()
     {
         $model = $this->getUrlModel([
-            'routeParamsResolver' => $this->getRouteParamsResolver(),
+            'routeParamsResolverFactory' => $this->getRouteParamsResolverFactory(),
             'scopeResolver' => $this->scopeResolverMock,
             'scopeConfig' => $this->scopeConfig,
         ]);
@@ -562,8 +585,13 @@ class UrlTest extends \PHPUnit_Framework_TestCase
     {
         $requestMock = $this->getRequestMock();
         $model = $this->getUrlModel(
-            ['session' => $this->sessionMock, 'request' => $requestMock, 'sidResolver' => $this->sidResolverMock,
-                'scopeResolver' => $this->scopeResolverMock, 'routeParamsResolver' => $this->getRouteParamsResolver(), ]
+            [
+                'session' => $this->sessionMock,
+                'request' => $requestMock,
+                'sidResolver' => $this->sidResolverMock,
+                'scopeResolver' => $this->scopeResolverMock,
+                'routeParamsResolverFactory' => $this->getRouteParamsResolverFactory(),
+            ]
         );
 
         $requestMock->expects($this->once())
@@ -585,8 +613,13 @@ class UrlTest extends \PHPUnit_Framework_TestCase
     {
         $requestMock = $this->getRequestMock();
         $model = $this->getUrlModel(
-            ['session' => $this->sessionMock, 'request' => $requestMock, 'sidResolver' => $this->sidResolverMock,
-                'scopeResolver' => $this->scopeResolverMock, 'routeParamsResolver' => $this->getRouteParamsResolver(), ]
+            [
+                'session' => $this->sessionMock,
+                'request' => $requestMock,
+                'sidResolver' => $this->sidResolverMock,
+                'scopeResolver' => $this->scopeResolverMock,
+                'routeParamsResolverFactory' => $this->getRouteParamsResolverFactory(),
+            ]
         );
 
         $requestMock->expects($this->once())->method('getHttpHost')->will($this->returnValue('localhost'));
diff --git a/lib/internal/Magento/Framework/Url.php b/lib/internal/Magento/Framework/Url.php
index efffc744e3fe46da126f655f16a95c9f1c5bd4a7..697e461df050f1f623075655acd3ea4fc13ccaa9 100644
--- a/lib/internal/Magento/Framework/Url.php
+++ b/lib/internal/Magento/Framework/Url.php
@@ -56,6 +56,7 @@ namespace Magento\Framework;
  * - G: route_path
  * - H: route_url
  * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
 class Url extends \Magento\Framework\Object implements \Magento\Framework\UrlInterface
 {
@@ -133,8 +134,12 @@ class Url extends \Magento\Framework\Object implements \Magento\Framework\UrlInt
     /**
      * @var \Magento\Framework\Url\RouteParamsResolverInterface
      */
-    protected $_routeParamsResolver;
+    private $_routeParamsResolver;
 
+    /**
+     * @var \Magento\Framework\Url\RouteParamsResolverFactory
+     */
+    private $_routeParamsResolverFactory;
     /**
      * @var \Magento\Framework\Url\ScopeResolverInterface
      */
@@ -157,7 +162,7 @@ class Url extends \Magento\Framework\Object implements \Magento\Framework\UrlInt
      * @param \Magento\Framework\Url\ScopeResolverInterface $scopeResolver
      * @param \Magento\Framework\Session\Generic $session
      * @param \Magento\Framework\Session\SidResolverInterface $sidResolver
-     * @param \Magento\Framework\Url\RouteParamsResolverFactory $routeParamsResolver
+     * @param \Magento\Framework\Url\RouteParamsResolverFactory $routeParamsResolverFactory
      * @param \Magento\Framework\Url\QueryParamsResolverInterface $queryParamsResolver
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param string $scopeType
@@ -171,7 +176,7 @@ class Url extends \Magento\Framework\Object implements \Magento\Framework\UrlInt
         \Magento\Framework\Url\ScopeResolverInterface $scopeResolver,
         \Magento\Framework\Session\Generic $session,
         \Magento\Framework\Session\SidResolverInterface $sidResolver,
-        \Magento\Framework\Url\RouteParamsResolverFactory $routeParamsResolver,
+        \Magento\Framework\Url\RouteParamsResolverFactory $routeParamsResolverFactory,
         \Magento\Framework\Url\QueryParamsResolverInterface $queryParamsResolver,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         $scopeType,
@@ -183,7 +188,7 @@ class Url extends \Magento\Framework\Object implements \Magento\Framework\UrlInt
         $this->_scopeResolver = $scopeResolver;
         $this->_session = $session;
         $this->_sidResolver = $sidResolver;
-        $this->_routeParamsResolver = $routeParamsResolver->create();
+        $this->_routeParamsResolverFactory = $routeParamsResolverFactory;
         $this->_queryParamsResolver = $queryParamsResolver;
         $this->_scopeConfig = $scopeConfig;
         $this->_scopeType = $scopeType;
@@ -322,10 +327,10 @@ class Url extends \Magento\Framework\Object implements \Magento\Framework\UrlInt
      */
     protected function _getType()
     {
-        if (!$this->_routeParamsResolver->hasData('type')) {
-            $this->_routeParamsResolver->setData('type', self::DEFAULT_URL_TYPE);
+        if (!$this->getRouteParamsResolver()->hasData('type')) {
+            $this->getRouteParamsResolver()->setData('type', self::DEFAULT_URL_TYPE);
         }
-        return $this->_routeParamsResolver->getType();
+        return $this->getRouteParamsResolver()->getType();
     }
 
     /**
@@ -335,27 +340,27 @@ class Url extends \Magento\Framework\Object implements \Magento\Framework\UrlInt
      */
     protected function _isSecure()
     {
-        if ($this->_routeParamsResolver->hasData('secure_is_forced')) {
-            return (bool) $this->_routeParamsResolver->getData('secure');
+        if ($this->getRouteParamsResolver()->hasData('secure_is_forced')) {
+            return (bool) $this->getRouteParamsResolver()->getData('secure');
         }
 
         if (!$this->_getScope()->isUrlSecure()) {
             return false;
         }
 
-        if (!$this->_routeParamsResolver->hasData('secure')) {
+        if (!$this->getRouteParamsResolver()->hasData('secure')) {
             if ($this->_getType() == UrlInterface::URL_TYPE_LINK) {
                 $pathSecure = $this->_urlSecurityInfo->isSecure('/' . $this->_getActionPath());
-                $this->_routeParamsResolver->setData('secure', $pathSecure);
+                $this->getRouteParamsResolver()->setData('secure', $pathSecure);
             } elseif ($this->_getType() == UrlInterface::URL_TYPE_STATIC) {
                 $isRequestSecure = $this->_getRequest()->isSecure();
-                $this->_routeParamsResolver->setData('secure', $isRequestSecure);
+                $this->getRouteParamsResolver()->setData('secure', $isRequestSecure);
             } else {
-                $this->_routeParamsResolver->setData('secure', true);
+                $this->getRouteParamsResolver()->setData('secure', true);
             }
         }
 
-        return $this->_routeParamsResolver->getData('secure');
+        return $this->getRouteParamsResolver()->getData('secure');
     }
 
     /**
@@ -367,7 +372,7 @@ class Url extends \Magento\Framework\Object implements \Magento\Framework\UrlInt
     public function setScope($params)
     {
         $this->setData('scope', $this->_scopeResolver->getScope($params));
-        $this->_routeParamsResolver->setScope($this->_scopeResolver->getScope($params));
+        $this->getRouteParamsResolver()->setScope($this->_scopeResolver->getScope($params));
         return $this;
     }
 
@@ -401,11 +406,11 @@ class Url extends \Magento\Framework\Object implements \Magento\Framework\UrlInt
             $this->setScope($params['_scope']);
         }
         if (isset($params['_type'])) {
-            $this->_routeParamsResolver->setType($params['_type']);
+            $this->getRouteParamsResolver()->setType($params['_type']);
         }
 
         if (isset($params['_secure'])) {
-            $this->_routeParamsResolver->setSecure($params['_secure']);
+            $this->getRouteParamsResolver()->setSecure($params['_secure']);
         }
 
         /**
@@ -416,13 +421,13 @@ class Url extends \Magento\Framework\Object implements \Magento\Framework\UrlInt
                 $this->_getRouteFrontName()
             )
         ) {
-            $this->_routeParamsResolver->setType(UrlInterface::URL_TYPE_DIRECT_LINK);
+            $this->getRouteParamsResolver()->setType(UrlInterface::URL_TYPE_DIRECT_LINK);
         }
 
         $result = $this->_getScope()->getBaseUrl($this->_getType(), $this->_isSecure());
         // setting back the original scope
         $this->setScope($origScope);
-        $this->_routeParamsResolver->setType(self::DEFAULT_URL_TYPE);
+        $this->getRouteParamsResolver()->setType(self::DEFAULT_URL_TYPE);
         return $result;
     }
 
@@ -471,7 +476,7 @@ class Url extends \Magento\Framework\Object implements \Magento\Framework\UrlInt
                 $key = array_shift($routePieces);
                 if (!empty($routePieces)) {
                     $value = array_shift($routePieces);
-                    $this->_routeParamsResolver->setRouteParam($key, $value);
+                    $this->getRouteParamsResolver()->setRouteParam($key, $value);
                 }
             }
         }
@@ -650,7 +655,7 @@ class Url extends \Magento\Framework\Object implements \Magento\Framework\UrlInt
      */
     protected function _setRouteParams(array $data, $unsetOldParams = true)
     {
-        $this->_routeParamsResolver->setRouteParams($data, $unsetOldParams);
+        $this->getRouteParamsResolver()->setRouteParams($data, $unsetOldParams);
         return $this;
     }
 
@@ -661,7 +666,7 @@ class Url extends \Magento\Framework\Object implements \Magento\Framework\UrlInt
      */
     protected function _getRouteParams()
     {
-        return $this->_routeParamsResolver->getRouteParams();
+        return $this->getRouteParamsResolver()->getRouteParams();
     }
 
     /**
@@ -677,7 +682,7 @@ class Url extends \Magento\Framework\Object implements \Magento\Framework\UrlInt
             return $routePath;
         }
 
-        $this->_routeParamsResolver->unsetData('route_params');
+        $this->getRouteParamsResolver()->unsetData('route_params');
 
         if (isset($routeParams['_direct'])) {
             if (is_array($routeParams)) {
@@ -786,7 +791,7 @@ class Url extends \Magento\Framework\Object implements \Magento\Framework\UrlInt
          * this method has condition for adding default controller and action names
          * in case when we have params
          */
-        $this->_routeParamsResolver->unsetData('secure');
+        $this->getRouteParamsResolver()->unsetData('secure');
         $fragment = null;
         if (isset($routeParams['_fragment'])) {
             $fragment = $routeParams['_fragment'];
@@ -840,7 +845,7 @@ class Url extends \Magento\Framework\Object implements \Magento\Framework\UrlInt
         if (!is_null($fragment)) {
             $url .= '#' . $fragment;
         }
-        $this->_routeParamsResolver->unsetData('secure');
+        $this->getRouteParamsResolver()->unsetData('secure');
         return $this->escape($url);
     }
 
@@ -1038,4 +1043,17 @@ class Url extends \Magento\Framework\Object implements \Magento\Framework\UrlInt
         $url = $this->_request->getScheme() . '://' . $this->_request->getHttpHost() . $port . $requestUri;
         return $url;
     }
+
+    /**
+     * Get Route Params Resolver
+     *
+     * @return Url\RouteParamsResolverInterface
+     */
+    protected function getRouteParamsResolver()
+    {
+        if (!$this->_routeParamsResolver) {
+            $this->_routeParamsResolver = $this->_routeParamsResolverFactory->create();
+        }
+        return $this->_routeParamsResolver;
+    }
 }
diff --git a/lib/internal/Magento/Framework/Url/ScopeResolverInterface.php b/lib/internal/Magento/Framework/Url/ScopeResolverInterface.php
index 893443659220d4b68e5ec3514f25beb0ea3c7725..a31ae25c76ea41a6efea88d85ccfb5c424092143 100644
--- a/lib/internal/Magento/Framework/Url/ScopeResolverInterface.php
+++ b/lib/internal/Magento/Framework/Url/ScopeResolverInterface.php
@@ -10,7 +10,7 @@ interface ScopeResolverInterface extends \Magento\Framework\App\ScopeResolverInt
     /**
      * Retrieve area code
      *
-     * @return \Magento\Framework\Url\ScopeInterface[]
+     * @return string|null
      */
     public function getAreaCode();
 }
diff --git a/lib/internal/Magento/Framework/UrlInterface/Proxy.php b/lib/internal/Magento/Framework/UrlInterface/Proxy.php
new file mode 100644
index 0000000000000000000000000000000000000000..7ed1a1bbc7bff3df6959ec70ed2aa2c779b21636
--- /dev/null
+++ b/lib/internal/Magento/Framework/UrlInterface/Proxy.php
@@ -0,0 +1,212 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\UrlInterface;
+
+/**
+ * Proxy class for @see \Magento\Framework\UrlInterface
+ */
+class Proxy implements \Magento\Framework\UrlInterface
+{
+    /**
+     * Object Manager instance
+     *
+     * @var \Magento\Framework\ObjectManagerInterface
+     */
+    protected $_objectManager = null;
+
+    /**
+     * Proxied instance name
+     *
+     * @var string
+     */
+    protected $_instanceName = null;
+
+    /**
+     * Proxied instance
+     *
+     * @var \Magento\Framework\UrlInterface
+     */
+    protected $_subject = null;
+
+    /**
+     * Instance shareability flag
+     *
+     * @var bool
+     */
+    protected $_isShared = null;
+
+    /**
+     * Proxy constructor
+     *
+     * @param \Magento\Framework\ObjectManagerInterface $objectManager
+     * @param string $instanceName
+     * @param bool $shared
+     */
+    public function __construct(
+        \Magento\Framework\ObjectManagerInterface $objectManager,
+        $instanceName = '\\Magento\\Framework\\UrlInterface',
+        $shared = true
+    ) {
+        $this->_objectManager = $objectManager;
+        $this->_instanceName = $instanceName;
+        $this->_isShared = $shared;
+    }
+
+    /**
+     * @return array
+     */
+    public function __sleep()
+    {
+        return ['_subject', '_isShared'];
+    }
+
+    /**
+     * Retrieve ObjectManager from global scope
+     *
+     * @return void
+     */
+    public function __wakeup()
+    {
+        $this->_objectManager = \Magento\Framework\App\ObjectManager::getInstance();
+    }
+
+    /**
+     * Clone proxied instance
+     *
+     * @return void
+     */
+    public function __clone()
+    {
+        $this->_subject = clone $this->_getSubject();
+    }
+
+    /**
+     * Get proxied instance
+     *
+     * @return \Magento\Framework\UrlInterface
+     */
+    protected function _getSubject()
+    {
+        if (!$this->_subject) {
+            $this->_subject = true === $this->_isShared
+                ? $this->_objectManager->get($this->_instanceName)
+                : $this->_objectManager->create($this->_instanceName);
+        }
+        return $this->_subject;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getUseSession()
+    {
+        return $this->_getSubject()->getUseSession();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getBaseUrl($params = [])
+    {
+        return $this->_getSubject()->getBaseUrl($params);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getCurrentUrl()
+    {
+        return $this->_getSubject()->getCurrentUrl();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getRouteUrl($routePath = null, $routeParams = null)
+    {
+        return $this->_getSubject()->getRouteUrl($routePath, $routeParams);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function addSessionParam()
+    {
+        return $this->_getSubject()->addSessionParam();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function addQueryParams(array $data)
+    {
+        return $this->_getSubject()->addQueryParams($data);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setQueryParam($key, $data)
+    {
+        return $this->_getSubject()->setQueryParam($key, $data);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getUrl($routePath = null, $routeParams = null)
+    {
+        return $this->_getSubject()->getUrl($routePath, $routeParams);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function escape($value)
+    {
+        return $this->_getSubject()->escape($value);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getDirectUrl($url, $params = [])
+    {
+        return $this->_getSubject()->getDirectUrl($url, $params);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function sessionUrlVar($html)
+    {
+        return $this->_getSubject()->sessionUrlVar($html);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function isOwnOriginUrl()
+    {
+        return $this->_getSubject()->isOwnOriginUrl();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getRedirectUrl($url)
+    {
+        return $this->_getSubject()->getRedirectUrl($url);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setScope($params)
+    {
+        return $this->_getSubject()->setScope($params);
+    }
+}
diff --git a/lib/internal/Magento/Framework/Validator/Factory.php b/lib/internal/Magento/Framework/Validator/Factory.php
index a663b91cc745f01f164e1d30a1f6e9f04682087b..ef5679b220c2460dbc1e94d7d09760af0436fa31 100644
--- a/lib/internal/Magento/Framework/Validator/Factory.php
+++ b/lib/internal/Magento/Framework/Validator/Factory.php
@@ -24,6 +24,11 @@ class Factory
      */
     protected $_configFiles = null;
 
+    /**
+     * @var bool
+     */
+    private $isDefaultTranslatorInitialized = false;
+
     /**
      * Initialize dependencies
      *
@@ -36,7 +41,6 @@ class Factory
     ) {
         $this->_objectManager = $objectManager;
         $this->_configFiles = $moduleReader->getConfigurationFiles('validation.xml');
-        $this->_initializeDefaultTranslator();
     }
 
     /**
@@ -46,15 +50,18 @@ class Factory
      */
     protected function _initializeDefaultTranslator()
     {
-        // Pass translations to \Magento\Framework\TranslateInterface from validators
-        $translatorCallback = function () {
-            $argc = func_get_args();
-            return (string)new \Magento\Framework\Phrase(array_shift($argc), $argc);
-        };
-        /** @var \Magento\Framework\Translate\Adapter $translator */
-        $translator = $this->_objectManager->create('Magento\Framework\Translate\Adapter');
-        $translator->setOptions(['translator' => $translatorCallback]);
-        \Magento\Framework\Validator\AbstractValidator::setDefaultTranslator($translator);
+        if (!$this->isDefaultTranslatorInitialized) {
+            // Pass translations to \Magento\Framework\TranslateInterface from validators
+            $translatorCallback = function () {
+                $argc = func_get_args();
+                return (string)new \Magento\Framework\Phrase(array_shift($argc), $argc);
+            };
+            /** @var \Magento\Framework\Translate\Adapter $translator */
+            $translator = $this->_objectManager->create('Magento\Framework\Translate\Adapter');
+            $translator->setOptions(['translator' => $translatorCallback]);
+            \Magento\Framework\Validator\AbstractValidator::setDefaultTranslator($translator);
+            $this->isDefaultTranslatorInitialized = true;
+        }
     }
 
     /**
@@ -66,6 +73,7 @@ class Factory
      */
     public function getValidatorConfig()
     {
+        $this->_initializeDefaultTranslator();
         return $this->_objectManager->create('Magento\Framework\Validator\Config', ['configFiles' => $this->_configFiles]);
     }
 
@@ -79,6 +87,7 @@ class Factory
      */
     public function createValidatorBuilder($entityName, $groupName, array $builderConfig = null)
     {
+        $this->_initializeDefaultTranslator();
         return $this->getValidatorConfig()->createValidatorBuilder($entityName, $groupName, $builderConfig);
     }
 
@@ -92,6 +101,7 @@ class Factory
      */
     public function createValidator($entityName, $groupName, array $builderConfig = null)
     {
+        $this->_initializeDefaultTranslator();
         return $this->getValidatorConfig()->createValidator($entityName, $groupName, $builderConfig);
     }
 }
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php
new file mode 100644
index 0000000000000000000000000000000000000000..f2d2779be11166b93310f688199c584c3b63c44f
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\View\Element\UiComponent\Argument\Interpreter;
+
+use Magento\Framework\ObjectManagerInterface;
+use Magento\Framework\Data\Argument\InterpreterInterface;
+
+/**
+ * Class ConfigurableObject
+ */
+class ConfigurableObject implements InterpreterInterface
+{
+    /**
+     * @var ObjectManagerInterface
+     */
+    protected $objectManager;
+
+    /**
+     * @var InterpreterInterface
+     */
+    protected $argumentInterpreter;
+
+    /**
+     * Constructor
+     *
+     * @param ObjectManagerInterface $objectManager
+     * @param InterpreterInterface $argumentInterpreter
+     */
+    public function __construct(ObjectManagerInterface $objectManager, InterpreterInterface $argumentInterpreter)
+    {
+        $this->objectManager = $objectManager;
+        $this->argumentInterpreter = $argumentInterpreter;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function evaluate(array $data)
+    {
+        if (!isset($data['argument'])) {
+            throw new \InvalidArgumentException('Node "argument" required for this type.');
+        }
+        foreach ($data['argument'] as $name => $argument) {
+            $arguments[$name] = $this->argumentInterpreter->evaluate($argument);
+        }
+        if (!isset($arguments['class'])) {
+            throw new \InvalidArgumentException('Node "argument" with name "class" is required for this type.');
+        }
+        $className = $arguments['class'];
+        unset($arguments['class']);
+
+        return $this->objectManager->create($className, $arguments);
+    }
+}
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/ArrayObjectFactory.php b/lib/internal/Magento/Framework/View/Element/UiComponent/ArrayObjectFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..64c4cffc8cb596e60697e245c36ef9e526284f3f
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/ArrayObjectFactory.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\View\Element\UiComponent;
+
+/**
+ * Class ArrayObjectFactory
+ */
+class ArrayObjectFactory
+{
+    /**
+     * Create class instance with specified parameters
+     *
+     * @param array $data
+     * @return \ArrayObject
+     */
+    public function create(array $data = [])
+    {
+        return new \ArrayObject($data);
+    }
+}
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Config/Converter.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/Converter.php
new file mode 100644
index 0000000000000000000000000000000000000000..bf13c675696839882895b842a4e2b2252e64ff5f
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/Converter.php
@@ -0,0 +1,123 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\View\Element\UiComponent\Config;
+
+use Magento\Framework\Config\ConverterInterface;
+use Magento\Framework\View\Layout\Argument\Parser;
+
+/**
+ * Class Converter
+ */
+class Converter implements ConverterInterface
+{
+    /**
+     * The key attributes of a node
+     */
+    const DATA_ATTRIBUTES_KEY = '@attributes';
+
+    /**
+     * The key for the data arguments
+     */
+    const DATA_ARGUMENTS_KEY = '@arguments';
+
+    /**
+     * The key of the argument node
+     */
+    const ARGUMENT_KEY = 'argument';
+
+    /**
+     * Key name attribute value
+     */
+    const NAME_ATTRIBUTE_KEY = 'name';
+
+    /**
+     * @var Parser
+     */
+    protected $argumentParser;
+
+    /**
+     * Constructor
+     *
+     * @param Parser $argumentParser
+     */
+    public function __construct(Parser $argumentParser)
+    {
+        $this->argumentParser = $argumentParser;
+    }
+
+    /**
+     * Transform Xml to array
+     *
+     * @param \DOMNode $node
+     * @return array|string
+     *
+     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+     * @SuppressWarnings(PHPMD.NPathComplexity)
+     */
+    protected function toArray(\DOMNode $node)
+    {
+        $result = [];
+        $attributes = [];
+        // Collect data from attributes
+        if ($node->hasAttributes()) {
+            foreach ($node->attributes as $attribute) {
+                $attributes[$attribute->name] = $attribute->value;
+            }
+        }
+        switch ($node->nodeType) {
+            case XML_TEXT_NODE:
+            case XML_COMMENT_NODE:
+            case XML_CDATA_SECTION_NODE:
+                break;
+            default:
+                if ($node->localName === static::ARGUMENT_KEY) {
+                    if (!isset($attributes[static::NAME_ATTRIBUTE_KEY])) {
+                        throw new \InvalidArgumentException(
+                            'Attribute "' . static::NAME_ATTRIBUTE_KEY . '" is absent in the attributes node.'
+                        );
+                    }
+                    $result[ $attributes[static::NAME_ATTRIBUTE_KEY] ] = $this->argumentParser->parse($node);
+                } else {
+                    $arguments = [];
+                    for ($i = 0, $iLength = $node->childNodes->length; $i < $iLength; ++$i) {
+                        $itemNode = $node->childNodes->item($i);
+                        if (empty($itemNode->localName)) {
+                            continue;
+                        }
+                        if ($itemNode->nodeName === static::ARGUMENT_KEY) {
+                            $arguments += $this->toArray($itemNode);
+                        } else {
+                            $result[$itemNode->localName][] = $this->toArray($itemNode);
+                        }
+                    }
+                    if (!empty($arguments)) {
+                        $result[static::DATA_ARGUMENTS_KEY] = $arguments;
+                    }
+                    if (!empty($attributes)) {
+                        $result[static::DATA_ATTRIBUTES_KEY] = $attributes;
+                    }
+                }
+                break;
+        }
+
+        return $result;
+    }
+
+    /**
+     * Convert configuration
+     *
+     * @param \DOMDocument|null $source
+     * @return array
+     */
+    public function convert($source)
+    {
+        if ($source === null) {
+            return [];
+        }
+
+        return $this->toArray($source);
+    }
+}
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Config/DomMerger.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/DomMerger.php
new file mode 100644
index 0000000000000000000000000000000000000000..72b18bb610577f7218ef4615f0d7cde0cf3d421e
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/DomMerger.php
@@ -0,0 +1,455 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\View\Element\UiComponent\Config;
+
+use Magento\Framework\Config\Dom;
+use Magento\Framework\Module\Dir\Reader as DirectoryReader;
+
+/**
+ * Class DomMerger
+ */
+class DomMerger implements DomMergerInterface
+{
+    /**
+     * Format of items in errors array to be used by default. Available placeholders - fields of \LibXMLError.
+     */
+    const ERROR_FORMAT_DEFAULT = "Message: %message%\nLine: %line%\n";
+
+    /**
+     * Location schema file
+     *
+     * @var string
+     */
+    protected $schemaFilePath;
+
+    /**
+     * Result DOM document
+     *
+     * @var \DOMDocument
+     */
+    protected $domDocument;
+
+    /**
+     * Id attribute list
+     *
+     * @var array
+     */
+    protected $idAttributes = [];
+
+    /**
+     * Context XPath
+     *
+     * @var array
+     */
+    protected $contextXPath = [];
+
+    /**
+     * Is merge simple XML Element
+     *
+     * @var bool
+     */
+    protected $isMergeSimpleXMLElement;
+
+    /**
+     * Build DOM with initial XML contents and specifying identifier attributes for merging
+     *
+     * Format of $schemaFileType: array('etc', 'sql', 'data', 'i18n', 'view', 'Controller')
+     * Format of $schemaFileModule: 'Magento_XXXXX'
+     * Format of $schemaFileName: 'schema.xsd'
+     * Format of $idAttributes: array('name', 'id')
+     * Format of $contextXPath: array('/config/ui')
+     * The path to ID attribute name should not include any attribute notations or modifiers -- only node names
+     *
+     * @param string $schemaFileType
+     * @param string $schemaFileModule
+     * @param string $schemaFileName
+     * @param DirectoryReader $directoryReader
+     * @param bool $isMergeSimpleXMLElement
+     * @param array $contextXPath
+     * @param array $idAttributes
+     */
+    public function __construct(
+        DirectoryReader $directoryReader,
+        $schemaFileType,
+        $schemaFileModule,
+        $schemaFileName,
+        $isMergeSimpleXMLElement = false,
+        array $contextXPath = [],
+        array $idAttributes = []
+    ) {
+        $this->schemaFilePath = $directoryReader->getModuleDir($schemaFileType, $schemaFileModule) . '/'
+            . trim($schemaFileName, '/');
+        $this->isMergeSimpleXMLElement = $isMergeSimpleXMLElement;
+        $this->contextXPath = $contextXPath;
+        $this->idAttributes = $idAttributes;
+    }
+
+    /**
+     * Is id attribute
+     *
+     * @param string $attributeName
+     * @return bool
+     */
+    protected function isIdAttribute($attributeName)
+    {
+        return in_array($attributeName, $this->idAttributes);
+    }
+
+    /**
+     * Is merge context
+     *
+     * @param string $xPath
+     * @return bool
+     */
+    protected function isMergeContext($xPath)
+    {
+        foreach ($this->contextXPath as $context) {
+            if (strpos($xPath, $context) === 0) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Is context XPath
+     *
+     * @param array $xPath
+     * @return bool
+     */
+    protected function isContextXPath(array $xPath)
+    {
+        return count(array_intersect($xPath, $this->contextXPath)) === count($xPath);
+    }
+
+    /**
+     * Merges attributes of the merge node to the base node
+     *
+     * @param \DOMElement $baseNode
+     * @param \DOMNode $mergeNode
+     * @return void
+     */
+    protected function mergeAttributes(\DOMElement $baseNode, \DOMNode $mergeNode)
+    {
+        foreach ($mergeNode->attributes as $name => $attribute) {
+            $baseNode->setAttribute($name, $attribute->value);
+        }
+    }
+
+    /**
+     * Create XPath
+     *
+     * @param \DOMNode $node
+     * @return string
+     */
+    protected function createXPath(\DOMNode $node)
+    {
+        $parentXPath = '';
+        $currentXPath = $node->getNodePath();
+        if ($node->parentNode !== null && !$node->isSameNode($node->parentNode)) {
+            $parentXPath = $this->createXPath($node->parentNode);
+            $pathParts = explode('/', $currentXPath);
+            $currentXPath = '/' . end($pathParts);
+        }
+        $attributesXPath = '';
+        if ($node->hasAttributes()) {
+            $attributes = [];
+            foreach ($node->attributes as $name => $attribute) {
+                if ($this->isIdAttribute($name)) {
+                    $attributes[] = sprintf('@%s="%s"', $name, $attribute->value);
+                    break;
+                }
+            }
+            if (!empty($attributes)) {
+                if (substr($currentXPath, -1) === ']') {
+                    $currentXPath = substr($currentXPath, 0, strrpos($currentXPath, '['));
+                }
+                $attributesXPath = '[' . implode(' and ', $attributes) . ']';
+            }
+        }
+        return '/' . trim($parentXPath . $currentXPath . $attributesXPath, '/');
+    }
+
+    /**
+     * Merge nested xml nodes
+     *
+     * @param \DOMXPath $rootDomXPath
+     * @param \DOMNodeList $insertedNodes
+     * @param \DOMNode $contextNode
+     * @return void
+     *
+     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+     * @SuppressWarnings(PHPMD.NPathComplexity)
+     */
+    protected function nestedMerge(\DOMXPath $rootDomXPath, \DOMNodeList $insertedNodes, \DOMNode $contextNode)
+    {
+        for ($i = 0, $iLength = $insertedNodes->length; $i < $iLength; ++$i) {
+            $insertedItem = $insertedNodes->item($i);
+            switch ($insertedItem->nodeType) {
+                case XML_TEXT_NODE:
+                case XML_COMMENT_NODE:
+                case XML_CDATA_SECTION_NODE:
+                    if (trim($insertedItem->textContent) !== '') {
+                        $this->insertBefore($contextNode, $insertedItem);
+                    }
+                    break;
+                default:
+                    $insertedXPath = $this->createXPath($insertedItem);
+                    $rootMatchList = $rootDomXPath->query($insertedXPath, $contextNode);
+                    $jLength = $rootMatchList->length;
+                    if ($jLength > 0) {
+                        for ($j = 0; $j < $jLength; ++$j) {
+                            $rootItem = $rootMatchList->item($j);
+                            $rootItemXPath = $this->createXPath($rootItem);
+                            if ($this->isMergeContext($insertedXPath)) {
+                                if ($this->isTextNode($insertedItem) && $this->isTextNode($rootItem)) {
+                                    $rootItem->nodeValue = $insertedItem->nodeValue;
+                                } else if (!$this->isContextXPath([$rootItemXPath, $insertedXPath])
+                                    && !$this->hasIdAttribute($rootItem)
+                                    && !$this->hasIdAttribute($insertedItem)
+                                ) {
+                                    if ($this->isMergeSimpleXMLElement) {
+                                        $this->nestedMerge($rootDomXPath, $insertedItem->childNodes, $rootItem);
+                                        $this->mergeAttributes($rootItem, $insertedItem);
+                                    } else {
+                                        $this->appendChild($contextNode, $insertedItem);
+                                    }
+                                } else {
+                                    $this->nestedMerge($rootDomXPath, $insertedItem->childNodes, $rootItem);
+                                    $this->mergeAttributes($rootItem, $insertedItem);
+                                }
+                            } else {
+                                $this->appendChild($contextNode, $insertedItem);
+                            }
+                        }
+                    } else {
+                        $this->appendChild($contextNode, $insertedItem);
+                    }
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Append child node
+     *
+     * @param \DOMNode $parentNode
+     * @param \DOMNode $childNode
+     * @return void
+     */
+    protected function appendChild(\DOMNode $parentNode, \DOMNode $childNode)
+    {
+        $importNode = $this->getDom()->importNode($childNode, true);
+        $parentNode->appendChild($importNode);
+    }
+
+    /**
+     * Insert before
+     *
+     * @param \DOMNode $parentNode
+     * @param \DOMNode $childNode
+     * @return void
+     */
+    protected function insertBefore(\DOMNode $parentNode, \DOMNode $childNode)
+    {
+        $importNode = $this->getDom()->importNode($childNode, true);
+        $parentNode->insertBefore($importNode);
+    }
+
+    /**
+     * Check if the node content is text
+     *
+     * @param \DOMNode $node
+     * @return bool
+     */
+    protected function isTextNode(\DOMNode $node)
+    {
+        return $node->childNodes->length == 1 && $node->childNodes->item(0) instanceof \DOMText;
+    }
+
+    /**
+     * Has ID attribute
+     *
+     * @param \DOMNode $node
+     * @return bool
+     * @SuppressWarnings(PHPMD.UnusedLocalVariable)
+     */
+    protected function hasIdAttribute(\DOMNode $node)
+    {
+        if (!$node->hasAttributes()) {
+            return false;
+        }
+
+        foreach ($node->attributes as $name => $attribute) {
+            if (in_array($name, $this->idAttributes)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Recursive merging of the \DOMElement into the original document
+     *
+     * Algorithm:
+     * 1. Find the same node in original document
+     * 2. Extend and override original document node attributes and scalar value if found
+     * 3. Append new node if original document doesn't have the same node
+     *
+     * @param \DOMElement $node
+     * @throws \Magento\Framework\Exception\LocalizedException
+     * @return void
+     */
+    public function mergeNode(\DOMElement $node)
+    {
+        $parentDoom = $this->getDom();
+        $this->nestedMerge(new \DOMXPath($parentDoom), $node->childNodes, $parentDoom->documentElement);
+    }
+
+    /**
+     * Create DOM document based on $xml parameter
+     *
+     * @param string $xml
+     * @return \DOMDocument
+     * @throws \Magento\Framework\Exception\LocalizedException
+     */
+    public function createDomDocument($xml)
+    {
+        $domDocument = new \DOMDocument();
+        $domDocument->loadXML($xml);
+        if ($this->schemaFilePath) {
+            $errors = $this->validateDomDocument($domDocument);
+            if (count($errors)) {
+                throw new \Magento\Framework\Exception\LocalizedException(implode("\n", $errors));
+            }
+        }
+
+        return $domDocument;
+    }
+
+    /**
+     * Validate dom document
+     *
+     * @param \DOMDocument $domDocument
+     * @param string|null $schemaFilePath
+     * @return array of errors
+     * @throws \Exception
+     */
+    protected function validateDomDocument(\DOMDocument $domDocument, $schemaFilePath = null)
+    {
+        $schemaFilePath = $schemaFilePath !== null ? $schemaFilePath : $this->schemaFilePath;
+        libxml_use_internal_errors(true);
+        try {
+            $result = $domDocument->schemaValidate($schemaFilePath);
+            $errors = [];
+            if (!$result) {
+                $validationErrors = libxml_get_errors();
+                if (count($validationErrors)) {
+                    foreach ($validationErrors as $error) {
+                        $errors[] = $this->renderErrorMessage($error, static::ERROR_FORMAT_DEFAULT);
+                    }
+                } else {
+                    $errors[] = 'Unknown validation error';
+                }
+            }
+        } catch (\Exception $exception) {
+            libxml_use_internal_errors(false);
+            throw $exception;
+        }
+        libxml_use_internal_errors(false);
+
+        return $errors;
+    }
+
+    /**
+     * Render error message string by replacing placeholders '%field%' with properties of \LibXMLError
+     *
+     * @param \LibXMLError $errorInfo
+     * @return string
+     * @throws \Magento\Framework\Exception\LocalizedException
+     */
+    protected function renderErrorMessage(\LibXMLError $errorInfo)
+    {
+        $result = static::ERROR_FORMAT_DEFAULT;
+        foreach ($errorInfo as $field => $value) {
+            $result = str_replace('%' . $field . '%', trim((string)$value), $result);
+        }
+        if (strpos($result, '%') !== false) {
+            throw new \Magento\Framework\Exception\LocalizedException(
+                new \Magento\Framework\Phrase(
+                    'Error format "' . static::ERROR_FORMAT_DEFAULT . '" contains unsupported placeholders.'
+                )
+            );
+        }
+
+        return $result;
+    }
+
+    /**
+     * Merge string $xml into DOM document
+     *
+     * @param string $xml
+     * @return void
+     */
+    public function merge($xml)
+    {
+        if (!isset($this->domDocument)) {
+            $this->domDocument = $this->createDomDocument($xml);
+        } else {
+            $this->mergeNode($this->createDomDocument($xml)->documentElement);
+        }
+    }
+
+    /**
+     * Get DOM document
+     *
+     * @return \DOMDocument
+     * @throws \Magento\Framework\Exception\LocalizedException
+     */
+    public function getDom()
+    {
+        if (!isset($this->domDocument)) {
+            throw new \Magento\Framework\Exception\LocalizedException(
+                new \Magento\Framework\Phrase('Object DOMDocument should be created.')
+            );
+        }
+
+        return $this->domDocument;
+    }
+
+    /**
+     * Set DOM document
+     *
+     * @param \DOMDocument $domDocument
+     * @return void
+     */
+    public function setDom(\DOMDocument $domDocument)
+    {
+        $this->domDocument = $domDocument;
+    }
+
+    /**
+     * Unset DOM document
+     *
+     * @return void
+     */
+    public function unsetDom()
+    {
+        unset($this->domDocument);
+    }
+
+    /**
+     * Validate self contents towards to specified schema
+     *
+     * @param string|null $schemaFilePath
+     * @return array
+     */
+    public function validate($schemaFilePath = null)
+    {
+        return $this->validateDomDocument($this->getDom(), $schemaFilePath);
+    }
+}
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Config/DomMergerInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/DomMergerInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..0fe94609ccebb4fc3c10b20e902d1e5ab49e494c
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/DomMergerInterface.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\View\Element\UiComponent\Config;
+
+/**
+ * Interface DomMergerInterface
+ */
+interface DomMergerInterface
+{
+    /**
+     * Merge $xml into DOM document
+     *
+     * @param string $xml
+     * @return void
+     */
+    public function merge($xml);
+
+    /**
+     * Recursive merging of the \DOMElement into the original document
+     *
+     * Algorithm:
+     * 1. Find the same node in original document
+     * 2. Extend and override original document node attributes and scalar value if found
+     * 3. Append new node if original document doesn't have the same node
+     *
+     * @param \DOMElement $node
+     * @throws \Magento\Framework\Exception\LocalizedException
+     * @return void
+     */
+    public function mergeNode(\DOMElement $node);
+
+    /**
+     * Get DOM document
+     *
+     * @return \DOMDocument
+     */
+    public function getDom();
+
+    /**
+     * Set DOM document
+     *
+     * @param \DOMDocument $domDocument
+     * @return void
+     */
+    public function setDom(\DOMDocument $domDocument);
+
+    /**
+     * Unset DOM document
+     *
+     * @return void
+     */
+    public function unsetDom();
+
+    /**
+     * Validate self contents towards to specified schema
+     *
+     * @param string $schemaFileName
+     * @return array
+     */
+    public function validate($schemaFileName);
+}
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Config/FileCollector/AggregatedFileCollector.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/FileCollector/AggregatedFileCollector.php
new file mode 100644
index 0000000000000000000000000000000000000000..880b6bc6e1ce75f83cc6dada5ba56a2cc9329a22
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/FileCollector/AggregatedFileCollector.php
@@ -0,0 +1,86 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\View\Element\UiComponent\Config\FileCollector;
+
+use Magento\Framework\Filesystem;
+use Magento\Framework\View\DesignInterface;
+use Magento\Framework\App\Filesystem\DirectoryList;
+use Magento\Framework\View\File\CollectorInterface;
+use Magento\Framework\View\Element\UiComponent\Config\FileCollectorInterface;
+
+/**
+ * Class AggregatedFileCollector
+ */
+class AggregatedFileCollector implements FileCollectorInterface
+{
+    /**
+     * Search pattern
+     *
+     * @var string
+     */
+    protected $searchPattern;
+
+    /**
+     * @var CollectorInterface
+     */
+    protected $collectorAggregated;
+
+    /**
+     * @var DesignInterface
+     */
+    protected $design;
+
+    /**
+     * @var Filesystem
+     */
+    protected $filesystem;
+
+    /**
+     * Constructor
+     *
+     * @param CollectorInterface $collectorAggregated
+     * @param DesignInterface $design
+     * @param Filesystem $filesystem
+     * @param string $searchPattern
+     */
+    public function __construct(
+        CollectorInterface $collectorAggregated,
+        DesignInterface $design,
+        Filesystem $filesystem,
+        $searchPattern = null
+    ) {
+        $this->searchPattern = $searchPattern;
+        $this->collectorAggregated = $collectorAggregated;
+        $this->design = $design;
+        $this->filesystem = $filesystem;
+    }
+
+    /**
+     * Collect files
+     *
+     * @param string|null $searchPattern
+     * @return array
+     * @throws \Exception
+     */
+    public function collectFiles($searchPattern = null)
+    {
+        $result = [];
+        if ($searchPattern === null) {
+            $searchPattern = $this->searchPattern;
+        }
+        if ($searchPattern === null) {
+            throw new \Exception('Search pattern cannot be empty.');
+        }
+        $files = $this->collectorAggregated->getFiles($this->design->getDesignTheme(), $searchPattern);
+        $fileReader = $this->filesystem->getDirectoryRead(DirectoryList::ROOT);
+        foreach ($files as $file) {
+            $filePath = $fileReader->getRelativePath($file->getFilename());
+            $result[sprintf('%x', crc32($filePath))] = $fileReader->readFile($filePath);
+        }
+
+        return $result;
+    }
+}
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Config/FileCollector/AggregatedFileCollectorFactory.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/FileCollector/AggregatedFileCollectorFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..609156211828e0afc6e5f505211e2aea2ed1a766
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/FileCollector/AggregatedFileCollectorFactory.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\View\Element\UiComponent\Config\FileCollector;
+
+use Magento\Framework\ObjectManagerInterface;
+
+/**
+ * Class AggregatedFileCollectorFactory
+ */
+class AggregatedFileCollectorFactory
+{
+    const INSTANCE_NAME = 'Magento\Framework\View\Element\UiComponent\Config\FileCollector\AggregatedFileCollector';
+
+    /**
+     * @var ObjectManagerInterface
+     */
+    protected $objectManager;
+
+    /**
+     * Constructor
+     *
+     * @param ObjectManagerInterface $objectManager
+     */
+    public function __construct(ObjectManagerInterface $objectManager)
+    {
+        $this->objectManager = $objectManager;
+    }
+
+    /**
+     * Create config reader
+     *
+     * @param array $arguments
+     * @return AggregatedFileCollector
+     */
+    public function create(array $arguments = [])
+    {
+        return $this->objectManager->create(static::INSTANCE_NAME, $arguments);
+    }
+}
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Config/FileCollectorInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/FileCollectorInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..c2f74254bed42237886c862978d5a7c889c190ba
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/FileCollectorInterface.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\View\Element\UiComponent\Config;
+
+/**
+ * Interface FileCollectorInterface
+ */
+interface FileCollectorInterface
+{
+    /**
+     * Collect files
+     *
+     * @param string|null $searchPattern
+     * @return array
+     */
+    public function collectFiles($searchPattern = null);
+}
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Config/Manager.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/Manager.php
new file mode 100644
index 0000000000000000000000000000000000000000..a43e1aeacc804ecfc745b6223447538ab9355734
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/Manager.php
@@ -0,0 +1,331 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\View\Element\UiComponent\Config;
+
+use ArrayObject;
+use Magento\Framework\Exception\LocalizedException;
+use Magento\Framework\Config\CacheInterface;
+use Magento\Framework\View\Element\UiComponent\ArrayObjectFactory;
+use Magento\Framework\View\Element\UiComponent\Config\FileCollector\AggregatedFileCollectorFactory;
+use Magento\Framework\View\Element\UiComponent\Config\Provider\Component\Definition as ComponentDefinition;
+
+/**
+ * Class Manager
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
+class Manager implements ManagerInterface
+{
+    /**
+     * ID in the storage cache
+     */
+    const CACHE_ID = 'ui_component_configuration_data';
+
+    /**
+     * Configuration provider for UI component
+     *
+     * @var ComponentDefinition
+     */
+    protected $componentConfigProvider;
+
+    /**
+     * DOM document merger
+     *
+     * @var DomMergerInterface
+     */
+    protected $domMerger;
+
+    /**
+     * Factory for UI config reader
+     *
+     * @var ReaderFactory
+     */
+    protected $readerFactory;
+
+    /**
+     * Component data
+     *
+     * @var ArrayObject
+     */
+    protected $componentsData;
+
+    /**
+     * Components pool
+     *
+     * @var ArrayObject
+     */
+    protected $componentsPool;
+
+    /**
+     * Factory for ArrayObject
+     *
+     * @var ArrayObjectFactory
+     */
+    protected $arrayObjectFactory;
+
+    /**
+     * @var AggregatedFileCollectorFactory
+     */
+    protected $aggregatedFileCollectorFactory;
+
+    /**
+     * @var CacheInterface
+     */
+    protected $cache;
+
+    /**
+     * @var UiReaderInterface[]
+     */
+    protected $uiReader;
+
+    /**
+     * Constructor
+     *
+     * @param ComponentDefinition $componentConfigProvider
+     * @param DomMergerInterface $domMerger
+     * @param ReaderFactory $readerFactory
+     * @param ArrayObjectFactory $arrayObjectFactory
+     * @param AggregatedFileCollectorFactory $aggregatedFileCollectorFactory
+     * @param CacheInterface $cache
+     */
+    public function __construct(
+        ComponentDefinition $componentConfigProvider,
+        DomMergerInterface $domMerger,
+        ReaderFactory $readerFactory,
+        ArrayObjectFactory $arrayObjectFactory,
+        AggregatedFileCollectorFactory $aggregatedFileCollectorFactory,
+        CacheInterface $cache
+    ) {
+        $this->componentConfigProvider = $componentConfigProvider;
+        $this->domMerger = $domMerger;
+        $this->readerFactory = $readerFactory;
+        $this->arrayObjectFactory = $arrayObjectFactory;
+        $this->componentsData = $this->arrayObjectFactory->create();
+        $this->aggregatedFileCollectorFactory = $aggregatedFileCollectorFactory;
+        $this->cache = $cache;
+    }
+
+    /**
+     * Get component data
+     *
+     * @param string $name
+     * @return array
+     */
+    public function getData($name)
+    {
+        return (array) $this->componentsData->offsetGet($name);
+    }
+
+    /**
+     * Has component data
+     *
+     * @param string $name
+     * @return bool
+     */
+    protected function hasData($name)
+    {
+        return $this->componentsData->offsetExists($name);
+    }
+
+    /**
+     * Prepare the initialization data of UI components
+     *
+     * @param string $name
+     * @return ManagerInterface
+     * @throws \Magento\Framework\Exception\LocalizedException
+     */
+    public function prepareData($name)
+    {
+        if ($name === null || $this->hasData($name)) {
+            throw new LocalizedException(
+                new \Magento\Framework\Phrase(
+                    'Initialization error component, check the '
+                    . 'spelling of the name or the correctness of the call.'
+                )
+            );
+        }
+        $this->componentsPool = $this->arrayObjectFactory->create();
+
+        $cacheID = static::CACHE_ID . '_' . $name;
+        $cachedPool = $this->cache->load($cacheID);
+        if ($cachedPool === false) {
+            $this->prepare($name);
+            $this->cache->save($this->componentsPool->serialize(), $cacheID);
+        } else {
+            $this->componentsPool->unserialize($cachedPool);
+        }
+        $this->componentsData->offsetSet($name, $this->componentsPool);
+
+        return $this;
+    }
+
+    /**
+     * To create the raw  data components
+     *
+     * @param string $component
+     * @return array
+     */
+    public function createRawComponentData($component)
+    {
+        $componentData = $this->componentConfigProvider->getComponentData($component);
+        $componentData[Converter::DATA_ATTRIBUTES_KEY] = isset($componentData[Converter::DATA_ATTRIBUTES_KEY])
+            ? $componentData[Converter::DATA_ATTRIBUTES_KEY]
+            : [];
+        $componentData[Converter::DATA_ARGUMENTS_KEY] = isset($componentData[Converter::DATA_ARGUMENTS_KEY])
+            ? $componentData[Converter::DATA_ARGUMENTS_KEY]
+            : [];
+
+        return [
+            ManagerInterface::COMPONENT_ATTRIBUTES_KEY => $componentData[Converter::DATA_ATTRIBUTES_KEY],
+            ManagerInterface::COMPONENT_ARGUMENTS_KEY => $componentData[Converter::DATA_ARGUMENTS_KEY],
+        ];
+    }
+
+    /**
+     * Get UIReader and collect base files configuration
+     *
+     * @param string $name
+     * @return UiReaderInterface
+     */
+    public function getReader($name)
+    {
+        if (!isset($this->uiReader[$name])) {
+            $this->domMerger->unsetDom();
+            $this->uiReader[$name] =  $this->readerFactory->create(
+                [
+                    'fileCollector' => $this->aggregatedFileCollectorFactory->create(
+                        ['searchPattern' => sprintf(ManagerInterface::SEARCH_PATTERN, $name)]
+                    ),
+                    'domMerger' => $this->domMerger
+                ]
+            );
+        }
+
+        return $this->uiReader[$name];
+    }
+
+    /**
+     * Initialize the new component data
+     *
+     * @param string $name
+     * @return void
+     */
+    protected function prepare($name)
+    {
+        $componentData = $this->getReader($name)->read();
+        $componentsPool = reset($componentData);
+        $componentsPool = reset($componentsPool);
+        $componentsPool[Converter::DATA_ATTRIBUTES_KEY] = array_merge(
+            ['name' => $name],
+            $componentsPool[Converter::DATA_ATTRIBUTES_KEY]
+        );
+        $components = $this->createDataForComponent(key($componentData), [$componentsPool]);
+        $this->addComponentIntoPool($name, reset($components));
+    }
+
+    /**
+     * Create data for component instance
+     *
+     * @param string $name
+     * @param array $componentsPool
+     * @return array
+     */
+    protected function createDataForComponent($name, array $componentsPool)
+    {
+        $createdComponents = [];
+        $rootComponent = $this->createRawComponentData($name);
+        foreach ($componentsPool as $key => $component) {
+            $resultConfiguration = [ManagerInterface::CHILDREN_KEY => []];
+            $instanceName = $this->createName($component, $key, $name);
+            $resultConfiguration[ManagerInterface::COMPONENT_ARGUMENTS_KEY] = $this->mergeArguments(
+                $component,
+                $rootComponent
+            );
+            unset($component[Converter::DATA_ARGUMENTS_KEY]);
+            $resultConfiguration[ManagerInterface::COMPONENT_ATTRIBUTES_KEY] = $this->mergeAttributes(
+                $component,
+                $rootComponent
+            );
+            unset($component[Converter::DATA_ATTRIBUTES_KEY]);
+            // Create inner components
+            foreach ($component as $subComponentName => $subComponent) {
+                $resultConfiguration[ManagerInterface::CHILDREN_KEY] = array_merge(
+                    $resultConfiguration[ManagerInterface::CHILDREN_KEY],
+                    $this->createDataForComponent($subComponentName, $subComponent)
+                );
+            }
+            $createdComponents[$instanceName] = $resultConfiguration;
+        }
+
+        return $createdComponents;
+    }
+
+    /**
+     * Add a component into pool
+     *
+     * @param string $instanceName
+     * @param array $configuration
+     * @return void
+     */
+    protected function addComponentIntoPool($instanceName, array $configuration)
+    {
+        $this->componentsPool->offsetSet($instanceName, $configuration);
+    }
+
+    /**
+     * Merge component arguments
+     *
+     * @param array $componentData
+     * @param array $rootComponentData
+     * @return array
+     */
+    protected function mergeArguments(array $componentData, array $rootComponentData)
+    {
+        $baseArguments = isset($rootComponentData[ManagerInterface::COMPONENT_ARGUMENTS_KEY])
+            ? $rootComponentData[ManagerInterface::COMPONENT_ARGUMENTS_KEY]
+            : [];
+        $componentArguments = isset($componentData[Converter::DATA_ARGUMENTS_KEY])
+            ? $componentData[Converter::DATA_ARGUMENTS_KEY]
+            : [];
+
+        return array_replace_recursive($baseArguments, $componentArguments);
+    }
+
+    /**
+     * Merge component attributes
+     *
+     * @param array $componentData
+     * @param array $rootComponentData
+     * @return array
+     */
+    protected function mergeAttributes(array $componentData, array $rootComponentData)
+    {
+        $baseAttributes = isset($rootComponentData[ManagerInterface::COMPONENT_ATTRIBUTES_KEY])
+            ? $rootComponentData[ManagerInterface::COMPONENT_ATTRIBUTES_KEY]
+            : [];
+        $componentAttributes = isset($componentData[Converter::DATA_ATTRIBUTES_KEY])
+            ? $componentData[Converter::DATA_ATTRIBUTES_KEY]
+            : [];
+        unset($componentAttributes['noNamespaceSchemaLocation']);
+
+        return array_replace_recursive($baseAttributes, $componentAttributes);
+    }
+
+    /**
+     * Create name component instance
+     *
+     * @param array $componentData
+     * @param string|int $key
+     * @param string $componentName
+     * @return string
+     */
+    protected function createName(array $componentData, $key, $componentName)
+    {
+        return isset($componentData[Converter::DATA_ATTRIBUTES_KEY][Converter::NAME_ATTRIBUTE_KEY])
+            ? $componentData[Converter::DATA_ATTRIBUTES_KEY][Converter::NAME_ATTRIBUTE_KEY]
+            : sprintf(ManagerInterface::ANONYMOUS_TEMPLATE, $componentName, $key);
+    }
+}
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Config/ManagerInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/ManagerInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..29f26032ad8ffc7e5efafc5274718aaa49480a21
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/ManagerInterface.php
@@ -0,0 +1,72 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\View\Element\UiComponent\Config;
+
+use Magento\Framework\Exception\LocalizedException;
+
+/**
+ * Interface ManagerInterface
+ */
+interface ManagerInterface
+{
+    /**
+     * Search pattern
+     */
+    const SEARCH_PATTERN = '%s.xml';
+
+    /**
+     * The anonymous template name
+     */
+    const ANONYMOUS_TEMPLATE = 'anonymous_%s_component_%d';
+
+    /**
+     * The key arguments in the data component
+     */
+    const COMPONENT_ARGUMENTS_KEY = 'arguments';
+
+    /**
+     * The key attributes in the data component
+     */
+    const COMPONENT_ATTRIBUTES_KEY = 'attributes';
+
+    /**
+     * The array key sub components
+     */
+    const CHILDREN_KEY = 'children';
+
+    /**
+     * Prepare the initialization data of UI components
+     *
+     * @param string $name
+     * @return ManagerInterface
+     * @throws \Magento\Framework\Exception\LocalizedException
+     */
+    public function prepareData($name);
+
+    /**
+     * Get component data
+     *
+     * @param string $name
+     * @return array
+     */
+    public function getData($name);
+
+    /**
+     * To create the raw  data components
+     *
+     * @param string $component
+     * @return array
+     */
+    public function createRawComponentData($component);
+
+    /**
+     * Get UIReader and collect base files configuration
+     *
+     * @param string $name
+     * @return UiReaderInterface
+     */
+    public function getReader($name);
+}
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Config/Provider/Component/Definition.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/Provider/Component/Definition.php
new file mode 100644
index 0000000000000000000000000000000000000000..7e7e27bed013d0205c3f2f00c2112b9ba635b39e
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/Provider/Component/Definition.php
@@ -0,0 +1,101 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\View\Element\UiComponent\Config\Provider\Component;
+
+use Magento\Framework\Config\CacheInterface;
+use Magento\Framework\View\Element\UiComponent\Config\Converter;
+use Magento\Framework\View\Element\UiComponent\ArrayObjectFactory;
+use Magento\Framework\View\Element\UiComponent\Config\UiReaderInterface;
+
+/**
+ * Class Definition
+ */
+class Definition
+{
+    /**
+     * ID in the storage cache
+     */
+    const CACHE_ID = 'ui_component_definition_data';
+
+    /**
+     * Components node name in config
+     */
+    const COMPONENTS_KEY = 'components';
+
+    /**
+     * @var CacheInterface
+     */
+    protected $cache;
+
+    /**
+     * UI component data
+     *
+     * @var \ArrayObject
+     */
+    protected $componentData;
+
+    /**
+     * Constructor
+     *
+     * @param UiReaderInterface $uiReader
+     * @param ArrayObjectFactory $arrayObjectFactory
+     * @param CacheInterface $cache
+     */
+    public function __construct(
+        UiReaderInterface $uiReader,
+        ArrayObjectFactory $arrayObjectFactory,
+        CacheInterface $cache
+    ) {
+        $this->cache = $cache;
+        $this->componentData = $arrayObjectFactory->create();
+        $cachedData = $this->cache->load(static::CACHE_ID);
+        if ($cachedData === false) {
+            $data = $uiReader->read();
+            $this->cache->save(serialize($data), static::CACHE_ID);
+        } else {
+            $data = unserialize($cachedData);
+        }
+        $this->prepareComponentData($data);
+    }
+
+    /**
+     * Get component data
+     *
+     * @param string $name
+     * @return array
+     */
+    public function getComponentData($name)
+    {
+        return (array) $this->componentData->offsetGet($name);
+    }
+
+    /**
+     * Set component data
+     *
+     * @param string $name
+     * @param array $data
+     * @return void
+     */
+    public function setComponentData($name, array $data)
+    {
+        $this->componentData->offsetSet($name, $data);
+    }
+
+    /**
+     * Prepare configuration data for the component
+     *
+     * @param array $componentsData
+     * @return void
+     */
+    protected function prepareComponentData(array $componentsData)
+    {
+        $componentsData = reset($componentsData[static::COMPONENTS_KEY]);
+        unset($componentsData[Converter::DATA_ATTRIBUTES_KEY]);
+        foreach ($componentsData as $name => $data) {
+            $this->setComponentData($name, reset($data));
+        }
+    }
+}
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Config/Provider/Template.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/Provider/Template.php
new file mode 100644
index 0000000000000000000000000000000000000000..1c47f39a1a993e2b80a9e4d0d67fe5e1858dfe6d
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/Provider/Template.php
@@ -0,0 +1,111 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\View\Element\UiComponent\Config\Provider;
+
+use Magento\Framework\Config\CacheInterface;
+use Magento\Framework\View\Element\UiComponent\Config\ReaderFactory;
+use Magento\Framework\View\Element\UiComponent\Config\DomMergerInterface;
+use Magento\Framework\View\Element\UiComponent\Config\FileCollector\AggregatedFileCollector;
+use Magento\Framework\View\Element\UiComponent\Config\FileCollector\AggregatedFileCollectorFactory;
+
+/**
+ * Class Template
+ */
+class Template
+{
+    /**
+     * Components node name in config
+     */
+    const TEMPLATE_KEY = 'template';
+
+    /**
+     * ID in the storage cache
+     */
+    const CACHE_ID = 'ui_component_templates';
+
+    /**
+     * @var AggregatedFileCollector
+     */
+    protected $aggregatedFileCollector;
+
+    /**
+     * @var DomMergerInterface
+     */
+    protected $domMerger;
+
+    /**
+     * @var CacheInterface
+     */
+    protected $cache;
+
+    /**
+     * Factory for UI config reader
+     *
+     * @var ReaderFactory
+     */
+    protected $readerFactory;
+
+    /**
+     * @var AggregatedFileCollectorFactory
+     */
+    protected $aggregatedFileCollectorFactory;
+
+    /**
+     * @var array
+     */
+    protected $cachedTemplates = [];
+
+    /**
+     * Constructor
+     *
+     * @param AggregatedFileCollector $aggregatedFileCollector
+     * @param DomMergerInterface $domMerger
+     * @param CacheInterface $cache
+     * @param ReaderFactory $readerFactory
+     * @param AggregatedFileCollectorFactory $aggregatedFileCollectorFactory
+     */
+    public function __construct(
+        AggregatedFileCollector $aggregatedFileCollector,
+        DomMergerInterface $domMerger,
+        CacheInterface $cache,
+        ReaderFactory $readerFactory,
+        AggregatedFileCollectorFactory $aggregatedFileCollectorFactory
+    ) {
+        $this->aggregatedFileCollector = $aggregatedFileCollector;
+        $this->domMerger = $domMerger;
+        $this->cache = $cache;
+        $this->readerFactory = $readerFactory;
+        $this->aggregatedFileCollectorFactory = $aggregatedFileCollectorFactory;
+
+        $cachedTemplates = $this->cache->load(static::CACHE_ID);
+        $this->cachedTemplates = $cachedTemplates === false ? [] : unserialize($cachedTemplates);
+    }
+
+    /**
+     * Get template content
+     *
+     * @param string $template
+     * @return string
+     * @throws \Exception
+     */
+    public function getTemplate($template)
+    {
+        $hash = sprintf('%x', crc32($template));
+        if (isset($this->cachedTemplates[$hash])) {
+            return $this->cachedTemplates[$hash];
+        }
+
+        $this->cachedTemplates[$hash] = $this->readerFactory->create(
+            [
+                'fileCollector' => $this->aggregatedFileCollectorFactory->create(['searchPattern' => $template]),
+                'domMerger' => $this->domMerger
+            ]
+        )->getContent();
+        $this->cache->save(serialize($this->cachedTemplates), static::CACHE_ID);
+
+        return $this->cachedTemplates[$hash];
+    }
+}
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Config/Reader.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/Reader.php
new file mode 100644
index 0000000000000000000000000000000000000000..13ddec6465bf1995527ec36381856640f08531fd
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/Reader.php
@@ -0,0 +1,117 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\View\Element\UiComponent\Config;
+
+use Magento\Framework\Filesystem;
+use Magento\Framework\Config\ConverterInterface;
+use Magento\Framework\Config\FileIteratorFactory;
+use Magento\Framework\App\Filesystem\DirectoryList;
+use Magento\Framework\Filesystem\Directory\ReadInterface;
+
+/**
+ * Class Reader
+ */
+class Reader implements UiReaderInterface
+{
+    /**
+     * DOM document merger
+     *
+     * @var DomMergerInterface
+     */
+    protected $domMerger;
+
+    /**
+     * XML converter
+     *
+     * @var ConverterInterface
+     */
+    protected $converter;
+
+    /**
+     * Constructor
+     *
+     * @param FileCollectorInterface $fileCollector
+     * @param ConverterInterface $converter
+     * @param DomMergerInterface $domMerger
+     */
+    public function __construct(
+        FileCollectorInterface $fileCollector,
+        ConverterInterface $converter,
+        DomMergerInterface $domMerger
+    ) {
+        $this->converter = $converter;
+        $this->domMerger = $domMerger;
+        $this->readFiles($fileCollector->collectFiles());
+    }
+
+    /**
+     * Read configuration files
+     *
+     * @param array $fileList
+     * @return array
+     * @throws \Magento\Framework\Exception\LocalizedException
+     */
+    protected function readFiles(array $fileList)
+    {
+        foreach ($fileList as $fileContent) {
+            $this->domMerger->merge($fileContent);
+        }
+    }
+
+    /**
+     * Add xml content in the merged file
+     *
+     * @param string $xmlContent
+     * @return void
+     */
+    public function addXMLContent($xmlContent)
+    {
+        $this->domMerger->merge($xmlContent);
+    }
+
+    /**
+     * Add DOM node into DOM document
+     *
+     * @param \DOMNode $node
+     * @return void
+     */
+    public function addNode(\DOMNode $node)
+    {
+        $this->domMerger->mergeNode($node);
+    }
+
+    /**
+     * Load configuration scope
+     *
+     * @param string|null $scope
+     * @return array
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function read($scope = null)
+    {
+        return $this->converter->convert($this->domMerger->getDom());
+    }
+
+    /**
+     * Get content from the merged files
+     *
+     * @return string
+     */
+    public function getContent()
+    {
+        return $this->domMerger->getDom()->saveXML();
+    }
+
+    /**
+     * Get DOM document
+     *
+     * @return \DOMDocument
+     */
+    public function getDOMDocument()
+    {
+        return $this->domMerger->getDom();
+    }
+}
diff --git a/app/code/Magento/Ui/DataProvider/Factory.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/ReaderFactory.php
similarity index 61%
rename from app/code/Magento/Ui/DataProvider/Factory.php
rename to lib/internal/Magento/Framework/View/Element/UiComponent/Config/ReaderFactory.php
index c24c9d58bee80128958c3062dd41070624f131e9..3efb30cb1141dd4e0621fa1c614caf7665f79a51 100644
--- a/app/code/Magento/Ui/DataProvider/Factory.php
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/ReaderFactory.php
@@ -3,15 +3,17 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-namespace Magento\Ui\DataProvider;
+namespace Magento\Framework\View\Element\UiComponent\Config;
 
 use Magento\Framework\ObjectManagerInterface;
 
 /**
- * Class Factory
+ * Class ReaderFactory
  */
-class Factory
+class ReaderFactory
 {
+    const INSTANCE_NAME = 'Magento\Framework\View\Element\UiComponent\Config\Reader';
+
     /**
      * @var ObjectManagerInterface
      */
@@ -28,14 +30,13 @@ class Factory
     }
 
     /**
-     * Create data provider
+     * Create config reader
      *
-     * @param string $providerClass
      * @param array $arguments
-     * @return mixed
+     * @return UiReaderInterface
      */
-    public function create($providerClass, array $arguments = [])
+    public function create(array $arguments = [])
     {
-        return $this->objectManager->create($providerClass, ['arguments' => $arguments]);
+        return $this->objectManager->create(static::INSTANCE_NAME, $arguments);
     }
 }
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Config/UiReaderInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/UiReaderInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..a9c1915131fab999a939b2bf294eaa745926f15a
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/UiReaderInterface.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\View\Element\UiComponent\Config;
+
+use Magento\Framework\Config\ReaderInterface;
+
+/**
+ * Interface UiReaderInterface
+ */
+interface UiReaderInterface extends ReaderInterface
+{
+    /**
+     * Add xml content in the merged file
+     *
+     * @param string $xmlContent
+     * @return void
+     */
+    public function addXMLContent($xmlContent);
+
+    /**
+     * Get content from the merged files
+     *
+     * @return string
+     */
+    public function getContent();
+
+    /**
+     * Get DOM document
+     *
+     * @return \DOMDocument
+     */
+    public function getDOMDocument();
+
+    /**
+     * Add DOM node into DOM document
+     *
+     * @param \DOMNode $node
+     * @return void
+     */
+    public function addNode(\DOMNode $node);
+}
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigBuilderInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigBuilderInterface.php
deleted file mode 100644
index bba2e86556c49b6eb924e99c2a1e6bec70109dcf..0000000000000000000000000000000000000000
--- a/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigBuilderInterface.php
+++ /dev/null
@@ -1,20 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Framework\View\Element\UiComponent;
-
-/**
- * Interface ConfigBuilderInterface
- */
-interface ConfigBuilderInterface
-{
-    /**
-     * Config data to JSON by output
-     *
-     * @param ConfigInterface $configuration
-     * @return string
-     */
-    public function toJson(ConfigInterface $configuration);
-}
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigFactory.php b/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigFactory.php
deleted file mode 100644
index 9470ec3119f2bba2b1956c0a82d32dbda6d443bb..0000000000000000000000000000000000000000
--- a/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigFactory.php
+++ /dev/null
@@ -1,53 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Framework\View\Element\UiComponent;
-
-use Magento\Framework\ObjectManagerInterface;
-
-/**
- * Class ConfigFactory
- */
-class ConfigFactory
-{
-    /**
-     * Object Manager instance
-     *
-     * @var ObjectManagerInterface
-     */
-    protected $objectManager = null;
-
-    /**
-     * Instance name to create
-     *
-     * @var string
-     */
-    protected $instanceName = null;
-
-    /**
-     * Factory constructor
-     *
-     * @param ObjectManagerInterface $objectManager
-     * @param string $instanceName
-     */
-    public function __construct(
-        ObjectManagerInterface $objectManager,
-        $instanceName = 'Magento\Framework\View\Element\UiComponent\ConfigInterface'
-    ) {
-        $this->objectManager = $objectManager;
-        $this->instanceName = $instanceName;
-    }
-
-    /**
-     * Create class instance with specified parameters
-     *
-     * @param array $data
-     * @return \Magento\Framework\View\Element\UiComponent\ConfigInterface
-     */
-    public function create(array $data = [])
-    {
-        return $this->objectManager->create($this->instanceName, $data);
-    }
-}
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigInterface.php
deleted file mode 100644
index ad665bc3de14e7b1d5470a65f13f498b07b93c83..0000000000000000000000000000000000000000
--- a/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigInterface.php
+++ /dev/null
@@ -1,52 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Framework\View\Element\UiComponent;
-
-/**
- * Class ConfigInterface
- */
-interface ConfigInterface
-{
-    /**
-     * Get configuration data
-     *
-     * @param string|null $key
-     * @return mixed
-     */
-    public function getData($key = null);
-
-    /**
-     * Add configuration data
-     *
-     * @param string $key
-     * @param mixed $data
-     * @return mixed
-     */
-    public function addData($key, $data);
-
-    /**
-     * Update configuration data
-     *
-     * @param string $key
-     * @param mixed $data
-     * @return mixed
-     */
-    public function updateData($key, $data);
-
-    /**
-     * Get owner name
-     *
-     * @return string
-     */
-    public function getName();
-
-    /**
-     * Get owner parent name
-     *
-     * @return string
-     */
-    public function getParentName();
-}
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigStorageBuilderInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigStorageBuilderInterface.php
deleted file mode 100644
index ef081fd327d6f7a2a82f2f520cf6996e615426fe..0000000000000000000000000000000000000000
--- a/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigStorageBuilderInterface.php
+++ /dev/null
@@ -1,21 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Framework\View\Element\UiComponent;
-
-/**
- * Interface ConfigStorageBuilderInterface
- */
-interface ConfigStorageBuilderInterface
-{
-    /**
-     * Config storage data to JSON by output
-     *
-     * @param ConfigStorageInterface $storage
-     * @param string $parentName
-     * @return string
-     */
-    public function toJson(ConfigStorageInterface $storage, $parentName = null);
-}
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigStorageInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigStorageInterface.php
deleted file mode 100644
index 3b31ff3e7de77de41d104050c5b929dbc818669e..0000000000000000000000000000000000000000
--- a/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigStorageInterface.php
+++ /dev/null
@@ -1,222 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Framework\View\Element\UiComponent;
-
-use Magento\Framework\Api\CriteriaInterface;
-use Magento\Framework\Data\CollectionDataSourceInterface;
-
-/**
- * Class ConfigurationStorageInterface
- */
-interface ConfigStorageInterface
-{
-    /**
-     * Register component
-     *
-     * @param string $name
-     * @param array $data
-     * @return mixed
-     */
-    public function addComponent($name, $data);
-
-    /**
-     * Add components configuration
-     *
-     * @param ConfigInterface $config
-     * @return void
-     */
-    public function addComponentsData(ConfigInterface $config);
-
-    /**
-     * Remove components configuration
-     *
-     * @param ConfigInterface $configuration
-     * @return void
-     */
-    public function removeComponentsData(ConfigInterface $configuration);
-
-    /**
-     * Get components configuration
-     *
-     * @param string|null $name
-     * @return ConfigInterface|null|array
-     */
-    public function getComponentsData($name = null);
-
-    /**
-     * @return array
-     */
-    public function getComponents();
-
-    /**
-     * Add data in storage
-     *
-     * @param string $name
-     * @param array $dataSource
-     * @return void
-     */
-    public function addDataSource($name, array $dataSource);
-
-    /**
-     * Remove data in storage
-     *
-     * @param string $name
-     * @return void
-     */
-    public function removeDataSource($name);
-
-    /**
-     * Get data from storage
-     *
-     * @param string|null $name
-     * @return array|null
-     */
-    public function getDataSource($name = null);
-
-    /**
-     * Update data in storage
-     *
-     * @param string $name
-     * @param array $dataSource
-     * @return void
-     */
-    public function updateDataSource($name, array $dataSource);
-
-    /**
-     * Add meta data
-     *
-     * @param string $key
-     * @param array $data
-     * @return mixed
-     */
-    public function addMeta($key, array $data);
-
-    /**
-     * Remove meta data
-     *
-     * @param string $key
-     * @return array
-     */
-    public function removeMeta($key);
-
-    /**
-     * Get meta data
-     *
-     * @param string|null $key
-     * @return array|null
-     */
-    public function getMeta($key = null);
-
-    /**
-     * Update meta data in storage
-     *
-     * @param string $key
-     * @param array $data
-     * @return void
-     */
-    public function updateMeta($key, array $data);
-
-    /**
-     * @return array
-     */
-    public function getMetaKeys();
-
-    /**
-     * Set data collection
-     *
-     * @param string $key
-     * @param CollectionDataSourceInterface|CriteriaInterface $dataCollection
-     * @return void
-     */
-    public function addDataCollection($key, CollectionDataSourceInterface $dataCollection);
-
-    /**
-     * Get data collection
-     *
-     * @param string|null $key
-     * @return CollectionDataSourceInterface|CriteriaInterface
-     */
-    public function getDataCollection($key = null);
-
-    /**
-     * Update data collection in storage
-     *
-     * @param string $key
-     * @param CollectionDataSourceInterface|CriteriaInterface $dataCollection
-     * @return mixed
-     */
-    public function updateDataCollection($key, CollectionDataSourceInterface $dataCollection);
-
-    /**
-     * Add cloud data in storage
-     *
-     * @param string $key
-     * @param array $data
-     * @return void
-     */
-    public function addGlobalData($key, array $data);
-
-    /**
-     * Remove cloud data in storage
-     *
-     * @param string $key
-     * @return void
-     */
-    public function removeGlobalData($key);
-
-    /**
-     * Get cloud data from storage
-     *
-     * @param string|null $key
-     * @return array|null
-     */
-    public function getGlobalData($key = null);
-
-    /**
-     * @param string $key
-     * @param DataProviderInterface $dataProvider
-     * @return void
-     */
-    public function addDataProvider($key, DataProviderInterface $dataProvider);
-
-    /**
-     * @param string $key
-     * @return void
-     */
-    public function removeDataProvider($key);
-
-    /**
-     * @param null|string $key
-     * @return DataProviderInterface[]|DataProviderInterface|null
-     */
-    public function getDataProvider($key = null);
-
-    /**
-     * @param string $key
-     * @param DataProviderInterface $dataProvider
-     * @return void
-     */
-    public function updateDataProvider($key, DataProviderInterface $dataProvider);
-
-    /**
-     * @param string $dataScope
-     * @param array $structure
-     * @return void
-     */
-    public function addLayoutStructure($dataScope, array $structure);
-
-    /**
-     * @return array
-     */
-    public function getLayoutStructure();
-
-    /**
-     * @param string $name
-     * @param mixed $default
-     * @return array
-     */
-    public function getLayoutNode($name, $default = null);
-}
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/ContainerInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/ContainerInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..4966134eaf77811bc53bf5d1cd6bb5cafdba74a7
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/ContainerInterface.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\View\Element\UiComponent;
+
+use Magento\Framework\View\Element\BlockInterface;
+
+/**
+ * Interface ContainerInterface
+ */
+interface ContainerInterface extends BlockInterface
+{
+    //
+}
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/ContentType/AbstractContentType.php b/lib/internal/Magento/Framework/View/Element/UiComponent/ContentType/AbstractContentType.php
new file mode 100644
index 0000000000000000000000000000000000000000..72c021138f7892e7ae8e24d71f00ac7252fe3a14
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/ContentType/AbstractContentType.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\View\Element\UiComponent\ContentType;
+
+use Magento\Framework\View\FileSystem;
+use Magento\Framework\View\TemplateEnginePool;
+
+/**
+ * Class AbstractContentType
+ */
+abstract class AbstractContentType implements ContentTypeInterface
+{
+    /**
+     * @var FileSystem
+     */
+    protected $filesystem;
+
+    /**
+     * @var TemplateEnginePool
+     */
+    protected $templateEnginePool;
+
+    /**
+     * Constructor
+     *
+     * @param FileSystem $filesystem
+     * @param TemplateEnginePool $templateEnginePool
+     */
+    public function __construct(
+        FileSystem $filesystem,
+        TemplateEnginePool $templateEnginePool
+    ) {
+        $this->filesystem = $filesystem;
+        $this->templateEnginePool = $templateEnginePool;
+    }
+}
diff --git a/app/code/Magento/Ui/ContentType/ContentTypeFactory.php b/lib/internal/Magento/Framework/View/Element/UiComponent/ContentType/ContentTypeFactory.php
similarity index 72%
rename from app/code/Magento/Ui/ContentType/ContentTypeFactory.php
rename to lib/internal/Magento/Framework/View/Element/UiComponent/ContentType/ContentTypeFactory.php
index 5bdda92584f66a60744b4e22b654b89110086a0d..886331cf65935b7662688e42fcf22c5c009cf162 100644
--- a/app/code/Magento/Ui/ContentType/ContentTypeFactory.php
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/ContentType/ContentTypeFactory.php
@@ -3,7 +3,7 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-namespace Magento\Ui\ContentType;
+namespace Magento\Framework\View\Element\UiComponent\ContentType;
 
 use Magento\Framework\ObjectManagerInterface;
 
@@ -12,26 +12,17 @@ use Magento\Framework\ObjectManagerInterface;
  */
 class ContentTypeFactory
 {
-    /**
-     * Default content type
-     */
-    const DEFAULT_TYPE = 'html';
-
     /**
      * Content types
      *
      * @var array
      */
-    protected $types = [
-        'html' => 'Magento\Ui\ContentType\Html',
-        'json' => 'Magento\Ui\ContentType\Json',
-        'xml' => 'Magento\Ui\ContentType\Xml',
-    ];
+    protected $types;
 
     /**
      * Object manager
      *
-     * @var \Magento\Framework\ObjectManagerInterface
+     * @var ObjectManagerInterface
      */
     protected $objectManager;
 
@@ -41,9 +32,9 @@ class ContentTypeFactory
      * @param ObjectManagerInterface $objectManager
      * @param array $types
      */
-    public function __construct(ObjectManagerInterface $objectManager, array $types = [])
+    public function __construct(ObjectManagerInterface $objectManager, array $types)
     {
-        $this->types = array_merge($this->types, $types);
+        $this->types = $types;
         $this->objectManager = $objectManager;
     }
 
@@ -54,7 +45,7 @@ class ContentTypeFactory
      * @return ContentTypeInterface
      * @throws \InvalidArgumentException
      */
-    public function get($type = ContentTypeFactory::DEFAULT_TYPE)
+    public function get($type)
     {
         if (!isset($this->types[$type])) {
             throw new \InvalidArgumentException(sprintf("Wrong content type '%s', renderer not exists.", $type));
diff --git a/app/code/Magento/Ui/ContentType/ContentTypeInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/ContentType/ContentTypeInterface.php
similarity index 55%
rename from app/code/Magento/Ui/ContentType/ContentTypeInterface.php
rename to lib/internal/Magento/Framework/View/Element/UiComponent/ContentType/ContentTypeInterface.php
index 575c42e77d1dd9f0b6108be376c61654e9ce6656..cbefd547d9caae922abf02085c51feeb603d29f8 100644
--- a/app/code/Magento/Ui/ContentType/ContentTypeInterface.php
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/ContentType/ContentTypeInterface.php
@@ -3,7 +3,7 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-namespace Magento\Ui\ContentType;
+namespace Magento\Framework\View\Element\UiComponent\ContentType;
 
 use Magento\Framework\View\Element\UiComponentInterface;
 
@@ -13,11 +13,11 @@ use Magento\Framework\View\Element\UiComponentInterface;
 interface ContentTypeInterface
 {
     /**
-     * Render data
+     * Render component
      *
-     * @param UiComponentInterface $view
+     * @param UiComponentInterface $component
      * @param string $template
-     * @return mixed
+     * @return string
      */
-    public function render(UiComponentInterface $view, $template = '');
+    public function render(UiComponentInterface $component, $template = '');
 }
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/ContentType/Html.php b/lib/internal/Magento/Framework/View/Element/UiComponent/ContentType/Html.php
new file mode 100644
index 0000000000000000000000000000000000000000..4283327e3e86bd5ecd8eb6486d66a8c2489da20c
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/ContentType/Html.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\View\Element\UiComponent\ContentType;
+
+use Magento\Framework\View\Element\UiComponentInterface;
+
+/**
+ * Class Html
+ */
+class Html extends AbstractContentType
+{
+    /**
+     * Render data
+     *
+     * @param UiComponentInterface $component
+     * @param string $template
+     * @return string
+     */
+    public function render(UiComponentInterface $component, $template = '')
+    {
+        $result = '';
+        if ($template) {
+            $extension = pathinfo($template, PATHINFO_EXTENSION);
+            $templateEngine = $this->templateEnginePool->get($extension);
+            $result = $templateEngine->render($component, $this->getTemplate($extension, $template));
+        }
+        return $result;
+    }
+
+    /**
+     * Get template path
+     *
+     * @param string $extension
+     * @param string $template
+     * @return string
+     */
+    protected function getTemplate($extension, $template)
+    {
+        switch ($extension) {
+            case 'xhtml':
+                return $template;
+            default:
+                return $this->filesystem->getTemplateFileName($template);
+        }
+    }
+}
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/ContentType/Json.php b/lib/internal/Magento/Framework/View/Element/UiComponent/ContentType/Json.php
new file mode 100644
index 0000000000000000000000000000000000000000..3185bc6cb2ac0b83581502f57e48607b624257ab
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/ContentType/Json.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\View\Element\UiComponent\ContentType;
+
+use Magento\Framework\View\FileSystem;
+use Magento\Framework\View\TemplateEnginePool;
+use Magento\Framework\View\Element\UiComponentInterface;
+
+/**
+ * Class Json
+ */
+class Json extends AbstractContentType
+{
+    /**
+     * Constructor
+     *
+     * @param FileSystem $filesystem
+     * @param TemplateEnginePool $templateEnginePool
+     */
+    public function __construct(
+        FileSystem $filesystem,
+        TemplateEnginePool $templateEnginePool
+    ) {
+        parent::__construct($filesystem, $templateEnginePool);
+    }
+
+    /**
+     * Render data
+     *
+     * @param UiComponentInterface $component
+     * @param string $template
+     * @return string
+     * @throws \Exception
+     */
+    public function render(UiComponentInterface $component, $template = '')
+    {
+        $data = $component->getDataSourceData();
+        $data = reset($data);
+
+        return json_encode($data['config']['data']);
+    }
+}
diff --git a/app/code/Magento/Ui/ContentType/Xml.php b/lib/internal/Magento/Framework/View/Element/UiComponent/ContentType/Xml.php
similarity index 82%
rename from app/code/Magento/Ui/ContentType/Xml.php
rename to lib/internal/Magento/Framework/View/Element/UiComponent/ContentType/Xml.php
index 065a34d73a17f71633cc5ee3ea702bd1e4d77915..9715e8d6ea510e4861d6e5cc3ed4535baa303e9e 100644
--- a/app/code/Magento/Ui/ContentType/Xml.php
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/ContentType/Xml.php
@@ -3,43 +3,47 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-namespace Magento\Ui\ContentType;
+namespace Magento\Framework\View\Element\UiComponent\ContentType;
 
-use Magento\Framework\View\Element\UiComponentInterface;
+use Magento\Framework\Xml\Generator;
 use Magento\Framework\View\FileSystem;
 use Magento\Framework\View\TemplateEnginePool;
-use Magento\Framework\Xml\Generator;
+use Magento\Framework\View\Element\UiComponentInterface;
 
 /**
  * Class Xml
  */
-class Xml implements ContentTypeInterface
+class Xml extends AbstractContentType
 {
     /**
-     * @var \Magento\Framework\View\FileSystem
+     * @var FileSystem
      */
     protected $filesystem;
 
     /**
-     * @var \Magento\Framework\View\TemplateEnginePool
+     * @var TemplateEnginePool
      */
     protected $templateEnginePool;
 
     /**
-     * @var \Magento\Framework\Xml\Generator
+     * @var Generator
      */
     protected $generator;
 
     /**
+     * Constructor
+     *
      * @param FileSystem $filesystem
      * @param TemplateEnginePool $templateEnginePool
      * @param Generator $generator
      */
-    public function __construct(FileSystem $filesystem, TemplateEnginePool $templateEnginePool, Generator $generator)
-    {
-        $this->filesystem = $filesystem;
-        $this->templateEnginePool = $templateEnginePool;
+    public function __construct(
+        FileSystem $filesystem,
+        TemplateEnginePool $templateEnginePool,
+        Generator $generator
+    ) {
         $this->generator = $generator;
+        parent::__construct($filesystem, $templateEnginePool);
     }
 
     /**
@@ -48,6 +52,7 @@ class Xml implements ContentTypeInterface
      * @param UiComponentInterface $view
      * @param string $template
      * @return string
+     * @throws \Exception
      */
     public function render(UiComponentInterface $view, $template = '')
     {
@@ -62,7 +67,8 @@ class Xml implements ContentTypeInterface
         } else {
             $result = $this->getDataXml($view);
         }
-        return $result;
+
+        throw new \Exception('Please implement XML renderer');
     }
 
     /**
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php
index 582fad08370f42cba9aac5880f3fd353e8adfc78..2e9e35bce7ef1db4cc563e3d15d3ffed00f6f85e 100644
--- a/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php
@@ -5,29 +5,32 @@
  */
 namespace Magento\Framework\View\Element\UiComponent;
 
+use Magento\Framework\UrlInterface;
 use Magento\Framework\App\RequestInterface;
-use Magento\Framework\Registry;
-use Magento\Framework\View\Element\UiComponentFactory;
-use Magento\Framework\View\LayoutInterface;
+use Magento\Framework\View\Element\UiComponentInterface;
+use Magento\Framework\View\Element\UiComponent\Control\ActionPoolFactory;
+use Magento\Framework\View\Element\UiComponent\Control\ActionPoolInterface;
+use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderFactory;
+use Magento\Framework\View\Element\UiComponent\ContentType\ContentTypeFactory;
+use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface;
+use Magento\Framework\View\Element\UiComponent\ContentType\ContentTypeInterface;
+use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface;
+use Magento\Framework\View\LayoutInterface as PageLayoutInterface;
 
 /**
  * Class Context
  */
-class Context extends Registry
+class Context implements ContextInterface
 {
     /**
-     * Configuration storage builder
-     *
-     * @var ConfigStorageBuilderInterface
+     * @var string
      */
-    protected $configStorageBuilder;
+    protected $namespace;
 
     /**
-     * Configuration storage
-     *
-     * @var ConfigStorageInterface
+     * @var DataProviderInterface
      */
-    protected $configStorage;
+    protected $dataProvider;
 
     /**
      * Application request
@@ -36,6 +39,13 @@ class Context extends Registry
      */
     protected $request;
 
+    /**
+     * Factory renderer for a content type
+     *
+     * @var ContentTypeFactory
+     */
+    protected $contentTypeFactory;
+
     /**
      * Accept type
      *
@@ -44,191 +54,249 @@ class Context extends Registry
     protected $acceptType;
 
     /**
-     * @var LayoutInterface
+     * @var PageLayoutInterface
      */
     protected $pageLayout;
 
     /**
-     * @var LayoutInterface
+     * @var ButtonProviderFactory
      */
-    protected $layout;
+    protected $buttonProviderFactory;
 
     /**
-     * @var UiComponentFactory
+     * @var ActionPoolInterface
      */
-    protected $factory;
+    protected $actionPool;
 
     /**
-     * Data Namespace
+     * Registry components
      *
-     * @var string
+     * @var array
      */
-    protected $namespace;
+    protected $componentsDefinitions = [];
 
     /**
-     * Constructor
+     * Url Builder
      *
-     * @param ConfigStorageInterface $configStorage
-     * @param ConfigStorageBuilderInterface $configStorageBuilder
+     * @var UrlInterface
+     */
+    protected $urlBuilder;
+
+    /**
+     * @param PageLayoutInterface $pageLayout
      * @param RequestInterface $request
+     * @param ButtonProviderFactory $buttonProviderFactory
+     * @param ActionPoolFactory $actionPoolFactory
+     * @param ContentTypeFactory $contentTypeFactory
+     * @param UrlInterface $urlBuilder
+     * @param DataProviderInterface|null $dataProvider
+     * @param string $namespace
      */
     public function __construct(
-        ConfigStorageInterface $configStorage,
-        ConfigStorageBuilderInterface $configStorageBuilder,
-        RequestInterface $request
+        PageLayoutInterface $pageLayout,
+        RequestInterface $request,
+        ButtonProviderFactory $buttonProviderFactory,
+        ActionPoolFactory $actionPoolFactory,
+        ContentTypeFactory $contentTypeFactory,
+        UrlInterface $urlBuilder,
+        DataProviderInterface $dataProvider = null,
+        $namespace = null
     ) {
-        $this->configStorage = $configStorage;
-        $this->configStorageBuilder = $configStorageBuilder;
+        $this->namespace = $namespace;
         $this->request = $request;
+        $this->buttonProviderFactory = $buttonProviderFactory;
+        $this->dataProvider = $dataProvider;
+        $this->pageLayout = $pageLayout;
+        $this->actionPool = $actionPoolFactory->create(['context' => $this]);
+        $this->contentTypeFactory = $contentTypeFactory;
+        $this->urlBuilder = $urlBuilder;
+
         $this->setAcceptType();
     }
 
     /**
-     * Getting requested accept type
+     * Add component into registry
      *
+     * @param string $name
+     * @param array $config
      * @return void
      */
-    protected function setAcceptType()
+    public function addComponentDefinition($name, array $config)
     {
-        $this->acceptType = 'xml';
-
-        $rawAcceptType = $this->request->getHeader('Accept');
-        if (strpos($rawAcceptType, 'json') !== false) {
-            $this->acceptType = 'json';
-        } elseif (strpos($rawAcceptType, 'html') !== false) {
-            $this->acceptType = 'html';
+        if (!isset($this->componentsDefinitions[$name])) {
+            $this->componentsDefinitions[$name] = $config;
         }
     }
 
     /**
-     * Getting accept type
+     * To get the registry components
      *
-     * @return string
+     * @return array
      */
-    public function getAcceptType()
+    public function getComponentsDefinitions()
     {
-        return $this->acceptType;
+        return $this->componentsDefinitions;
     }
 
     /**
-     * Set Ui Components Factory
+     * Get render engine
      *
-     * @param UiComponentFactory $render
-     * @return void
+     * @return ContentTypeInterface
      */
-    public function setRender(UiComponentFactory $render)
+    public function getRenderEngine()
     {
-        $this->factory = $render;
+        return $this->contentTypeFactory->get($this->getAcceptType());
     }
 
     /**
-     * Get Ui Components Factory
-     *
-     * @return UiComponentFactory
+     * @return string
      */
-    public function getRender()
+    public function getNamespace()
     {
-        return $this->factory;
+        return $this->namespace;
     }
 
     /**
-     * Set root layout
+     * Getting accept type
      *
-     * @param LayoutInterface $layout
-     * @return void
+     * @return string
      */
-    public function setPageLayout(LayoutInterface $layout)
+    public function getAcceptType()
     {
-        $this->pageLayout = $layout;
+        return $this->acceptType;
     }
 
     /**
-     * Get root layout
+     * Getting all request data
      *
-     * @return LayoutInterface
+     * @return mixed
      */
-    public function getPageLayout()
+    public function getRequestParams()
     {
-        return $this->pageLayout;
+        return $this->request->getParams();
     }
 
     /**
-     * Set root view
+     * Getting data according to the key
      *
-     * @param string $namespace
-     * @return void
+     * @param string $key
+     * @param mixed|null $defaultValue
+     * @return mixed
      */
-    public function setNamespace($namespace)
+    public function getRequestParam($key, $defaultValue = null)
     {
-        $this->namespace = $namespace;
+        return $this->request->getParam($key, $defaultValue);
     }
 
     /**
-     * Get root view
+     * Get data provider
      *
-     * @return string
+     * @return DataProviderInterface
      */
-    public function getNamespace()
+    public function getDataProvider()
     {
-        return $this->namespace;
+        return $this->dataProvider;
     }
 
     /**
-     * Getting all request data
+     * Get page layout
      *
-     * @return mixed
+     * @return PageLayoutInterface
      */
-    public function getRequestParams()
+    public function getPageLayout()
     {
-        return $this->request->getParams();
+        return $this->pageLayout;
     }
 
     /**
-     * Getting data according to the key
+     * Add button in the actions toolbar
      *
-     * @param string $key
-     * @param mixed|null $defaultValue
-     * @return mixed
+     * @param array $buttons
+     * @param UiComponentInterface $component
+     * @return void
      */
-    public function getRequestParam($key, $defaultValue = null)
+    public function addButtons(array $buttons, UiComponentInterface $component)
     {
-        return $this->request->getParam($key, $defaultValue);
+        if (!empty($buttons)) {
+            foreach ($buttons as $buttonId => $buttonData) {
+                if (is_array($buttonData)) {
+                    $buttons[$buttonId] = $buttonData;
+                    continue;
+                }
+                /** @var ButtonProviderInterface $button */
+                $button = $this->buttonProviderFactory->create($buttonData);
+                $buttonData = $button->getButtonData();
+                if (!$buttonData) {
+                    unset($buttons[$buttonId]);
+                    continue;
+                }
+                $buttons[$buttonId] = $buttonData;
+            }
+            uasort($buttons, [$this, 'sortButtons']);
+
+            foreach ($buttons as $buttonId => $buttonData) {
+                if (isset($buttonData['url'])) {
+                    $buttonData['url'] = $this->getUrl($buttonData['url']);
+                }
+                $this->actionPool->add($buttonId, $buttonData, $component);
+            }
+        }
     }
 
     /**
-     * Get storage configuration
+     * Sort buttons by sort order
      *
-     * @return ConfigStorageInterface
+     * @param array $itemA
+     * @param array $itemB
+     * @return int
      */
-    public function getStorage()
+    public function sortButtons(array $itemA, array $itemB)
     {
-        return $this->configStorage;
+        $sortOrderA = isset($itemA['sort_order']) ? intval($itemA['sort_order']) : 0;
+        $sortOrderB = isset($itemB['sort_order']) ? intval($itemB['sort_order']) : 0;
+
+        return $sortOrderA - $sortOrderB;
     }
 
     /**
-     * Get configuration builder
+     * Getting requested accept type
      *
-     * @return ConfigStorageBuilderInterface
+     * @return void
      */
-    public function getConfigBuilder()
+    protected function setAcceptType()
     {
-        return $this->configStorageBuilder;
+        $this->acceptType = 'html';
+
+        $rawAcceptType = $this->request->getHeader('Accept');
+        if ($this->request->getParam('isAjax') === 'true' || strpos($rawAcceptType, 'json') !== false) {
+            $this->acceptType = 'json';
+        } else if (strpos($rawAcceptType, 'html') !== false) {
+            $this->acceptType = 'html';
+        } else if (strpos($rawAcceptType, 'xml') !== false) {
+            $this->acceptType = 'xml';
+        }
     }
 
     /**
-     * @param LayoutInterface $layout
+     * Set data provider
+     *
+     * @param DataProviderInterface $dataProvider
      * @return void
      */
-    public function setLayout(LayoutInterface $layout)
+    public function setDataProvider(DataProviderInterface $dataProvider)
     {
-        $this->layout = $layout;
+        $this->dataProvider = $dataProvider;
     }
 
     /**
-     * @return LayoutInterface
+     * Generate url by route and parameters
+     *
+     * @param   string $route
+     * @param   array $params
+     * @return  string
      */
-    public function getLayout()
+    public function getUrl($route = '', $params = [])
     {
-        return $this->layout;
+        return $this->urlBuilder->getUrl($route, $params);
     }
 }
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/ContextFactory.php b/lib/internal/Magento/Framework/View/Element/UiComponent/ContextFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..5708da5d21278eb8342e92c4cd753e81e3158d40
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/ContextFactory.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\View\Element\UiComponent;
+
+use Magento\Framework\ObjectManagerInterface;
+
+/**
+ * Class ContextFactory
+ */
+class ContextFactory
+{
+    const INSTANCE_NAME = 'Magento\Framework\View\Element\UiComponent\ContextInterface';
+
+    /**
+     * @var ObjectManagerInterface
+     */
+    protected $objectManager;
+
+    /**
+     * Constructor
+     *
+     * @param ObjectManagerInterface $objectManager
+     */
+    public function __construct(ObjectManagerInterface $objectManager)
+    {
+        $this->objectManager = $objectManager;
+    }
+
+    /**
+     * Create context
+     *
+     * @param array $arguments
+     * @return ContextInterface
+     */
+    public function create(array $arguments = [])
+    {
+        return $this->objectManager->create(static::INSTANCE_NAME, $arguments);
+    }
+}
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/ContextInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/ContextInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..321f2cc5b2e066774a462c6a424edc4f43694384
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/ContextInterface.php
@@ -0,0 +1,110 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\View\Element\UiComponent;
+
+use Magento\Framework\View\Element\UiComponentInterface;
+use Magento\Framework\View\Element\UiComponent\ContentType\ContentTypeInterface;
+use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface;
+use Magento\Framework\View\LayoutInterface as PageLayoutInterface;
+
+/**
+ * Interface ContextInterface
+ */
+interface ContextInterface
+{
+    /**
+     * Add components definition
+     *
+     * @param string $name
+     * @param array $config
+     * @return void
+     */
+    public function addComponentDefinition($name, array $config);
+
+    /**
+     * Get components definitions
+     *
+     * @return array
+     */
+    public function getComponentsDefinitions();
+
+    /**
+     * Getting root component name
+     *
+     * @return string
+     */
+    public function getNamespace();
+
+    /**
+     * Getting accept type
+     *
+     * @return string
+     */
+    public function getAcceptType();
+
+    /**
+     * Set data provider
+     *
+     * @param DataProviderInterface $dataProvider
+     * @return void
+     */
+    public function setDataProvider(DataProviderInterface $dataProvider);
+
+    /**
+     * Get data provider
+     *
+     * @return DataProviderInterface
+     */
+    public function getDataProvider();
+
+    /**
+     * Getting all request data
+     *
+     * @return mixed
+     */
+    public function getRequestParams();
+
+    /**
+     * Getting data according to the key
+     *
+     * @param string $key
+     * @param mixed|null $defaultValue
+     * @return mixed
+     */
+    public function getRequestParam($key, $defaultValue = null);
+
+    /**
+     * Get root layout
+     *
+     * @return PageLayoutInterface
+     */
+    public function getPageLayout();
+
+    /**
+     * Add button in the actions toolbar
+     *
+     * @param array $buttons
+     * @param UiComponentInterface $component
+     * @return void
+     */
+    public function addButtons(array $buttons, UiComponentInterface $component);
+
+    /**
+     * Get render engine
+     *
+     * @return ContentTypeInterface
+     */
+    public function getRenderEngine();
+
+    /**
+     * Generate url by route and parameters
+     *
+     * @param   string $route
+     * @param   array $params
+     * @return  string
+     */
+    public function getUrl($route = '', $params = []);
+}
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Control/ActionPoolFactory.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Control/ActionPoolFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..477ff99cebcb3ce5a129184330c43f4e47b4abc1
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Control/ActionPoolFactory.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\View\Element\UiComponent\Control;
+
+use Magento\Framework\ObjectManagerInterface;
+
+/**
+ * Class ActionPoolFactory
+ */
+class ActionPoolFactory
+{
+    const INSTANCE = 'Magento\Framework\View\Element\UiComponent\Control\ActionPoolInterface';
+
+    /**
+     * @var ObjectManagerInterface
+     */
+    protected $objectManager;
+
+    /**
+     * Constructor
+     *
+     * @param ObjectManagerInterface $objectManager
+     */
+    public function __construct(ObjectManagerInterface $objectManager)
+    {
+        $this->objectManager = $objectManager;
+    }
+
+    /**
+     * Create Action Pool
+     *
+     * @param array $arguments
+     * @return ActionPoolInterface
+     */
+    public function create(array $arguments = [])
+    {
+        return $this->objectManager->create(static::INSTANCE, $arguments);
+    }
+}
diff --git a/app/code/Magento/Ui/Component/Control/ActionPoolInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Control/ActionPoolInterface.php
similarity index 76%
rename from app/code/Magento/Ui/Component/Control/ActionPoolInterface.php
rename to lib/internal/Magento/Framework/View/Element/UiComponent/Control/ActionPoolInterface.php
index 2a9d361a58f59c1c0ce9e7364eef0110c7e1a8b6..225bfe0dcf81b7faef0e797b4629bc7c0ec7a32e 100644
--- a/app/code/Magento/Ui/Component/Control/ActionPoolInterface.php
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Control/ActionPoolInterface.php
@@ -3,8 +3,9 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-namespace Magento\Ui\Component\Control;
+namespace Magento\Framework\View\Element\UiComponent\Control;
 
+use Magento\Framework\View\Element\BlockInterface;
 use Magento\Framework\View\Element\UiComponentInterface;
 
 /**
@@ -38,4 +39,11 @@ interface ActionPoolInterface
      * @return void
      */
     public function update($key, array $data);
+
+    /**
+     * Get toolbar block
+     *
+     * @return bool|BlockInterface
+     */
+    public function getToolbar();
 }
diff --git a/app/code/Magento/Ui/Component/Control/ButtonProviderFactory.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Control/ButtonProviderFactory.php
similarity index 93%
rename from app/code/Magento/Ui/Component/Control/ButtonProviderFactory.php
rename to lib/internal/Magento/Framework/View/Element/UiComponent/Control/ButtonProviderFactory.php
index c30c7a0f9ced52d49d42778a52063f4f27abca66..b4fe0c6561ebe8d033d2b58776b93819c4683e6f 100644
--- a/app/code/Magento/Ui/Component/Control/ButtonProviderFactory.php
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Control/ButtonProviderFactory.php
@@ -3,13 +3,12 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-namespace Magento\Ui\Component\Control;
+namespace Magento\Framework\View\Element\UiComponent\Control;
 
 use Magento\Framework\ObjectManagerInterface;
 
 /**
  * Class ButtonProviderFactory
- * @package Magento\Ui\DataProvider
  */
 class ButtonProviderFactory
 {
@@ -43,6 +42,7 @@ class ButtonProviderFactory
                 sprintf('"%s" must implement the interface ButtonProviderInterface.', $providerClass)
             );
         }
+
         return $object;
     }
 }
diff --git a/app/code/Magento/Ui/Component/Control/ButtonProviderInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Control/ButtonProviderInterface.php
similarity index 76%
rename from app/code/Magento/Ui/Component/Control/ButtonProviderInterface.php
rename to lib/internal/Magento/Framework/View/Element/UiComponent/Control/ButtonProviderInterface.php
index 508ae595faac9f4b5929e04a5d6edbe16952e8bb..160968779bd5384033f1e617b3506ec99f1a5e09 100644
--- a/app/code/Magento/Ui/Component/Control/ButtonProviderInterface.php
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Control/ButtonProviderInterface.php
@@ -3,11 +3,10 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-namespace Magento\Ui\Component\Control;
+namespace Magento\Framework\View\Element\UiComponent\Control;
 
 /**
  * Interface ButtonProviderInterface
- * @package Magento\Ui\Component\Control
  */
 interface ButtonProviderInterface
 {
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Control/ControlInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Control/ControlInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..2b5870a14a36e50048338dcac6dac21973c1c263
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Control/ControlInterface.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\View\Element\UiComponent\Control;
+
+use Magento\Framework\View\Element\BlockInterface;
+
+/**
+ * Interface ControlInterface
+ */
+interface ControlInterface extends BlockInterface
+{
+    //
+}
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/DataProvider/DataProviderInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/DataProvider/DataProviderInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..034e0fa56c6c448229160f3272384652ce70a158
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/DataProvider/DataProviderInterface.php
@@ -0,0 +1,125 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\View\Element\UiComponent\DataProvider;
+
+/**
+ * Interface DataProviderInterface
+ */
+interface DataProviderInterface
+{
+    /**
+     * Get config data
+     *
+     * @return mixed
+     */
+    public function getConfigData();
+
+    /**
+     * Set config data
+     *
+     * @param mixed $config
+     * @return void
+     */
+    public function setConfigData($config);
+
+    /**
+     * @return array
+     */
+    public function getMeta();
+
+    /**
+     * @param string $fieldSetName
+     * @param string $fieldName
+     * @return array
+     */
+    public function getFieldMetaInfo($fieldSetName, $fieldName);
+
+    /**
+     * @param string $fieldSetName
+     * @return array
+     */
+    public function getFieldsMetaInfo($fieldSetName);
+
+    /**
+     * Get primary field name
+     *
+     * @return string
+     */
+    public function getPrimaryFieldName();
+
+    /**
+     * Get field name in request
+     *
+     * @return string
+     */
+    public function getRequestFieldName();
+
+    /**
+     * Get data
+     *
+     * @return mixed
+     */
+    public function getData();
+
+    /**
+     * Add field to select
+     *
+     * @param string|array $field
+     * @param string|null $alias
+     * @return void
+     */
+    public function addField($field, $alias = null);
+
+    /**
+     * Add field filter to collection
+     *
+     * @param string|array $field
+     * @param string|int|array|null $condition
+     * @return void
+     */
+    public function addFilter($field, $condition = null);
+
+    /**
+     * Add ORDER BY to the end or to the beginning
+     *
+     * @param string $field
+     * @param string $direction
+     * @return void
+     */
+    public function addOrder($field, $direction);
+
+    /**
+     * Set Query limit
+     *
+     * @param int $offset
+     * @param int $size
+     * @return void
+     */
+    public function setLimit($offset, $size);
+
+    /**
+     * Removes field from select
+     *
+     * @param string|null $field
+     * @param bool $isAlias Alias identifier
+     * @return void
+     */
+    public function removeField($field, $isAlias = false);
+
+    /**
+     * Removes all fields from select
+     *
+     * @return void
+     */
+    public function removeAllFields();
+
+    /**
+     * Retrieve count of loaded items
+     *
+     * @return int
+     */
+    public function count();
+}
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/DataProviderInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/DataProviderInterface.php
deleted file mode 100644
index 2ba4ce76daf8ea7d97421c6266b2b5bf6cd6cef2..0000000000000000000000000000000000000000
--- a/lib/internal/Magento/Framework/View/Element/UiComponent/DataProviderInterface.php
+++ /dev/null
@@ -1,27 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Framework\View\Element\UiComponent;
-
-/**
- * Interface DataProviderInterface
- * @package Magento\Framework\View\Element\UiComponent
- */
-interface DataProviderInterface
-{
-    /**
-     * Get meta data
-     *
-     * @return array
-     */
-    public function getMeta();
-
-    /**
-     * Get data
-     *
-     * @return array
-     */
-    public function getData();
-}
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/DataSourceInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/DataSourceInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..d2d8f67167ab159d90b297f56935461f32481031
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/DataSourceInterface.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\View\Element\UiComponent;
+
+use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface;
+use Magento\Framework\View\Element\UiComponentInterface;
+
+/**
+ * Interface DataSourceInterface
+ */
+interface DataSourceInterface extends UiComponentInterface
+{
+    /**
+     * @return DataProviderInterface
+     */
+    public function getDataProvider();
+}
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/JsConfigInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/JsConfigInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..0826398d684042927ad8675b0cc6ae75cf68c7e2
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/JsConfigInterface.php
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\View\Element\UiComponent;
+
+use Magento\Framework\View\Element\UiComponentInterface;
+
+/**
+ * Interface JsConfigInterface
+ */
+interface JsConfigInterface extends UiComponentInterface
+{
+    /**
+     * Get JS config
+     *
+     * @return array|string
+     */
+    public function getJsConfig();
+}
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/LayoutInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/LayoutInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..d5d98ecace047ea3ac1587a5f45ceca14fd1992d
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/LayoutInterface.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\View\Element\UiComponent;
+
+use Magento\Framework\View\Element\UiComponentInterface;
+
+/**
+ * Interface LayoutInterface
+ */
+interface LayoutInterface
+{
+    const SECTIONS_KEY = 'sections';
+
+    const AREAS_KEY = 'areas';
+
+    const GROUPS_KEY = 'groups';
+
+    const ELEMENTS_KEY = 'elements';
+
+    const DATA_SOURCE_KEY = 'data_source';
+
+    /**
+     * @param UiComponentInterface $component
+     * @return array
+     */
+    public function build(UiComponentInterface $component);
+}
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponentFactory.php b/lib/internal/Magento/Framework/View/Element/UiComponentFactory.php
index 48239e9c92261b3b62ae5e0e19b942f2ff21fd72..a1b37315a3a1c632053ea0f39b5766151ac61796 100644
--- a/lib/internal/Magento/Framework/View/Element/UiComponentFactory.php
+++ b/lib/internal/Magento/Framework/View/Element/UiComponentFactory.php
@@ -6,9 +6,11 @@
 namespace Magento\Framework\View\Element;
 
 use Magento\Framework\Object;
-use Magento\Framework\View\Element\UiComponent\Context as RenderContext;
-use Magento\Framework\View\LayoutFactory;
-use Magento\Framework\View\LayoutInterface;
+use Magento\Framework\Exception\LocalizedException;
+use Magento\Framework\ObjectManagerInterface;
+use Magento\Framework\Data\Argument\InterpreterInterface;
+use Magento\Framework\View\Element\UiComponent\ContextInterface;
+use Magento\Framework\View\Element\UiComponent\Config\ManagerInterface;
 
 /**
  * Class UiComponentFactory
@@ -16,172 +18,154 @@ use Magento\Framework\View\LayoutInterface;
 class UiComponentFactory extends Object
 {
     /**
-     * Ui element view
+     * Object manager
      *
-     * @var UiComponentInterface
+     * @var ObjectManagerInterface
      */
-    protected $view;
+    protected $objectManager;
 
     /**
-     * Render context
+     * UI component manager
      *
-     * @var RenderContext
+     * @var ManagerInterface
      */
-    protected $renderContext;
+    protected $componentManager;
 
     /**
-     * Layout Interface
+     * Argument interpreter
      *
-     * @var \Magento\Framework\View\LayoutFactory
+     * @var InterpreterInterface
      */
-    protected $layoutFactory;
-
-    /**
-     * @var LayoutInterface
-     */
-    protected $layout;
-
-    /**
-     * @var bool
-     */
-    protected $layoutLoaded = false;
+    protected $argumentInterpreter;
 
     /**
      * Constructor
      *
-     * @param RenderContext $renderContext
-     * @param LayoutFactory $layoutFactory
+     * @param ObjectManagerInterface $objectManager
+     * @param ManagerInterface $componentManager
+     * @param InterpreterInterface $argumentInterpreter
      * @param array $data
      */
     public function __construct(
-        RenderContext $renderContext,
-        LayoutFactory $layoutFactory,
+        ObjectManagerInterface $objectManager,
+        ManagerInterface $componentManager,
+        InterpreterInterface $argumentInterpreter,
         array $data = []
     ) {
-        $this->renderContext = $renderContext;
-        $this->renderContext->setRender($this);
-        $this->layoutFactory = $layoutFactory;
+        $this->objectManager = $objectManager;
+        $this->componentManager = $componentManager;
+        $this->argumentInterpreter = $argumentInterpreter;
         parent::__construct($data);
     }
 
     /**
-     * Get component name
-     *
-     * @return string
-     */
-    public function getComponent()
-    {
-        return $this->getData('configuration/component');
-    }
-
-    /**
-     * Get layout handle
-     *
-     * @return string
-     */
-    public function getLayoutHandle()
-    {
-        return $this->getData('configuration/name');
-    }
-
-    /**
-     * @param LayoutInterface $layout
-     * @return void
-     */
-    public function setLayout(LayoutInterface $layout)
-    {
-        if (!$this->renderContext->getPageLayout()) {
-            $this->renderContext->setPageLayout($layout);
-        }
-    }
-
-    /**
-     * Create Ui Component instance
+     * Create child components
      *
-     * @param string $componentName
-     * @param string $handleName
-     * @param array $arguments
+     * @param array $bundleComponents
+     * @param ContextInterface $renderContext
+     * @param string $identifier
      * @return UiComponentInterface
      */
-    public function createUiComponent($componentName, $handleName, array $arguments = [])
-    {
-        if (!$this->layout) {
-            $this->renderContext->setNamespace($handleName);
-            $this->layout = $this->layoutFactory->create();
-            $this->renderContext->setLayout($this->layout);
-            $this->layout->getUpdate()->addHandle('ui_components');
-            $this->layout->getUpdate()->addHandle($handleName);
-            $this->loadLayout();
-            $this->layoutLoaded = true;
+    protected function createChildComponent(
+        array $bundleComponents,
+        ContextInterface $renderContext,
+        $identifier
+    ) {
+        list($className, $arguments) = $this->argumentsResolver($identifier, $bundleComponents);
+        if (isset($arguments['data']['disabled']) && $arguments['data']['disabled'] === 'true') {
+            return null;
         }
-
-        $view = $this->getUiElementView($componentName);
-        $view->update($arguments);
-        if ($this->layoutLoaded) {
-            $this->prepare($view);
+        $components = [];
+        foreach ($bundleComponents['children'] as $childrenIdentifier => $childrenData) {
+            $children = $this->createChildComponent(
+                $childrenData,
+                $renderContext,
+                $childrenIdentifier
+            );
+            $components[$childrenIdentifier] = $children;
+        }
+        $components = array_filter($components);
+        $arguments['components'] = $components;
+        if (!isset($arguments['context'])) {
+            $arguments['context'] = $renderContext;
         }
 
-        return $view;
+        return $this->objectManager->create($className, $arguments);
     }
 
     /**
-     * Prepare UI Component data
+     * Resolve arguments
      *
-     * @param object $view
-     * @return void
+     * @param string $identifier
+     * @param array $componentData
+     * @return array
      */
-    protected function prepare($view)
+    protected function argumentsResolver($identifier, array $componentData)
     {
-        if ($view instanceof UiComponentInterface) {
-            $view->prepare();
+        $attributes = $componentData[ManagerInterface::COMPONENT_ATTRIBUTES_KEY];
+        $className = $attributes['class'];
+        unset($attributes['class']);
+        $arguments = [];
+        foreach ($componentData[ManagerInterface::COMPONENT_ARGUMENTS_KEY] as $name => $argument) {
+            $arguments[$name] = $this->argumentInterpreter->evaluate($argument);
         }
-        foreach ($view->getLayout()->getChildNames($view->getNameInLayout()) as $childAlias) {
-            $name = $view->getLayout()->getChildName($view->getNameInLayout(), $childAlias);
-            if ($view->getLayout()->isContainer($name)) {
-                foreach ($view->getLayout()->getChildNames($name) as $childName) {
-                    $child = $view->getLayout()->getBlock($childName);
-                    $this->prepare($child);
-                }
-            } else {
-                $child = $view->getChildBlock($childAlias);
-                if ($child) {
-                    $this->prepare($child);
-                }
-            }
+
+        if (!isset($arguments['data'])) {
+            $arguments['data'] = [];
         }
+
+        $arguments['data'] = array_merge($arguments['data'], ['name' => $identifier], $attributes);
+        return [$className, $arguments];
     }
 
     /**
-     * Get UI Element View
+     * Create component object
      *
-     * @param string $uiElementName
+     * @param string $identifier
+     * @param string $name
+     * @param array $arguments
      * @return UiComponentInterface
-     * @throws \InvalidArgumentException
+     * @throws \Magento\Framework\Exception\LocalizedException
      */
-    public function getUiElementView($uiElementName)
+    public function create($identifier, $name = null, array $arguments = [])
     {
-        /** @var UiComponentInterface $view */
-        $view = $this->layout->getBlock($uiElementName);
-        if (!$view instanceof UiComponentInterface) {
-            throw new \InvalidArgumentException(
-                sprintf(
-                    'UI Element "%s" must implement \Magento\Framework\View\Element\UiComponentInterface',
-                    $uiElementName
-                )
+        if ($name === null) {
+            $bundleComponents = $this->componentManager->prepareData($identifier)->getData($identifier);
+            if (empty($bundleComponents)) {
+                throw new LocalizedException(new \Magento\Framework\Phrase('You use an empty set.'));
+            }
+            list($className, $componentArguments) = $this->argumentsResolver(
+                $identifier,
+                $bundleComponents[$identifier]
             );
-        }
-        return $view;
-    }
+            $componentArguments = array_merge($componentArguments, $arguments);
+            if (!isset($componentArguments['context'])) {
+                throw new LocalizedException(new \Magento\Framework\Phrase('Context, is required argument.'));
+            }
+            $componentContext = $componentArguments['context'];
+            $components = [];
+            foreach ($bundleComponents[$identifier]['children'] as $childrenIdentifier => $childrenData) {
+                $children = $this->createChildComponent(
+                    $childrenData,
+                    $componentContext,
+                    $childrenIdentifier
+                );
+                $components[$childrenIdentifier] = $children;
+            }
+            $components = array_filter($components);
+            $componentArguments['components'] = $components;
 
-    /**
-     * Load layout
-     *
-     * @return void
-     */
-    protected function loadLayout()
-    {
-        $this->layout->getUpdate()->load();
-        $this->layout->generateXml();
-        $this->layout->generateElements();
+            /** @var \Magento\Framework\View\Element\UiComponentInterface $component */
+            $component = $this->objectManager->create($className, array_merge($componentArguments, $arguments));
+
+            return $component;
+        } else {
+            $defaultData = $this->componentManager->createRawComponentData($name);
+            list($className, $componentArguments) = $this->argumentsResolver($identifier, $defaultData);
+            /** @var \Magento\Framework\View\Element\UiComponentInterface $component */
+            $component = $this->objectManager->create($className, array_merge($componentArguments, $arguments));
+
+            return $component;
+        }
     }
 }
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponentInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponentInterface.php
index 343f82b40d49eda567334bda03af72991cfe1ef6..a38823e7f0b14933a9fad1a2eaece9386d79f818 100644
--- a/lib/internal/Magento/Framework/View/Element/UiComponentInterface.php
+++ b/lib/internal/Magento/Framework/View/Element/UiComponentInterface.php
@@ -5,98 +5,105 @@
  */
 namespace Magento\Framework\View\Element;
 
-use Magento\Framework\View\Element\UiComponent\Context as RenderContext;
-use Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface;
+use Magento\Framework\View\Element\UiComponent\ContextInterface;
 
 /**
- * Class UiComponentInterface
+ * Interface UiComponentInterface
  */
 interface UiComponentInterface extends BlockInterface
 {
     /**
-     * Update component data
+     * Get component instance name
      *
-     * @param array $arguments
      * @return string
      */
-    public function update(array $arguments = []);
+    public function getName();
 
     /**
-     * Prepare component data
+     * Get component name
      *
-     * @return void
+     * @return string
      */
-    public function prepare();
+    public function getComponentName();
 
     /**
      * Render component
      *
-     * @param array $data
      * @return string
      */
-    public function render(array $data = []);
+    public function render();
 
     /**
-     * Render label
+     * Add component
      *
-     * @return mixed|string
+     * @param string $name
+     * @param UiComponentInterface $component
+     * @return void
      */
-    public function renderLabel();
+    public function addComponent($name, UiComponentInterface $component);
 
     /**
-     * Getting template for rendering content
-     *
-     * @return string|false
+     * @param string $name
+     * @return UiComponentInterface
      */
-    public function getContentTemplate();
+    public function getComponent($name);
 
     /**
-     * Getting template for rendering label
+     * Get child components
      *
-     * @return string|false
+     * @return UiComponentInterface[]
      */
-    public function getLabelTemplate();
+    public function getChildComponents();
 
     /**
-     * Getting instance name
+     * Get template
      *
      * @return string
      */
-    public function getName();
+    public function getTemplate();
 
     /**
-     * Getting parent name component instance
+     * Get component context
      *
-     * @return string
+     * @return ContextInterface
      */
-    public function getParentName();
+    public function getContext();
 
     /**
-     * Get render context
+     * Render child component
      *
-     * @return RenderContext
+     * @param string $name
+     * @return string
      */
-    public function getRenderContext();
+    public function renderChildComponent($name);
 
     /**
-     * Get elements
+     * Component data setter
      *
-     * @return UiComponentInterface[]
+     * @param string|array $key
+     * @param mixed $value
+     * @return void
      */
-    public function getElements();
+    public function setData($key, $value = null);
 
     /**
-     * Set elements
+     * Component data getter
      *
-     * @param array $elements
+     * @param string $key
+     * @param string|int $index
      * @return mixed
      */
-    public function setElements(array $elements);
+    public function getData($key = '', $index = null);
+
+    /**
+     * @return array
+     */
+    public function getDataSourceData();
 
     /**
-     * Get configuration builder
+     * Prepare component configuration
      *
-     * @return ConfigBuilderInterface
+     * @return void
      */
-    public function getConfigBuilder();
+    public function prepare();
 }
diff --git a/lib/internal/Magento/Framework/View/Element/UiElementFactory.php b/lib/internal/Magento/Framework/View/Element/UiElementFactory.php
deleted file mode 100644
index e6ae25787d59439286227694e66b78bab2ee4ad9..0000000000000000000000000000000000000000
--- a/lib/internal/Magento/Framework/View/Element/UiElementFactory.php
+++ /dev/null
@@ -1,59 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Framework\View\Element;
-
-use Magento\Framework\ObjectManagerInterface;
-use Magento\Framework\View\Element\UiComponent\Context as UiContext;
-
-/**
- * Class UiElementFactory
- */
-class UiElementFactory
-{
-    /**
-     * @var ObjectManagerInterface
-     */
-    protected $objectManager;
-
-    /**
-     * @var UiContext
-     */
-    protected $context;
-
-    /**
-     * Constructor
-     *
-     * @param ObjectManagerInterface $objectManager
-     * @param UiContext $context
-     */
-    public function __construct(ObjectManagerInterface $objectManager, UiContext $context)
-    {
-        $this->objectManager = $objectManager;
-        $this->context = $context;
-    }
-
-    /**
-     * Create data provider
-     *
-     * @param string $elementName
-     * @param array $data
-     * @return bool|BlockInterface
-     * @throws \Exception
-     */
-    public function create($elementName, array $data = [])
-    {
-        if ('text' == $elementName) {
-            $elementName = 'input';
-        }
-        $block = $this->context->getLayout()->getBlock($elementName);
-        if (!$block) {
-            throw new \Exception('Can not find block of element ' . $elementName);
-        }
-        $newBlock = clone $block;
-        $newBlock->addData($data);
-        return $newBlock;
-    }
-}
diff --git a/lib/internal/Magento/Framework/View/Layout.php b/lib/internal/Magento/Framework/View/Layout.php
index 6c857548d18ed329d6767bbc6f35684f8205e059..da8130891b3b05e624f358c2f0fe5b1b52d7444d 100644
--- a/lib/internal/Magento/Framework/View/Layout.php
+++ b/lib/internal/Magento/Framework/View/Layout.php
@@ -23,6 +23,12 @@ use Magento\Framework\View\Layout\ScheduledStructure;
  */
 class Layout extends \Magento\Framework\Simplexml\Config implements \Magento\Framework\View\LayoutInterface
 {
+
+    /**
+     * Empty layout xml
+     */
+    const LAYOUT_NODE = '<layout/>';
+
     /**
      * Layout Update module
      *
@@ -173,7 +179,6 @@ class Layout extends \Magento\Framework\Simplexml\Config implements \Magento\Fra
         $cacheable = true
     ) {
         $this->_elementClass = 'Magento\Framework\View\Layout\Element';
-        $this->setXml(simplexml_load_string('<layout/>', $this->_elementClass));
         $this->_renderingOutput = new \Magento\Framework\Object();
 
         $this->_processorFactory = $processorFactory;
@@ -188,8 +193,6 @@ class Layout extends \Magento\Framework\Simplexml\Config implements \Magento\Fra
 
         $this->readerContextFactory = $readerContextFactory;
         $this->generatorContextFactory = $generatorContextFactory;
-
-        $this->readerContext = $this->readerContextFactory->create();
     }
 
     /**
@@ -248,7 +251,7 @@ class Layout extends \Magento\Framework\Simplexml\Config implements \Magento\Fra
             $this->_update = null;
         }
         $this->_blocks = [];
-        $this->_xml = null;
+        parent::__destruct();
     }
 
     /**
@@ -278,14 +281,6 @@ class Layout extends \Magento\Framework\Simplexml\Config implements \Magento\Fra
         return $this;
     }
 
-    /**
-     * @return Layout\Reader\Context
-     */
-    public function getReaderContext()
-    {
-        return $this->readerContext;
-    }
-
     /**
      * Create structure of elements from the loaded XML configuration
      *
@@ -297,13 +292,12 @@ class Layout extends \Magento\Framework\Simplexml\Config implements \Magento\Fra
         $cacheId = 'structure_' . $this->getUpdate()->getCacheId();
         $result = $this->cache->load($cacheId);
         if ($result) {
-            /** @var Layout\Reader\Context $readerContext */
             $this->readerContext = unserialize($result);
         } else {
             \Magento\Framework\Profiler::start('build_structure');
-            $this->readerPool->interpret($this->readerContext, $this->getNode());
+            $this->readerPool->interpret($this->getReaderContext(), $this->getNode());
             \Magento\Framework\Profiler::stop('build_structure');
-            $this->cache->save(serialize($this->readerContext), $cacheId, $this->getUpdate()->getHandles());
+            $this->cache->save(serialize($this->getReaderContext()), $cacheId, $this->getUpdate()->getHandles());
         }
 
         $generatorContext = $this->generatorContextFactory->create(
@@ -314,7 +308,7 @@ class Layout extends \Magento\Framework\Simplexml\Config implements \Magento\Fra
         );
 
         \Magento\Framework\Profiler::start('generate_elements');
-        $this->generatorPool->process($this->readerContext, $generatorContext);
+        $this->generatorPool->process($this->getReaderContext(), $generatorContext);
         \Magento\Framework\Profiler::stop('generate_elements');
 
         $this->addToOutputRootContainers();
@@ -1035,7 +1029,7 @@ class Layout extends \Magento\Framework\Simplexml\Config implements \Magento\Fra
     public function isCacheable()
     {
         $this->build();
-        $cacheableXml = !(bool)count($this->_xml->xpath('//' . Element::TYPE_BLOCK . '[@cacheable="false"]'));
+        $cacheableXml = !(bool)count($this->getXml()->xpath('//' . Element::TYPE_BLOCK . '[@cacheable="false"]'));
         return $this->cacheable && $cacheableXml;
     }
 
@@ -1060,4 +1054,30 @@ class Layout extends \Magento\Framework\Simplexml\Config implements \Magento\Fra
         $this->isPrivate = (bool)$isPrivate;
         return $this;
     }
+
+    /**
+     * Getter and lazy loader for xml element
+     *
+     * @return \Magento\Framework\Simplexml\Element
+     */
+    protected function getXml()
+    {
+        if (!$this->_xml) {
+            $this->setXml(simplexml_load_string(self::LAYOUT_NODE, $this->_elementClass));
+        }
+        return $this->_xml;
+    }
+
+    /**
+     * Getter and lazy loader for reader context
+     *
+     * @return Layout\Reader\Context
+     */
+    public function getReaderContext()
+    {
+        if (!$this->readerContext) {
+            $this->readerContext = $this->readerContextFactory->create();
+        }
+        return $this->readerContext;
+    }
 }
diff --git a/lib/internal/Magento/Framework/View/Layout/Argument/Parser.php b/lib/internal/Magento/Framework/View/Layout/Argument/Parser.php
index 7697660afc02f2bd378e632c53d2fc4701976dc0..fd4bca2122cda5a66b55053ec86018c8495cea12 100644
--- a/lib/internal/Magento/Framework/View/Layout/Argument/Parser.php
+++ b/lib/internal/Magento/Framework/View/Layout/Argument/Parser.php
@@ -41,7 +41,13 @@ class Parser
         if (!$this->converter) {
             $arrayNodeConfig = new ArrayNodeConfig(
                 new NodePathMatcher(),
-                ['argument/param' => 'name', 'argument(/item)+' => 'name', 'argument(/item)+/param' => 'name'],
+                [
+                    'argument/param' => 'name',
+                    'argument(/item)+' => 'name',
+                    'argument(/item)+/param' => 'name',
+                    'argument(/argument)+' => 'name',
+                    'argument((/argument)+(/item)+)+' => 'name',
+                ],
                 ['argument/updater']
             );
             $this->converter = new FlatConverter($arrayNodeConfig);
diff --git a/lib/internal/Magento/Framework/View/Layout/Element.php b/lib/internal/Magento/Framework/View/Layout/Element.php
index 01e58372cec32bb6781a007019b9c6f37710c336..3ea80ec098168716b3d5ec83c2273f3db890b07a 100644
--- a/lib/internal/Magento/Framework/View/Layout/Element.php
+++ b/lib/internal/Magento/Framework/View/Layout/Element.php
@@ -37,7 +37,7 @@ class Element extends \Magento\Framework\Simplexml\Element
 
     const TYPE_MOVE = 'move';
 
-    const TYPE_UI_COMPONENT = 'ui_component';
+    const TYPE_UI_COMPONENT = 'uiComponent';
 
     const TYPE_HEAD = 'head';
 
diff --git a/lib/internal/Magento/Framework/View/Layout/Generator/UiComponent.php b/lib/internal/Magento/Framework/View/Layout/Generator/UiComponent.php
index 0356d93d04c868518ad389136162898e15a3201e..d5a8fcda61c2a164f1da15f4f9f3482112d18fe1 100644
--- a/lib/internal/Magento/Framework/View/Layout/Generator/UiComponent.php
+++ b/lib/internal/Magento/Framework/View/Layout/Generator/UiComponent.php
@@ -5,45 +5,63 @@
  */
 namespace Magento\Framework\View\Layout\Generator;
 
-use Magento\Framework\Data\Argument\InterpreterInterface;
-use Magento\Framework\View\Element\UiComponentFactory;
 use Magento\Framework\View\Layout;
+use Magento\Framework\View\Element\BlockFactory;
+use Magento\Framework\View\Layout\Data\Structure;
+use Magento\Framework\View\Layout\GeneratorInterface;
+use Magento\Framework\View\Element\UiComponentFactory;
+use Magento\Framework\View\Element\UiComponentInterface;
+use Magento\Framework\Data\Argument\InterpreterInterface;
+use Magento\Framework\View\Element\UiComponent\ContainerInterface;
+use Magento\Framework\View\Layout\Reader\Context as ReaderContext;
+use Magento\Framework\View\Layout\Generator\Context as GeneratorContext;
+use Magento\Framework\View\Element\UiComponent\ContextFactory as UiComponentContextFactory;
+use Magento\Framework\View\LayoutInterface;
 
-class UiComponent implements Layout\GeneratorInterface
+/**
+ * Class UiComponent
+ */
+class UiComponent implements GeneratorInterface
 {
     /**
      * Generator type
      */
-    const TYPE = 'ui_component';
+    const TYPE = 'uiComponent';
 
     /**
-     * @var \Magento\Framework\View\Element\UiComponentFactory
+     * Block container for components
+     */
+    const CONTAINER = 'Magento\Framework\View\Element\UiComponent\ContainerInterface';
+
+    /**
+     * @var UiComponentFactory
      */
     protected $uiComponentFactory;
 
     /**
-     * @var \Magento\Framework\Data\Argument\InterpreterInterface
+     * @var UiComponentContextFactory
      */
-    protected $argumentInterpreter;
+    protected $contextFactory;
 
     /**
      * Constructor
      *
      * @param UiComponentFactory $uiComponentFactory
-     * @param \Magento\Framework\Data\Argument\InterpreterInterface $argumentInterpreter
+     * @param BlockFactory $blockFactory
+     * @param UiComponentContextFactory $contextFactory
      */
     public function __construct(
         UiComponentFactory $uiComponentFactory,
-        InterpreterInterface $argumentInterpreter
+        BlockFactory $blockFactory,
+        UiComponentContextFactory $contextFactory
     ) {
         $this->uiComponentFactory = $uiComponentFactory;
-        $this->argumentInterpreter = $argumentInterpreter;
+        $this->blockFactory = $blockFactory;
+        $this->contextFactory = $contextFactory;
     }
 
     /**
      * {@inheritdoc}
-     *
-     * @return string
      */
     public function getType()
     {
@@ -53,11 +71,11 @@ class UiComponent implements Layout\GeneratorInterface
     /**
      * Creates UI Component object based on scheduled data and add it to the layout
      *
-     * @param Layout\Reader\Context $readerContext
-     * @param Context $generatorContext
+     * @param ReaderContext $readerContext
+     * @param GeneratorContext $generatorContext
      * @return $this
      */
-    public function process(Layout\Reader\Context $readerContext, Layout\Generator\Context $generatorContext)
+    public function process(ReaderContext $readerContext, GeneratorContext $generatorContext)
     {
         $scheduledStructure = $readerContext->getScheduledStructure();
         $scheduledElements = $scheduledStructure->getElements();
@@ -66,18 +84,16 @@ class UiComponent implements Layout\GeneratorInterface
         }
         $structure = $generatorContext->getStructure();
         $layout = $generatorContext->getLayout();
-        $this->uiComponentFactory->setLayout($layout);
+
+        // Instantiate blocks and collect all actions data
         /** @var $blocks \Magento\Framework\View\Element\AbstractBlock[] */
         $blocks = [];
-        // Instantiate blocks and collect all actions data
         foreach ($scheduledElements as $elementName => $element) {
-            list($type, $data) = $element;
-            if ($type === self::TYPE) {
-                $block = $this->generateComponent($structure, $elementName, $data);
-                $blocks[$elementName] = $block;
-                $layout->setBlock($elementName, $block);
-                $scheduledStructure->unsetElement($elementName);
-            }
+            list(, $data) = $element;
+            $block = $this->generateComponent($structure, $elementName, $data, $layout);
+            $blocks[$elementName] = $block;
+            $layout->setBlock($elementName, $block);
+            $scheduledStructure->unsetElement($elementName);
         }
 
         return $this;
@@ -86,35 +102,49 @@ class UiComponent implements Layout\GeneratorInterface
     /**
      * Create component object
      *
-     * @param \Magento\Framework\View\Layout\Data\Structure $structure
+     * @param Structure $structure
      * @param string $elementName
      * @param string $data
-     * @return \Magento\Framework\View\Element\UiComponentInterface
+     * @param LayoutInterface $layout
+     * @return ContainerInterface
      */
-    protected function generateComponent(Layout\Data\Structure $structure, $elementName, $data)
+    protected function generateComponent(Structure $structure, $elementName, $data, LayoutInterface $layout)
     {
         $attributes = $data['attributes'];
         if (!empty($attributes['group'])) {
             $structure->addToParentGroup($elementName, $attributes['group']);
         }
-        $arguments = empty($data['arguments']) ? [] : $this->evaluateArguments($data['arguments']);
-        $componentName = isset($attributes['component']) ? $attributes['component'] : '';
-        $uiComponent = $this->uiComponentFactory->createUiComponent($componentName, $elementName, $arguments);
-        return $uiComponent;
+
+        $context = $this->contextFactory->create([
+            'namespace' => $elementName,
+            'pageLayout' => $layout
+        ]);
+
+        $component = $this->uiComponentFactory->create($elementName, null, [
+            'context' => $context
+        ]);
+        $this->prepareComponent($component);
+
+        /** @var ContainerInterface $blockContainer */
+        $blockContainer = $this->blockFactory->createBlock(static::CONTAINER, ['component' => $component]);
+
+        return $blockContainer;
     }
 
     /**
-     * Compute and return argument values
+     * Call prepare method in the component UI
      *
-     * @param array $arguments
-     * @return array
+     * @param UiComponentInterface $component
+     * @return void
      */
-    protected function evaluateArguments(array $arguments)
+    protected function prepareComponent(UiComponentInterface $component)
     {
-        $result = [];
-        foreach ($arguments as $argumentName => $argumentData) {
-            $result[$argumentName] = $this->argumentInterpreter->evaluate($argumentData);
+        $childComponents = $component->getChildComponents();
+        if (!empty($childComponents)) {
+            foreach ($childComponents as $child) {
+                $this->prepareComponent($child);
+            }
         }
-        return $result;
+        $component->prepare();
     }
 }
diff --git a/lib/internal/Magento/Framework/View/Layout/Proxy.php b/lib/internal/Magento/Framework/View/Layout/Proxy.php
index 8c399f4e4161a7f847b4f22db49e7e97e8528ef2..95220e34913df356a84e427d9d72e04f5c73b6ac 100644
--- a/lib/internal/Magento/Framework/View/Layout/Proxy.php
+++ b/lib/internal/Magento/Framework/View/Layout/Proxy.php
@@ -6,8 +6,7 @@
 namespace Magento\Framework\View\Layout;
 
 /**
- * Proxy class for \Magento\Framework\View\Layout
- *
+ * Proxy class for @see \Magento\Framework\View\Layout
  * @SuppressWarnings(PHPMD.ExcessivePublicCount)
  */
 class Proxy extends \Magento\Framework\View\Layout
@@ -17,42 +16,44 @@ class Proxy extends \Magento\Framework\View\Layout
      *
      * @var \Magento\Framework\ObjectManagerInterface
      */
-    protected $objectManager;
+    protected $_objectManager = null;
 
     /**
      * Proxied instance name
      *
      * @var string
      */
-    protected $instanceName;
+    protected $_instanceName = null;
 
     /**
      * Proxied instance
      *
      * @var \Magento\Framework\View\Layout
      */
-    protected $subject;
+    protected $_subject = null;
 
     /**
      * Instance shareability flag
      *
      * @var bool
      */
-    protected $isShared;
+    protected $_isShared = null;
 
     /**
+     * Proxy constructor
+     *
      * @param \Magento\Framework\ObjectManagerInterface $objectManager
      * @param string $instanceName
      * @param bool $shared
      */
     public function __construct(
         \Magento\Framework\ObjectManagerInterface $objectManager,
-        $instanceName = 'Magento\Framework\View\Layout',
+        $instanceName = '\\Magento\\Framework\\View\\Layout',
         $shared = true
     ) {
-        $this->objectManager = $objectManager;
-        $this->instanceName = $instanceName;
-        $this->isShared = $shared;
+        $this->_objectManager = $objectManager;
+        $this->_instanceName = $instanceName;
+        $this->_isShared = $shared;
     }
 
     /**
@@ -70,7 +71,7 @@ class Proxy extends \Magento\Framework\View\Layout
      */
     public function __wakeup()
     {
-        $this->objectManager = \Magento\Framework\App\ObjectManager::getInstance();
+        $this->_objectManager = \Magento\Framework\App\ObjectManager::getInstance();
     }
 
     /**
@@ -80,7 +81,7 @@ class Proxy extends \Magento\Framework\View\Layout
      */
     public function __clone()
     {
-        $this->subject = clone $this->getSubject();
+        $this->_subject = clone $this->_getSubject();
     }
 
     /**
@@ -88,415 +89,334 @@ class Proxy extends \Magento\Framework\View\Layout
      *
      * @return \Magento\Framework\View\Layout
      */
-    protected function getSubject()
+    protected function _getSubject()
     {
-        if (!$this->subject) {
-            $this->subject = true === $this->isShared
-                ? $this->objectManager->get($this->instanceName)
-                : $this->objectManager->create($this->instanceName);
+        if (!$this->_subject) {
+            $this->_subject = true === $this->_isShared
+                ? $this->_objectManager->get($this->_instanceName)
+                : $this->_objectManager->create($this->_instanceName);
         }
-        return $this->subject;
+        return $this->_subject;
     }
 
     /**
-     * Retrieve the layout update instance
-     *
-     * @return \Magento\Framework\View\Layout\ProcessorInterface
+     * {@inheritdoc}
+     */
+    public function setGeneratorPool(\Magento\Framework\View\Layout\GeneratorPool $generatorPool)
+    {
+        return $this->_getSubject()->setGeneratorPool($generatorPool);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setBuilder(\Magento\Framework\View\Layout\BuilderInterface $builder)
+    {
+        return $this->_getSubject()->setBuilder($builder);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function publicBuild()
+    {
+        $this->_getSubject()->publicBuild();
+    }
+
+    /**
+     * {@inheritdoc}
      */
     public function getUpdate()
     {
-        return $this->getSubject()->getUpdate();
+        return $this->_getSubject()->getUpdate();
     }
 
     /**
-     * Layout xml generation
-     *
-     * @return $this
+     * {@inheritdoc}
      */
     public function generateXml()
     {
-        return $this->getSubject()->generateXml();
+        return $this->_getSubject()->generateXml();
     }
 
     /**
-     * Create structure of elements from the loaded XML configuration
-     *
-     * @return void
+     * {@inheritdoc}
      */
     public function generateElements()
     {
-        $this->getSubject()->generateElements();
+        $this->_getSubject()->generateElements();
     }
 
     /**
-     * Get child block if exists
-     *
-     * @param string $parentName
-     * @param string $alias
-     * @return bool|\Magento\Framework\View\Element\AbstractBlock
+     * {@inheritdoc}
      */
     public function getChildBlock($parentName, $alias)
     {
-        return $this->getSubject()->getChildBlock($parentName, $alias);
+        return $this->_getSubject()->getChildBlock($parentName, $alias);
     }
 
     /**
-     * Set child element into layout structure
-     *
-     * @param string $parentName
-     * @param string $elementName
-     * @param string $alias
-     * @return $this
+     * {@inheritdoc}
      */
     public function setChild($parentName, $elementName, $alias)
     {
-        return $this->getSubject()->setChild($parentName, $elementName, $alias);
+        return $this->_getSubject()->setChild($parentName, $elementName, $alias);
     }
 
     /**
-     * Reorder a child of a specified element
-     *
-     * If $offsetOrSibling is null, it will put the element to the end
-     * If $offsetOrSibling is numeric (integer) value, it will put the element after/before specified position
-     * Otherwise -- after/before specified sibling
-     *
-     * @param string $parentName
-     * @param string $childName
-     * @param string|int|null $offsetOrSibling
-     * @param bool $after
-     * @return void
+     * {@inheritdoc}
      */
     public function reorderChild($parentName, $childName, $offsetOrSibling, $after = true)
     {
-        $this->getSubject()->reorderChild($parentName, $childName, $offsetOrSibling, $after);
+        $this->_getSubject()->reorderChild($parentName, $childName, $offsetOrSibling, $after);
     }
 
     /**
-     * Remove child element from parent
-     *
-     * @param string $parentName
-     * @param string $alias
-     * @return $this
+     * {@inheritdoc}
      */
     public function unsetChild($parentName, $alias)
     {
-        return $this->getSubject()->unsetChild($parentName, $alias);
+        return $this->_getSubject()->unsetChild($parentName, $alias);
     }
 
     /**
-     * Get list of child names
-     *
-     * @param string $parentName
-     * @return array
+     * {@inheritdoc}
      */
     public function getChildNames($parentName)
     {
-        return $this->getSubject()->getChildNames($parentName);
+        return $this->_getSubject()->getChildNames($parentName);
     }
 
     /**
-     * Get list of child blocks
-     *
-     * Returns associative array of <alias> => <block instance>
-     *
-     * @param string $parentName
-     * @return array
+     * {@inheritdoc}
      */
     public function getChildBlocks($parentName)
     {
-        return $this->getSubject()->getChildBlocks($parentName);
+        return $this->_getSubject()->getChildBlocks($parentName);
     }
 
     /**
-     * Get child name by alias
-     *
-     * @param string $parentName
-     * @param string $alias
-     * @return bool|string
+     * {@inheritdoc}
      */
     public function getChildName($parentName, $alias)
     {
-        return $this->getSubject()->getChildName($parentName, $alias);
+        return $this->_getSubject()->getChildName($parentName, $alias);
     }
 
     /**
-     * Find an element in layout, render it and return string with its output
-     *
-     * @param string $name
-     * @param bool $useCache
-     * @return string
+     * {@inheritdoc}
      */
     public function renderElement($name, $useCache = true)
     {
-        return $this->getSubject()->renderElement($name, $useCache);
+        return $this->_getSubject()->renderElement($name, $useCache);
     }
 
     /**
-     * Add element to parent group
-     *
-     * @param string $blockName
-     * @param string $parentGroupName
-     * @return bool
+     * {@inheritdoc}
+     */
+    public function renderNonCachedElement($name)
+    {
+        return $this->_getSubject()->renderNonCachedElement($name);
+    }
+
+    /**
+     * {@inheritdoc}
      */
     public function addToParentGroup($blockName, $parentGroupName)
     {
-        return $this->getSubject()->addToParentGroup($blockName, $parentGroupName);
+        return $this->_getSubject()->addToParentGroup($blockName, $parentGroupName);
     }
 
     /**
-     * Get element names for specified group
-     *
-     * @param string $blockName
-     * @param string $groupName
-     * @return array
+     * {@inheritdoc}
      */
     public function getGroupChildNames($blockName, $groupName)
     {
-        return $this->getSubject()->getGroupChildNames($blockName, $groupName);
+        return $this->_getSubject()->getGroupChildNames($blockName, $groupName);
     }
 
     /**
-     * Check if element exists in layout structure
-     *
-     * @param string $name
-     * @return bool
+     * {@inheritdoc}
      */
     public function hasElement($name)
     {
-        return $this->getSubject()->hasElement($name);
+        return $this->_getSubject()->hasElement($name);
     }
 
     /**
-     * Get property value of an element
-     *
-     * @param string $name
-     * @param string $attribute
-     * @return mixed
+     * {@inheritdoc}
      */
     public function getElementProperty($name, $attribute)
     {
-        return $this->getSubject()->getElementProperty($name, $attribute);
+        return $this->_getSubject()->getElementProperty($name, $attribute);
     }
 
     /**
-     * Whether specified element is a block
-     *
-     * @param string $name
-     * @return bool
+     * {@inheritdoc}
      */
     public function isBlock($name)
     {
-        return $this->getSubject()->isBlock($name);
+        return $this->_getSubject()->isBlock($name);
     }
 
     /**
-     * Checks if element with specified name is container
-     *
-     * @param string $name
-     * @return bool
+     * {@inheritdoc}
+     */
+    public function isUiComponent($name)
+    {
+        return $this->_getSubject()->isUiComponent($name);
+    }
+
+    /**
+     * {@inheritdoc}
      */
     public function isContainer($name)
     {
-        return $this->getSubject()->isContainer($name);
+        return $this->_getSubject()->isContainer($name);
     }
 
     /**
-     * Whether the specified element may be manipulated externally
-     *
-     * @param string $name
-     * @return bool
+     * {@inheritdoc}
      */
     public function isManipulationAllowed($name)
     {
-        return $this->getSubject()->isManipulationAllowed($name);
+        return $this->_getSubject()->isManipulationAllowed($name);
     }
 
     /**
-     * Save block in blocks registry
-     *
-     * @param string $name
-     * @param \Magento\Framework\View\Element\AbstractBlock $block
-     * @return $this
+     * {@inheritdoc}
      */
     public function setBlock($name, $block)
     {
-        return $this->getSubject()->setBlock($name, $block);
+        return $this->_getSubject()->setBlock($name, $block);
     }
 
     /**
-     * Remove block from registry
-     *
-     * @param string $name
-     * @return $this
+     * {@inheritdoc}
      */
     public function unsetElement($name)
     {
-        return $this->getSubject()->unsetElement($name);
+        return $this->_getSubject()->unsetElement($name);
     }
 
     /**
-     * Block Factory
-     *
-     * @param  string $type
-     * @param  string $name
-     * @param  array $attributes
-     * @return \Magento\Framework\View\Element\AbstractBlock
+     * {@inheritdoc}
      */
-    public function createBlock($type, $name = '', array $attributes = [])
+    public function createBlock($type, $name = '', array $arguments = [])
     {
-        return $this->getSubject()->createBlock($type, $name, $attributes);
+        return $this->_getSubject()->createBlock($type, $name, $arguments);
     }
 
     /**
-     * Add a block to registry, create new object if needed
-     *
-     * @param string|\Magento\Framework\View\Element\AbstractBlock $block
-     * @param string $name
-     * @param string $parent
-     * @param string $alias
-     * @return \Magento\Framework\View\Element\AbstractBlock
+     * {@inheritdoc}
      */
     public function addBlock($block, $name = '', $parent = '', $alias = '')
     {
-        return $this->getSubject()->addBlock($block, $name, $parent, $alias);
+        return $this->_getSubject()->addBlock($block, $name, $parent, $alias);
     }
 
     /**
-     * Insert container into layout structure
-     *
-     * @param string $name
-     * @param string $label
-     * @param array $options
-     * @param string $parent
-     * @param string $alias
-     * @return void
+     * {@inheritdoc}
      */
     public function addContainer($name, $label, array $options = [], $parent = '', $alias = '')
     {
-        $this->getSubject()->addContainer($name, $label, $options, $parent, $alias);
+        $this->_getSubject()->addContainer($name, $label, $options, $parent, $alias);
     }
 
     /**
-     * Rename element in layout and layout structure
-     *
-     * @param string $oldName
-     * @param string $newName
-     * @return bool
+     * {@inheritdoc}
      */
     public function renameElement($oldName, $newName)
     {
-        return $this->getSubject()->renameElement($oldName, $newName);
+        return $this->_getSubject()->renameElement($oldName, $newName);
     }
 
     /**
-     * Retrieve all blocks from registry as array
-     *
-     * @return array
+     * {@inheritdoc}
      */
     public function getAllBlocks()
     {
-        return $this->getSubject()->getAllBlocks();
+        return $this->_getSubject()->getAllBlocks();
     }
 
     /**
-     * Get block object by name
-     *
-     * @param string $name
-     * @return \Magento\Framework\View\Element\AbstractBlock|bool
+     * {@inheritdoc}
      */
     public function getBlock($name)
     {
-        return $this->getSubject()->getBlock($name);
+        return $this->_getSubject()->getBlock($name);
     }
 
     /**
-     * Gets parent name of an element with specified name
-     *
-     * @param string $childName
-     * @return bool|string
+     * {@inheritdoc}
+     */
+    public function getUiComponent($name)
+    {
+        return $this->_getSubject()->getUiComponent($name);
+    }
+
+    /**
+     * {@inheritdoc}
      */
     public function getParentName($childName)
     {
-        return $this->getSubject()->getParentName($childName);
+        return $this->_getSubject()->getParentName($childName);
     }
 
     /**
-     * Get element alias by name
-     *
-     * @param string $name
-     * @return bool|string
+     * {@inheritdoc}
      */
     public function getElementAlias($name)
     {
-        return $this->getSubject()->getElementAlias($name);
+        return $this->_getSubject()->getElementAlias($name);
     }
 
     /**
-     * Add an element to output
-     *
-     * @param string $name
-     * @return $this
+     * {@inheritdoc}
      */
     public function addOutputElement($name)
     {
-        return $this->getSubject()->addOutputElement($name);
+        return $this->_getSubject()->addOutputElement($name);
     }
 
     /**
-     * Remove an element from output
-     *
-     * @param string $name
-     * @return $this
+     * {@inheritdoc}
      */
     public function removeOutputElement($name)
     {
-        return $this->getSubject()->removeOutputElement($name);
+        return $this->_getSubject()->removeOutputElement($name);
     }
 
     /**
-     * Get all blocks marked for output
-     *
-     * @return string
+     * {@inheritdoc}
      */
     public function getOutput()
     {
-        return $this->getSubject()->getOutput();
+        return $this->_getSubject()->getOutput();
     }
 
     /**
-     * Retrieve messages block
-     *
-     * @return \Magento\Framework\View\Element\Messages
+     * {@inheritdoc}
      */
     public function getMessagesBlock()
     {
-        return $this->getSubject()->getMessagesBlock();
+        return $this->_getSubject()->getMessagesBlock();
     }
 
     /**
-     * Get block singleton
-     *
-     * @param string $type
-     * @throws \Magento\Framework\Exception\LocalizedException
-     * @return \Magento\Framework\App\Helper\AbstractHelper
+     * {@inheritdoc}
      */
     public function getBlockSingleton($type)
     {
-        return $this->getSubject()->getBlockSingleton($type);
+        return $this->_getSubject()->getBlockSingleton($type);
     }
 
     /**
-     * @param string $namespace
-     * @param string $staticType
-     * @param string $dynamicType
-     * @param string $type
-     * @param string $template
-     * @param array $data
-     * @return $this
+     * {@inheritdoc}
      */
     public function addAdjustableRenderer($namespace, $staticType, $dynamicType, $type, $template, $data = [])
     {
-        return $this->getSubject()->addAdjustableRenderer(
+        return $this->_getSubject()->addAdjustableRenderer(
             $namespace,
             $staticType,
             $dynamicType,
@@ -507,394 +427,298 @@ class Proxy extends \Magento\Framework\View\Layout
     }
 
     /**
-     * Get renderer options
-     *
-     * @param string $namespace
-     * @param string $staticType
-     * @param string $dynamicType
-     * @return array|null
+     * {@inheritdoc}
      */
     public function getRendererOptions($namespace, $staticType, $dynamicType)
     {
-        return $this->getSubject()->getRendererOptions($namespace, $staticType, $dynamicType);
+        return $this->_getSubject()->getRendererOptions($namespace, $staticType, $dynamicType);
     }
 
     /**
-     * Execute renderer
-     *
-     * @param string $namespace
-     * @param string $staticType
-     * @param string $dynamicType
-     * @param array $data
-     * @return void
+     * {@inheritdoc}
      */
     public function executeRenderer($namespace, $staticType, $dynamicType, $data = [])
     {
-        $this->getSubject()->executeRenderer($namespace, $staticType, $dynamicType, $data);
+        $this->_getSubject()->executeRenderer($namespace, $staticType, $dynamicType, $data);
     }
 
     /**
-     * Init messages by message storage(s), loading and adding messages to layout messages block
-     *
-     * @param string|array $messageGroups
-     * @return void
+     * {@inheritdoc}
      */
     public function initMessages($messageGroups = [])
     {
-        $this->getSubject()->initMessages($messageGroups);
+        $this->_getSubject()->initMessages($messageGroups);
     }
 
     /**
-     * Check is exists non-cacheable layout elements
-     *
-     * @return bool
+     * {@inheritdoc}
      */
     public function isCacheable()
     {
-        return $this->getSubject()->isCacheable();
+        return $this->_getSubject()->isCacheable();
     }
 
     /**
-     * Check is exists non-cacheable layout elements
-     *
-     * @return bool
+     * {@inheritdoc}
      */
     public function isPrivate()
     {
-        return $this->getSubject()->isPrivate();
+        return $this->_getSubject()->isPrivate();
     }
 
     /**
-     * Mark layout as private
-     *
-     * @param bool $isPrivate
-     * @return $this
+     * {@inheritdoc}
      */
     public function setIsPrivate($isPrivate = true)
     {
-        return $this->getSubject()->setIsPrivate($isPrivate);
+        return $this->_getSubject()->setIsPrivate($isPrivate);
     }
 
     /**
-     * Sets xml for this configuration
-     *
-     * @param \Magento\Framework\Simplexml\Element $node
-     * @return $this
+     * {@inheritdoc}
+     */
+    public function getReaderContext()
+    {
+        return $this->_getSubject()->getReaderContext();
+    }
+
+    /**
+     * {@inheritdoc}
      */
     public function setXml(\Magento\Framework\Simplexml\Element $node)
     {
-        return $this->getSubject()->setXml($node);
+        return $this->_getSubject()->setXml($node);
     }
 
     /**
-     * Returns node found by the $path
-     *
-     * @param string $path
-     * @return \Magento\Framework\Simplexml\Element|bool
-     * @see \Magento\Framework\Simplexml\Element::descend
+     * {@inheritdoc}
      */
     public function getNode($path = null)
     {
-        return $this->getSubject()->getNode($path);
+        return $this->_getSubject()->getNode($path);
     }
 
     /**
-     * Returns nodes found by xpath expression
-     *
-     * @param string $xpath
-     * @return \SimpleXMLElement[]|bool
+     * {@inheritdoc}
      */
     public function getXpath($xpath)
     {
-        return $this->getSubject()->getXpath($xpath);
+        return $this->_getSubject()->getXpath($xpath);
     }
 
     /**
-     * Set cache
-     *
-     * @param \Magento\Framework\Simplexml\Config\Cache\AbstractCache $cache
-     * @return $this
+     * {@inheritdoc}
      */
     public function setCache($cache)
     {
-        return $this->getSubject()->setCache($cache);
+        return $this->_getSubject()->setCache($cache);
     }
 
     /**
-     * Return cache
-     *
-     * @return \Magento\Framework\Simplexml\Config\Cache\AbstractCache
+     * {@inheritdoc}
      */
     public function getCache()
     {
-        return $this->getSubject()->getCache();
+        return $this->_getSubject()->getCache();
     }
 
     /**
-     * Set whether cache is saved
-     *
-     * @param boolean $flag
-     * @return $this
+     * {@inheritdoc}
      */
     public function setCacheSaved($flag)
     {
-        return $this->getSubject()->setCacheSaved($flag);
+        return $this->_getSubject()->setCacheSaved($flag);
     }
 
     /**
-     * Return whether cache is saved
-     *
-     * @return bool
-     *
-     * @SuppressWarnings(PHPMD.BooleanGetMethodName)
+     * {@inheritdoc}
      */
     public function getCacheSaved()
     {
-        return $this->getSubject()->getCacheSaved();
+        return $this->_getSubject()->getCacheSaved();
     }
 
     /**
-     * Set cache ID
-     *
-     * @param string $id
-     * @return $this
+     * {@inheritdoc}
      */
     public function setCacheId($id)
     {
-        return $this->getSubject()->setCacheId($id);
+        return $this->_getSubject()->setCacheId($id);
     }
 
     /**
-     * Return cache ID
-     *
-     * @return string
+     * {@inheritdoc}
      */
     public function getCacheId()
     {
-        return $this->getSubject()->getCacheId();
+        return $this->_getSubject()->getCacheId();
     }
 
     /**
-     * Set cache tags
-     *
-     * @param array $tags
-     * @return $this
+     * {@inheritdoc}
      */
     public function setCacheTags($tags)
     {
-        return $this->getSubject()->setCacheTags($tags);
+        return $this->_getSubject()->setCacheTags($tags);
     }
 
     /**
-     * Return cache tags
-     *
-     * @return array
+     * {@inheritdoc}
      */
     public function getCacheTags()
     {
-        return $this->getSubject()->getCacheTags();
+        return $this->_getSubject()->getCacheTags();
     }
 
     /**
-     * Set cache lifetime
-     *
-     * @param int $lifetime
-     * @return $this
+     * {@inheritdoc}
      */
     public function setCacheLifetime($lifetime)
     {
-        return $this->getSubject()->setCacheLifetime($lifetime);
+        return $this->_getSubject()->setCacheLifetime($lifetime);
     }
 
     /**
-     * Return cache lifetime
-     *
-     * @return int
+     * {@inheritdoc}
      */
     public function getCacheLifetime()
     {
-        return $this->getSubject()->getCacheLifetime();
+        return $this->_getSubject()->getCacheLifetime();
     }
 
     /**
-     * Set cache checksum
-     *
-     * @param string $data
-     * @return $this
+     * {@inheritdoc}
      */
     public function setCacheChecksum($data)
     {
-        return $this->getSubject()->setCacheChecksum($data);
+        return $this->_getSubject()->setCacheChecksum($data);
     }
 
     /**
-     * Update cache checksum
-     *
-     * @param string $data
-     * @return $this
+     * {@inheritdoc}
      */
     public function updateCacheChecksum($data)
     {
-        return $this->getSubject()->updateCacheChecksum($data);
+        return $this->_getSubject()->updateCacheChecksum($data);
     }
 
     /**
-     * Return cache checksum
-     *
-     * @return string
+     * {@inheritdoc}
      */
     public function getCacheChecksum()
     {
-        return $this->getSubject()->getCacheChecksum();
+        return $this->_getSubject()->getCacheChecksum();
     }
 
     /**
-     * Get cache checksum ID
-     *
-     * @return string
+     * {@inheritdoc}
      */
     public function getCacheChecksumId()
     {
-        return $this->getSubject()->getCacheChecksumId();
+        return $this->_getSubject()->getCacheChecksumId();
     }
 
     /**
-     * Fetch cache checksum
-     *
-     * @return boolean
+     * {@inheritdoc}
      */
     public function fetchCacheChecksum()
     {
-        return $this->getSubject()->fetchCacheChecksum();
+        return $this->_getSubject()->fetchCacheChecksum();
     }
 
     /**
-     * Validate cache checksum
-     *
-     * @return boolean
+     * {@inheritdoc}
      */
     public function validateCacheChecksum()
     {
-        return $this->getSubject()->validateCacheChecksum();
+        return $this->_getSubject()->validateCacheChecksum();
     }
 
     /**
-     * Load cache
-     *
-     * @return boolean
+     * {@inheritdoc}
      */
     public function loadCache()
     {
-        return $this->getSubject()->loadCache();
+        return $this->_getSubject()->loadCache();
     }
 
     /**
-     * Save cache
-     *
-     * @param array $tags
-     * @return $this
+     * {@inheritdoc}
      */
     public function saveCache($tags = null)
     {
-        return $this->getSubject()->saveCache($tags);
+        return $this->_getSubject()->saveCache($tags);
     }
 
     /**
-     * Return Xml of node as string
-     *
-     * @return string
+     * {@inheritdoc}
      */
     public function getXmlString()
     {
-        return $this->getSubject()->getXmlString();
+        return $this->_getSubject()->getXmlString();
     }
 
     /**
-     * Remove cache
-     *
-     * @return $this
+     * {@inheritdoc}
      */
     public function removeCache()
     {
-        return $this->getSubject()->removeCache();
+        return $this->_getSubject()->removeCache();
     }
 
     /**
-     * Imports XML file
-     *
-     * @param string $filePath
-     * @return boolean
+     * {@inheritdoc}
      */
     public function loadFile($filePath)
     {
-        return $this->getSubject()->loadFile($filePath);
+        return $this->_getSubject()->loadFile($filePath);
     }
 
     /**
-     * Imports XML string
-     *
-     * @param string $string
-     * @return boolean
+     * {@inheritdoc}
      */
     public function loadString($string)
     {
-        return $this->getSubject()->loadString($string);
+        return $this->_getSubject()->loadString($string);
     }
 
     /**
-     * Imports DOM node
-     *
-     * @param \DOMNode $dom
-     * @return bool
+     * {@inheritdoc}
      */
     public function loadDom(\DOMNode $dom)
     {
-        return $this->getSubject()->loadDom($dom);
+        return $this->_getSubject()->loadDom($dom);
     }
 
     /**
-     * Create node by $path and set its value.
-     *
-     * @param string $path separated by slashes
-     * @param string $value
-     * @param boolean $overwrite
-     * @return $this
+     * {@inheritdoc}
      */
     public function setNode($path, $value, $overwrite = true)
     {
-        return $this->getSubject()->setNode($path, $value, $overwrite);
+        return $this->_getSubject()->setNode($path, $value, $overwrite);
     }
 
     /**
-     * Process configuration xml
-     *
-     * @return $this
+     * {@inheritdoc}
      */
     public function applyExtends()
     {
-        return $this->getSubject()->applyExtends();
+        return $this->_getSubject()->applyExtends();
     }
 
     /**
-     * Stub method for processing file data right after loading the file text
-     *
-     * @param string $text
-     * @return string
+     * {@inheritdoc}
      */
     public function processFileData($text)
     {
-        return $this->getSubject()->processFileData($text);
+        return $this->_getSubject()->processFileData($text);
     }
 
     /**
-     * Extend configuration
-     *
-     * @param \Magento\Framework\Simplexml\Config $config
-     * @param boolean $overwrite
-     * @return $this
+     * {@inheritdoc}
      */
     public function extend(\Magento\Framework\Simplexml\Config $config, $overwrite = true)
     {
-        return $this->getSubject()->extend($config, $overwrite);
+        return $this->_getSubject()->extend($config, $overwrite);
     }
 }
diff --git a/lib/internal/Magento/Framework/View/Layout/Reader/UiComponent.php b/lib/internal/Magento/Framework/View/Layout/Reader/UiComponent.php
index ae986912df95d2d2a2a928056141f5b1f3b40a48..ad363e5286cba67f5b781e77d6aecf62a28f316c 100644
--- a/lib/internal/Magento/Framework/View/Layout/Reader/UiComponent.php
+++ b/lib/internal/Magento/Framework/View/Layout/Reader/UiComponent.php
@@ -8,12 +8,15 @@ namespace Magento\Framework\View\Layout\Reader;
 use Magento\Framework\App;
 use Magento\Framework\View\Layout;
 
+/**
+ * Class UiComponent
+ */
 class UiComponent implements Layout\ReaderInterface
 {
     /**#@+
      * Supported types
      */
-    const TYPE_UI_COMPONENT = 'ui_component';
+    const TYPE_UI_COMPONENT = 'uiComponent';
     /**#@-*/
 
     /**
@@ -39,18 +42,14 @@ class UiComponent implements Layout\ReaderInterface
      * @param Layout\ScheduledStructure\Helper $helper
      * @param string|null $scopeType
      */
-    public function __construct(
-        Layout\ScheduledStructure\Helper $helper,
-        $scopeType = null
-    ) {
+    public function __construct(Layout\ScheduledStructure\Helper $helper, $scopeType = null)
+    {
         $this->layoutHelper = $helper;
         $this->scopeType = $scopeType;
     }
 
     /**
      * {@inheritdoc}
-     *
-     * @return string[]
      */
     public function getSupportedNodes()
     {
@@ -59,27 +58,24 @@ class UiComponent implements Layout\ReaderInterface
 
     /**
      * {@inheritdoc}
-     *
-     * @param Context $readerContext
-     * @param Layout\Element $currentElement
-     * @return $this
      */
     public function interpret(Context $readerContext, Layout\Element $currentElement)
     {
+        $attributes = $this->getAttributes($currentElement);
         $scheduledStructure = $readerContext->getScheduledStructure();
         $referenceName = $this->layoutHelper->scheduleStructure(
-            $readerContext->getScheduledStructure(),
+            $scheduledStructure,
             $currentElement,
             $currentElement->getParent(),
-            ['attributes' => $this->getAttributes($currentElement)]
+            ['attributes' => $attributes]
         );
-        $scheduledStructure->setStructureElementData($referenceName, [
-            'attributes' => $this->getAttributes($currentElement)
-        ]);
+
+        $scheduledStructure->setStructureElementData($referenceName, ['attributes' => $attributes]);
         $configPath = (string)$currentElement->getAttribute('ifconfig');
         if (!empty($configPath)) {
             $scheduledStructure->setElementToIfconfigList($referenceName, $configPath, $this->scopeType);
         }
+
         return $this;
     }
 
@@ -95,6 +91,7 @@ class UiComponent implements Layout\ReaderInterface
         foreach ($this->attributes as $attributeName) {
             $attributes[$attributeName] = (string)$element->getAttribute($attributeName);
         }
+
         return $attributes;
     }
 }
diff --git a/lib/internal/Magento/Framework/View/Layout/etc/body.xsd b/lib/internal/Magento/Framework/View/Layout/etc/body.xsd
index a8d5a75f795b074e2c90def67696e5a4784829b2..3b187137d61fcfbe88750b48835e516edf736d9e 100644
--- a/lib/internal/Magento/Framework/View/Layout/etc/body.xsd
+++ b/lib/internal/Magento/Framework/View/Layout/etc/body.xsd
@@ -17,7 +17,7 @@
             <xs:element ref="container" minOccurs="0" maxOccurs="unbounded"/>
             <xs:element ref="remove" minOccurs="0" maxOccurs="unbounded"/>
             <xs:element ref="move" minOccurs="0" maxOccurs="unbounded"/>
-            <xs:element ref="ui_component" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element ref="uiComponent" minOccurs="0" maxOccurs="unbounded"/>
         </xs:sequence>
     </xs:complexType>
 
diff --git a/lib/internal/Magento/Framework/View/Layout/etc/elements.xsd b/lib/internal/Magento/Framework/View/Layout/etc/elements.xsd
index 02fe8da728aa2233fea3c1c6adbea31708de5bc2..fc44f93df682b41c5ea8182aa2d9202b8239e2df 100644
--- a/lib/internal/Magento/Framework/View/Layout/etc/elements.xsd
+++ b/lib/internal/Magento/Framework/View/Layout/etc/elements.xsd
@@ -108,15 +108,15 @@
 
     <xs:element type="containerReferenceType" name="referenceContainer"/>
 
-    <xs:element type="uiComponentType" name="ui_component">
+    <xs:element type="uiComponentType" name="uiComponent">
         <xs:annotation>
             <xs:documentation>
                 Argument name must be unique in scope of all Blocks, Containers and other UI Components.
             </xs:documentation>
         </xs:annotation>
         <xs:key name="uiElementArgumentName">
-            <xs:selector xpath="./arguments/argument"></xs:selector>
-            <xs:field xpath="@name"></xs:field>
+            <xs:selector xpath="./argument"/>
+            <xs:field xpath="@name"/>
         </xs:key>
     </xs:element>
 
@@ -185,7 +185,7 @@
             <xs:element ref="container" minOccurs="0" maxOccurs="unbounded"/>
             <xs:element ref="referenceBlock" minOccurs="0" maxOccurs="unbounded"/>
             <xs:element ref="referenceContainer" minOccurs="0" maxOccurs="unbounded"/>
-            <xs:element ref="ui_component" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element ref="uiComponent" minOccurs="0" maxOccurs="unbounded"/>
         </xs:sequence>
         <xs:attribute type="elementNameType" name="name"/>
         <xs:attribute type="xs:string" name="label"/>
@@ -216,7 +216,7 @@
             <xs:element ref="block" minOccurs="0" maxOccurs="unbounded"/>
             <xs:element ref="container" minOccurs="0" maxOccurs="unbounded"/>
             <xs:element ref="referenceBlock" minOccurs="0" maxOccurs="unbounded"/>
-            <xs:element ref="ui_component" minOccurs="0" />
+            <xs:element ref="uiComponent" minOccurs="0" />
         </xs:sequence>
         <xs:attribute type="elementNameType" name="name" use="optional"/>
         <xs:attribute type="blockClassType" name="class" use="optional"/>
@@ -238,8 +238,8 @@
                 Part of view that can generate appropriate content.
             </xs:documentation>
         </xs:annotation>
-        <xs:sequence minOccurs="0" maxOccurs="unbounded">
-            <xs:element ref="arguments" minOccurs="0" maxOccurs="1"/>
+        <xs:sequence>
+            <xs:element name="argument" type="argumentType" minOccurs="0" maxOccurs="unbounded"/>
         </xs:sequence>
         <xs:attribute type="componentNameType" name="component" use="optional"/>
         <xs:attribute type="elementNameType" name="name" use="optional"/>
@@ -311,7 +311,7 @@
             <xs:element ref="container" minOccurs="0"/>
             <xs:element ref="referenceBlock" minOccurs="0" />
             <xs:element ref="referenceContainer" minOccurs="0"/>
-            <xs:element ref="ui_component" minOccurs="0" />
+            <xs:element ref="uiComponent" minOccurs="0" />
         </xs:choice>
         <xs:attribute type="elementNameType" name="name" use="required"/>
     </xs:complexType>
@@ -322,7 +322,7 @@
             <xs:element ref="block" minOccurs="0" />
             <xs:element ref="container" minOccurs="0" />
             <xs:element ref="referenceBlock" minOccurs="0" />
-            <xs:element ref="ui_component" minOccurs="0" />
+            <xs:element ref="uiComponent" minOccurs="0" />
         </xs:choice>
         <xs:attribute type="elementNameType" name="name" use="required"/>
         <xs:attribute type="htmlTagType" name="htmlTag"/>
diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Element/MessagesTest.php b/lib/internal/Magento/Framework/View/Test/Unit/Element/MessagesTest.php
index bd18ebe344f884734c1b78233ed278c6c8b6b440..6f552656be534c3322b7f778a769fb55c83a366c 100644
--- a/lib/internal/Magento/Framework/View/Test/Unit/Element/MessagesTest.php
+++ b/lib/internal/Magento/Framework/View/Test/Unit/Element/MessagesTest.php
@@ -9,6 +9,7 @@
  */
 namespace Magento\Framework\View\Test\Unit\Element;
 
+use Magento\Framework\Message\Manager;
 use \Magento\Framework\View\Element\Messages;
 
 use Magento\Framework\Message\ManagerInterface;
@@ -229,7 +230,7 @@ class MessagesTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals($emptyMessagesCacheKey, $this->messages->getCacheKeyInfo());
 
         $messagesCacheKey = ['storage_types' => 'a:1:{i:0;s:7:"default";}'];
-        $this->messages->addStorageType(ManagerInterface::DEFAULT_GROUP);
+        $this->messages->addStorageType(Manager::DEFAULT_GROUP);
         $this->assertEquals($messagesCacheKey, $this->messages->getCacheKeyInfo());
     }
 
diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Layout/Generator/UiComponentTest.php b/lib/internal/Magento/Framework/View/Test/Unit/Layout/Generator/UiComponentTest.php
index a15a926d50882d4c4fe81d5810789070a8a655cb..754a00210c34605eae25089667c656621b08d801 100644
--- a/lib/internal/Magento/Framework/View/Test/Unit/Layout/Generator/UiComponentTest.php
+++ b/lib/internal/Magento/Framework/View/Test/Unit/Layout/Generator/UiComponentTest.php
@@ -39,6 +39,16 @@ class UiComponentTest extends \PHPUnit_Framework_TestCase
      */
     protected $argumentInterpreterMock;
 
+    /**
+     * @var \Magento\Framework\View\Element\UiComponent\ContextFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $contextFactoryMock;
+
+    /**
+     * @var \Magento\Framework\View\Element\BlockFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $blockFactoryMock;
+
     /**
      * @var \Magento\Framework\View\Layout\Generator\UiComponent
      */
@@ -49,17 +59,31 @@ class UiComponentTest extends \PHPUnit_Framework_TestCase
         $this->objectManagerHelper = new ObjectManagerHelper($this);
         $this->argumentInterpreterMock = $this->getMockBuilder('Magento\Framework\Data\Argument\InterpreterInterface')
             ->disableOriginalConstructor()->getMockForAbstractClass();
-
         $this->uiComponentFactoryMock = $this->getMockBuilder('Magento\Framework\View\Element\UiComponentFactory')
             ->disableOriginalConstructor()->getMock();
         $this->scheduledStructureMock = $this->getMockBuilder('Magento\Framework\View\Layout\ScheduledStructure')
             ->disableOriginalConstructor()->getMock();
+        $this->contextFactoryMock = $this->getMock(
+            'Magento\Framework\View\Element\UiComponent\ContextFactory',
+            [],
+            [],
+            '',
+            false
+        );
+        $this->blockFactoryMock = $this->getMock(
+            'Magento\Framework\View\Element\BlockFactory',
+            [],
+            [],
+            '',
+            false
+        );
 
         $this->uiComponent = $this->objectManagerHelper->getObject(
             'Magento\Framework\View\Layout\Generator\UiComponent',
             [
                 'uiComponentFactory' => $this->uiComponentFactoryMock,
-                'argumentInterpreter' => $this->argumentInterpreterMock
+                'blockFactory' => $this->blockFactoryMock,
+                'contextFactory' => $this->contextFactoryMock
             ]
         );
     }
@@ -100,16 +124,50 @@ class UiComponentTest extends \PHPUnit_Framework_TestCase
             ->with($layoutMock)
             ->willReturnSelf();
 
-        $blockMock = $this->getMockBuilder('Magento\Framework\View\Element\AbstractBlock')
-            ->disableOriginalConstructor()->getMock();
+        $componentMock = $this->getMockForAbstractClass(
+            'Magento\Framework\View\Element\UiComponentInterface',
+            [],
+            '',
+            false,
+            true,
+            true,
+            []
+        );
+
+        $contextMock = $this->getMockForAbstractClass(
+            'Magento\Framework\View\Element\UiComponent\ContextInterface',
+            [],
+            '',
+            false
+        );
+        $blockMock = $this->getMockForAbstractClass(
+            'Magento\Framework\View\Element\BlockInterface',
+            [],
+            '',
+            false
+        );
+
+        $this->contextFactoryMock->expects($this->once())
+            ->method('create')
+            ->with(
+                [
+                    'namespace' => 'uiComponent',
+                    'pageLayout' => $layoutMock
+                ]
+            )->willReturn($contextMock);
 
         $this->uiComponentFactoryMock->expects($this->any())
-            ->method('createUiComponent')
+            ->method('create')
             ->with(
-                'component_name',
-                UiComponent::TYPE,
-                ['attribute_1' => 'value_1', 'attribute_2' => 'value_2']
-            )->willReturn($blockMock);
+                'uiComponent',
+                null,
+                ['context' => $contextMock]
+            )->willReturn($componentMock);
+
+        $this->blockFactoryMock->expects($this->once())
+            ->method('createBlock')
+            ->with(UiComponent::CONTAINER, ['component' => $componentMock])
+            ->willReturn($blockMock);
 
         $this->argumentInterpreterMock->expects($this->any())
             ->method('evaluate')
diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Layout/Reader/UiComponentTest.php b/lib/internal/Magento/Framework/View/Test/Unit/Layout/Reader/UiComponentTest.php
index 145c8f6992e9167ec631c92fdb132f38386afac4..1c573b9a2a8915ae92c27111caaa86c10ded1f8c 100644
--- a/lib/internal/Magento/Framework/View/Test/Unit/Layout/Reader/UiComponentTest.php
+++ b/lib/internal/Magento/Framework/View/Test/Unit/Layout/Reader/UiComponentTest.php
@@ -82,8 +82,8 @@ class UiComponentTest extends \PHPUnit_Framework_TestCase
         return [
             [
                 $this->getElement(
-                    '<ui_component name="cms_block_listing" component="listing" ifconfig="config_path"/>',
-                    'ui_component'
+                    '<uiComponent name="cms_block_listing" component="listing" ifconfig="config_path"/>',
+                    'uiComponent'
                 ),
             ]
         ];
diff --git a/lib/internal/Magento/Framework/View/Test/Unit/LayoutTest.php b/lib/internal/Magento/Framework/View/Test/Unit/LayoutTest.php
index 45effcf449e43c4e7a05dcc77d37003195069eea..3d60c5e411300fd1ba642d03ed96720959434828 100644
--- a/lib/internal/Magento/Framework/View/Test/Unit/LayoutTest.php
+++ b/lib/internal/Magento/Framework/View/Test/Unit/LayoutTest.php
@@ -134,9 +134,6 @@ class LayoutTest extends \PHPUnit_Framework_TestCase
         $this->readerContextMock = $this->getMockBuilder('Magento\Framework\View\Layout\Reader\Context')
             ->disableOriginalConstructor()
             ->getMock();
-        $this->readerContextFactoryMock->expects($this->once())
-            ->method('create')
-            ->willReturn($this->readerContextMock);
         $this->generatorContextFactoryMock = $this->getMockBuilder(
             'Magento\Framework\View\Layout\Generator\ContextFactory'
         )->disableOriginalConstructor()
@@ -683,6 +680,9 @@ class LayoutTest extends \PHPUnit_Framework_TestCase
 
     public function testGenerateElementsWithoutCache()
     {
+        $this->readerContextFactoryMock->expects($this->once())
+            ->method('create')
+            ->willReturn($this->readerContextMock);
         $layoutCacheId = 'layout_cache_id';
         $handles = ['default', 'another'];
         /** @var \Magento\Framework\View\Layout\Element $xml */
@@ -807,4 +807,10 @@ class LayoutTest extends \PHPUnit_Framework_TestCase
 
         $this->model->generateElements();
     }
+
+    public function testGetXml()
+    {
+        $xml = '<layout/>';
+        $this->assertSame($xml, \Magento\Framework\View\Layout::LAYOUT_NODE);
+    }
 }
diff --git a/lib/internal/Magento/Framework/Webapi/ServiceOutputProcessor.php b/lib/internal/Magento/Framework/Webapi/ServiceOutputProcessor.php
index 79cd652f4b22e85a9abc8299e6d6180f4e6037d0..1bf5137218bf4de0d49039d61593c1730a9d871c 100644
--- a/lib/internal/Magento/Framework/Webapi/ServiceOutputProcessor.php
+++ b/lib/internal/Magento/Framework/Webapi/ServiceOutputProcessor.php
@@ -8,6 +8,7 @@ namespace Magento\Framework\Webapi;
 use Magento\Framework\Api\AbstractExtensibleObject;
 use Magento\Framework\Api\ExtensibleDataObjectConverter;
 use Magento\Framework\Reflection\DataObjectProcessor;
+use Magento\Framework\Reflection\MethodsMap;
 
 /**
  * Data object converter for REST
@@ -19,12 +20,21 @@ class ServiceOutputProcessor
      */
     protected $dataObjectProcessor;
 
+    /**
+     * @var MethodsMap
+     */
+    protected $methodsMapProcessor;
+
     /**
      * @param DataObjectProcessor $dataObjectProcessor
+     * @param MethodsMap $methodsMapProcessor
      */
-    public function __construct(DataObjectProcessor $dataObjectProcessor)
-    {
+    public function __construct(
+        DataObjectProcessor $dataObjectProcessor,
+        MethodsMap $methodsMapProcessor
+    ) {
         $this->dataObjectProcessor = $dataObjectProcessor;
+        $this->methodsMapProcessor = $methodsMapProcessor;
     }
 
     /**
@@ -44,7 +54,7 @@ class ServiceOutputProcessor
     public function process($data, $serviceClassName, $serviceMethodName)
     {
         /** @var string $dataType */
-        $dataType = $this->dataObjectProcessor->getMethodReturnType($serviceClassName, $serviceMethodName);
+        $dataType = $this->methodsMapProcessor->getMethodReturnType($serviceClassName, $serviceMethodName);
         if (is_array($data)) {
             $result = [];
             $arrayElementType = substr($dataType, 0, -2);
diff --git a/lib/internal/Magento/Framework/composer.json b/lib/internal/Magento/Framework/composer.json
index 769a3a5d91d3f53dba9d6c08ee4fb4a25dbe4732..c2cf9161040653d1d6a8628baaee2e045fb075b3 100644
--- a/lib/internal/Magento/Framework/composer.json
+++ b/lib/internal/Magento/Framework/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/framework",
     "description": "N/A",
     "type": "magento2-library",
-    "version": "0.74.0-beta6",
+    "version": "0.74.0-beta7",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/lib/web/css/source/lib/_utilities.less b/lib/web/css/source/lib/_utilities.less
index fe49f1b1cbaf9eb97148dd655ce000b4ce7ecccd..0b31aaa2f1132525036f04c4e9907ad4ca018927 100644
--- a/lib/web/css/source/lib/_utilities.less
+++ b/lib/web/css/source/lib/_utilities.less
@@ -467,9 +467,18 @@
     appearance: @value;
 }
 
+.vendor-prefix-column-count (
+    @_value
+) {
+    -webkit-column-count: @_value;
+       -moz-column-count: @_value;
+            column-count: @_value;
+}
+
 //
 //  Pointer for popups or dropdowns
 //  ---------------------------------------------
+
 .pointer(
     @_size: 6px,
     @_background-color: @color-white,
diff --git a/lib/web/date-format-normalizer.js b/lib/web/date-format-normalizer.js
deleted file mode 100644
index f7a50afc01a7243a05da62324ecb40325e45a9d7..0000000000000000000000000000000000000000
--- a/lib/web/date-format-normalizer.js
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-define([],function(){
-    'use strict';
-
-    var formatCache = {};
-
-    function Formatter() {
-
-        /**
-         * Convert from string-Magento-date-format
-         * to string-moment-js-date-format. Result
-         * stored in internal cache.
-         * @param {String} zendFormat
-         * @return {String}
-         */
-        return function(zendFormat) {
-            var momentFormat = '';
-
-            if(formatCache[zendFormat]) {
-                momentFormat = formatCache[zendFormat];
-            } else {
-                // List of differences. Got from 'MMM d, y h:mm:ss a' -> "MMM D, YYYY h:mm:ss A"
-                momentFormat = String(zendFormat).
-                    replace('D','DDD').
-                    replace('dd','DD').
-                    replace('d','D').
-                    replace('EEEE','dddd').
-                    replace('EEE','ddd').
-                    replace('e','d').
-                    replace('y','YYYY').
-                    replace('a','A').
-                    toString();
-                formatCache[zendFormat] = momentFormat;
-            }
-
-            return momentFormat;
-        }
-    }
-
-    return new Formatter;
-});
\ No newline at end of file
diff --git a/lib/web/mage/adminhtml/globals.js b/lib/web/mage/adminhtml/globals.js
new file mode 100644
index 0000000000000000000000000000000000000000..c9f708bd6846e7f4366f43232148d1bccba6e5d3
--- /dev/null
+++ b/lib/web/mage/adminhtml/globals.js
@@ -0,0 +1,16 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+], function () {
+    'use strict';
+
+    /**
+     * Set of a temporary methods used to provide
+     * backward compatability with a legacy code.
+     */
+    window.setLocation = function (url) {
+        window.location.href = url;
+    };
+});
diff --git a/lib/web/mage/utils.js b/lib/web/mage/utils.js
deleted file mode 100644
index 239fca6d918ea5e78c51249e147f1a1be49e0c23..0000000000000000000000000000000000000000
--- a/lib/web/mage/utils.js
+++ /dev/null
@@ -1,451 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-//TODO: assemble all util methods in this module
-define([
-    'underscore'
-], function (_) {
-    'use strict';
-
-    var tplRegxp = /\{(\w*)\}/g;
-
-    /** @namespace */
-    var utils = {};
-
-    /**
-     * Replaces matches of '{*}' pattern with a matched property in 'data' object.
-     * @private
-     *
-     * @param {String} tpl - String to process.
-     * @param {Object} data - Data to match with pattern.
-     * @returns {String} Modified string.
-     *
-     * @example
-     *      template('Hello {one}!', {one: 'World'});
-     *      => 'Hello World!';
-     */
-    function template(tpl, data){
-        return tpl.replace(tplRegxp, function(match, key){
-            return data.hasOwnProperty(key) ? data[key] : '';
-        });
-    }
-
-    /**
-     * Sets nested property of a specified object.
-     * @private
-     *
-     * @param {Object} parent - Object to look inside for the properties.
-     * @param {Array} path - Splitted path the property.
-     * @param {*} value - Value of the last property in 'path' array.
-     * returns {*} New value for the property.
-     */
-    function setNested(parent, path, value){
-        var last = path.pop();
-
-        path.forEach(function(part) {
-            if (_.isUndefined(parent[part])) {
-                parent[part] = {};
-            }
-
-            parent = parent[part];
-        });
-
-        return (parent[last] = value);
-    }
-
-    /**
-     * Retrieves value of a nested property.
-     * @private
-     *
-     * @param {Object} parent - Object to look inside for the properties.
-     * @param {Array} path - Splitted path the property.
-     * @returns {*} Value of the property.
-     */
-    function getNested(parent, path){
-        var exists;
-
-        exists = path.every(function(part) {
-            parent = parent[part];
-
-            return !_.isUndefined(parent);
-        });
-
-        if(exists){
-            return parent;
-        }
-    }
-
-    /**
-     * Removes property from a specified object.
-     * @private
-     *
-     * @param {Object} parent - Object from which to remove property. 
-     * @param {Array} path - Splitted path to the propery.
-     */
-    function removeNested(parent, path) {
-        var field = path.pop();
-
-        parent = getNested(parent, path);
-
-        if (_.isObject(parent)) {
-            delete parent[field];
-        }
-    }
-
-    /**
-     * Object manipulation methods.
-     */
-    _.extend(utils, {
-        /**
-         * Retrieves or defines objects' property by a composite path.
-         *
-         * @param {Object} data - Container for the properties specified in path.
-         * @param {String} path - Objects' properties divided by dots.
-         * @param {*} [value] - New value for the last property.
-         * @returns {*} Returns value of the last property in chain.
-         *
-         * @example
-         *      utils.nested({}, 'one.two', 3);
-         *      => { one: {two: 3} }
-         */
-        nested: function(data, path, value){
-            var action = arguments.length > 2 ? setNested : getNested;
-
-            path = path ? path.split('.') : [];
-
-            return action(data, path, value);
-        },
-
-        /**
-         * Removes nested property from an object.
-         *
-         * @param {Object} data - Data source.
-         * @param {String} path - Path to the property e.g. 'one.two.three'
-         */
-        nestedRemove: function(data, path) {
-            path = path.split('.');
-
-            removeNested(data, path);
-        },
-
-        /**
-         * Flattens objects' nested properties.
-         *
-         * @param {Object} data - Object to flatten.
-         * @param {String} [separator='.'] - Objects' keys separator.
-         * @returns {Object} Flattened object.
-         *
-         * @example Example with a default separator.
-         *      utils.flatten({one: { two: { three: 'value'} }});
-         *      => { 'one.two.three': 'value' };
-         *
-         * @example Example with a custom separator.
-         *      utils.flatten({one: { two: { three: 'value'} }}, '=>');
-         *      => {'one=>two=>three': 'value'};
-         */
-        flatten: function(data, separator, parent, result){
-            separator   = separator || '.';
-            result      = result || {};
-
-            _.each(data, function(node, name){
-                if(parent){
-                    name = parent + separator + name;
-                }
-
-                typeof node === 'object' ?
-                    this.flatten(node, separator, name, result) :
-                    (result[name] = node);
-
-            }, this);
-
-            return result;
-        },
-
-        /**
-         * Opposite operation of the 'flatten' method.
-         *
-         * @param {Object} data - Previously flattened object.
-         * @param {String} [separator='.'] - Keys separator.
-         * @returns {Object} Object with nested properties.
-         *
-         * @example Example using custom separator.
-         *      utils.unflatten({'one=>two': 'value'}, '=>');
-         *      => {
-         *          one: { two: 'value' }
-         *      };      
-         */
-        unflatten: function(data, separator){
-            var result = {};
-
-            separator = separator || '.';
-
-            _.each(data, function(value, nodes){
-                nodes = nodes.split(separator);
-
-                setNested(result, nodes, value);
-            });
-
-            return result;
-        },
-
-        /**
-         * Same operation as 'flatten' method,
-         * but returns objects' keys wrapped in '[]'.
-         *
-         * @param {Object} data - Object that should be serialized.
-         * @returns {Object} Serialized data.
-         *
-         * @example
-         *      utils.serialize({one: { two: { three: 'value'} }});
-         *      => { 'one[two][three]': 'value' }
-         */
-        serialize: function(data){
-            var result = {};
-
-            data = this.flatten(data);
-
-            _.each(data, function(value, keys){
-                keys    = this.serializeName(keys);
-                value   = _.isUndefined(value) ? '' : value;
-
-                result[keys] = value;
-            }, this);
-
-            return result;
-        },
-
-        /**
-         * Applies provided data to the template.
-         *
-         * @param {(String|Object)} template
-         * @param {Object} source - Data object to match with template.
-         * @returns {String|Object}
-         *
-         * @example Template defined as a string.
-         *      var source = { foo: 'Random Stuff', bar: 'Some' };
-         *      
-         *      utils.template('{bar} {foo}', source);
-         *      => 'Some Random Stuff';
-         *
-         * @example Example of template defined as object.
-         *      var tpl = { key: { '{bar}_Baz': '{foo}' } };
-         *
-         *      utils.template(tpl, source);
-         *      => { key: { 'Some_Baz': 'Random Stuff' } };
-         */
-        template: function(templ, source){
-            var result,
-                parse;
-
-            if(_.isObject(templ)){
-                templ   = JSON.stringify(templ);
-                parse   = true;
-            }
-
-            result = template(templ, source);
-
-            return parse ? JSON.parse(result) : result;
-        }
-    });
-    
-    /**
-     * Helpers for working with strings.
-     */
-    _.extend(utils, {
-        /**
-         * Splits string by separator if it's possible,
-         * otherwise returns the incoming value.
-         *
-         * @param {(String|Array|*)} str - String to split. 
-         * @param {String} [separator=' '] - Seperator based on which to split the string. 
-         * @returns {Array|*} Splitted string or the incoming value.
-         */
-        stringToArray: function(str, separator){
-            separator = separator || ' ';
-
-            return typeof str === 'string' ?
-                str.split(separator) :
-                str;
-        },
-
-        /**
-         * Converts the incoming string which consists
-         * of a specified delimiters into a format commonly used in form elements.
-         *
-         * @param {String} name - The incoming string.
-         * @param {String} [separator='.']
-         * @returns {String} Serialized string.
-         *
-         * @example
-         *      utils.serializeName('one.two.three');
-         *      => 'one[two][three]';
-         */
-        serializeName: function(name, separator){
-            var result;
-
-            separator   = separator || '.';
-            name        = name.split(separator);
-
-            result = name.shift();
-
-            name.forEach(function(part){
-                result += '[' + part + ']';
-            });
-
-            return result;
-        }
-    });
-    
-    /**
-     * Array manipulation methods.
-     */
-    _.extend(utils, {
-        /**
-         * Facade method to remove/add value from/to array
-         * without creating a new instance.
-         *
-         * @param {Array} arr - Array to be modified. 
-         * @param {*} value - Value to add/remove.
-         * @param {Boolean} add - Flag that specfies operation.
-         * @returns {Utils} Chainable.
-         */
-        toggle: function(arr, value, add){
-            return add ? 
-                this.add(arr, value) :
-                this.remove(arr, value);
-        },
-
-        /**
-         * Removes the incoming value from array in case
-         * without creating a new instance of it.
-         *
-         * @param {Array} arr - Array to be modified.
-         * @param {*} value - Value to be removed.
-         * @returns {Utils} Chainable.
-         */
-        remove: function(arr, value){
-            var index = arr.indexOf(value);
-
-            if(~index){
-                arr.splice(index, 1);
-            }
-
-            return this;
-        },
-
-        /**
-         * Adds the incoming value to array if
-         * it's not alredy present in there.
-         *
-         * @param {Array} arr - Array to be modifed. 
-         * @param {...*} Values to be added.
-         * @returns {Utils} Chainable.
-         */
-        add: function(arr){
-            var values = _.toArray(arguments).slice(1);
-
-            values.forEach(function(value){
-                if(!~arr.indexOf(value)){
-                    arr.push(value);
-                }
-            });
-
-            return this;
-        },
-
-        /**
-         * Extends an incoming array with a specified ammount of undefined values
-         * starting from a specified position.
-         *
-         * @param {Array} container - Array to be extended.
-         * @param {Number} size - Ammount of values to be added.
-         * @param {Number} [offset=0] - Position at which to start inserting values.
-         * @returns {Array} Modified array.
-         */
-        reserve: function(container, size, offset){
-            container.splice(offset || 0, 0, new Array(size));
-
-            return _.flatten(container);
-        },
-
-        /**
-         * Compares multiple arrays without tracking order of their elements.
-         *
-         * @param {...Array} Multiple arrays to compare.
-         * @returns {Bollean} True if arrays are identical to each other.
-         */
-        identical: function(){
-            var arrays  = _.toArray(arguments),
-                first   = arrays.shift();
-
-            return arrays.every(function(arr) {
-                return (
-                    arr.length === first.length &&
-                    !_.difference(arr, first).length
-                );
-            });
-        }
-    });
-
-    /**
-     * Miscellaneous.
-     */
-    _.extend(utils, {
-        /**
-         * Generates a unique identifier.
-         *
-         * @param {Number} [size=7] - Length of a resulting identifier.
-         * @returns {String}
-         */
-        uniqueid: function (size) {
-            var code    = (Math.random() * 25 + 65) | 0,
-                idstr   = String.fromCharCode(code);
-
-            size = size || 7;
-
-            while (idstr.length < size) {
-                code = Math.floor((Math.random() * 42) + 48);
-
-                if (code < 58 || code > 64) {
-                    idstr += String.fromCharCode(code);
-                }
-            }
-
-            return idstr;
-        },
-
-        /**
-         * Serializes and sends data via POST request.
-         *
-         * @param {Object} options -
-         *      Options object that consists of
-         *      a 'url' and 'data' properties. 
-         */
-        submit: function(options){
-            var form = document.createElement('form'),
-                data = this.serialize(options.data),
-                field;
-
-            form.setAttribute('action', options.url);
-            form.setAttribute('method', 'post');
-
-            _.each(data, function(value, name){
-                field = document.createElement('input');
-
-                field.setAttribute('name', name);
-                field.setAttribute('type', 'hidden');
-
-                field.value = value;
-
-                form.appendChild(field);
-            });
-
-            document.body.appendChild(form);
-
-            form.submit();
-        }
-    });
-
-    return utils;
-});
\ No newline at end of file
diff --git a/lib/web/mage/utils/arrays.js b/lib/web/mage/utils/arrays.js
new file mode 100644
index 0000000000000000000000000000000000000000..54fb9a6189a8df0335808a989c5be5b859643ed8
--- /dev/null
+++ b/lib/web/mage/utils/arrays.js
@@ -0,0 +1,110 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+    'underscore',
+    './strings'
+], function (_, utils) {
+    'use strict';
+
+    return {
+       /**
+         * Facade method to remove/add value from/to array
+         * without creating a new instance.
+         *
+         * @param {Array} arr - Array to be modified.
+         * @param {*} value - Value to add/remove.
+         * @param {Boolean} add - Flag that specfies operation.
+         * @returns {Utils} Chainable.
+         */
+        toggle: function (arr, value, add) {
+            return add ?
+                this.add(arr, value) :
+                this.remove(arr, value);
+        },
+
+        /**
+         * Removes the incoming value from array in case
+         * without creating a new instance of it.
+         *
+         * @param {Array} arr - Array to be modified.
+         * @param {*} value - Value to be removed.
+         * @returns {Utils} Chainable.
+         */
+        remove: function (arr, value) {
+            var index = arr.indexOf(value);
+
+            if (~index) {
+                arr.splice(index, 1);
+            }
+
+            return this;
+        },
+
+        /**
+         * Adds the incoming value to array if
+         * it's not alredy present in there.
+         *
+         * @param {Array} arr - Array to be modifed.
+         * @param {...*} Values to be added.
+         * @returns {Utils} Chainable.
+         */
+        add: function (arr) {
+            var values = _.toArray(arguments).slice(1);
+
+            values.forEach(function (value) {
+                if (!~arr.indexOf(value)) {
+                    arr.push(value);
+                }
+            });
+
+            return this;
+        },
+
+        /**
+         * Extends an incoming array with a specified ammount of undefined values
+         * starting from a specified position.
+         *
+         * @param {Array} container - Array to be extended.
+         * @param {Number} size - Ammount of values to be added.
+         * @param {Number} [offset=0] - Position at which to start inserting values.
+         * @returns {Array} Modified array.
+         */
+        reserve: function (container, size, offset) {
+            container.splice(offset || 0, 0, new Array(size));
+
+            return _.flatten(container);
+        },
+
+        /**
+         * Compares multiple arrays without tracking order of their elements.
+         *
+         * @param {...Array} Multiple arrays to compare.
+         * @returns {Bollean} True if arrays are identical to each other.
+         */
+        identical: function () {
+            var arrays = _.toArray(arguments),
+                first = arrays.shift();
+
+            return arrays.every(function (arr) {
+                return arr.length === first.length &&
+                    !_.difference(arr, first).length;
+            });
+        },
+
+        formatOffset: function(elems, offset) {
+            if (utils.isEmpty(offset)) {
+                offset = -1;
+            }
+
+            offset = +offset;
+
+            if (offset < 0) {
+                offset += elems.length + 1;
+            }
+
+            return offset;
+        }
+    };
+});
diff --git a/lib/web/mage/utils/compare.js b/lib/web/mage/utils/compare.js
new file mode 100644
index 0000000000000000000000000000000000000000..f71e1bf8922273a2d40817151ffa00599f070c7e
--- /dev/null
+++ b/lib/web/mage/utils/compare.js
@@ -0,0 +1,133 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+    'underscore',
+    'mage/utils/objects'
+], function (_, utils) {
+    'use strict';
+
+    var primitives = [
+        'undefined',
+        'boolean',
+        'number',
+        'string'
+    ];
+
+    function isDifferent(a, b) {
+        var oldIsPrimitive = a === null || ~primitives.indexOf(typeof a);
+
+        return oldIsPrimitive ? a !== b : true;
+    }
+
+    function fullPath(prefix, part) {
+        return prefix ? prefix + '.' + part : part;
+    }
+
+    function format(name, newValue, oldValue, type) {
+        return {
+            name: name,
+            type: type,
+            value: newValue,
+            oldValue: oldValue
+        };
+    }
+
+    function flatten(obj, ns, result) {
+        result = result || {};
+        ns = ns || '';
+
+        if (!utils.isObject(obj)) {
+            obj = {};
+        }
+
+        _.each(obj, function (value, key) {
+            key = fullPath(ns, key);
+
+            if (utils.isObject(value)) {
+                flatten(value, key, result);
+            }
+
+            result[key] = value;
+        });
+
+        return result;
+    }
+
+    function getConatiners(changes) {
+        var indexed,
+            result = {};
+
+        indexed = _.indexBy(changes, 'name');
+
+        _.each(indexed, function (change, name) {
+            var path;
+
+            name = name.split('.');
+
+            name.forEach(function (part) {
+                path = fullPath(path, part);
+
+                if (!_.has(indexed, path)) {
+                    result[path] = result[path] || [];
+                    result[path].push(change);
+                }
+            });
+        });
+
+        return result;
+    }
+
+    function getModified(oldValues, current, key) {
+        var previous,
+            someIsObject;
+
+        if (_.has(oldValues, key)) {
+            previous = oldValues[key];
+            someIsObject = !utils.isObject(previous) || !utils.isObject(current);
+
+            if (someIsObject && isDifferent(previous, current)) {
+                return format(key, current, previous, 'update');
+            }
+        } else {
+            return format(key, current, undefined, 'add');
+        }
+    }
+
+    function getRemoved(newValues, previous, key) {
+        if (!_.has(newValues, key)) {
+            return format(key, undefined, previous, 'remove');
+        }
+    }
+
+    function compare(oldObj, newObj, ns) {
+        var removed,
+            modfied;
+
+        oldObj = flatten(oldObj, ns);
+        newObj = flatten(newObj, ns);
+
+        removed = _.map(oldObj, getRemoved.bind(null, newObj)),
+        modfied = _.map(newObj, getModified.bind(null, oldObj));
+
+        return _.compact(Array.prototype.concat(removed, modfied));
+    }
+
+    return {
+        compare: function (oldValue, newValue, ns) {
+            var changes = [];
+
+            if (utils.isObject(oldValue) || utils.isObject(newValue)) {
+                changes = compare.apply(null, arguments);
+            } else if (isDifferent(oldValue, newValue)) {
+                changes.push(format(ns, newValue, oldValue, 'update'));
+            }
+
+            return {
+                containers: getConatiners(changes),
+                changes: changes
+            };
+        }
+    };
+});
diff --git a/lib/web/mage/utils/main.js b/lib/web/mage/utils/main.js
new file mode 100644
index 0000000000000000000000000000000000000000..82b56e713e8c063b1f4d4920ae3d9a58bbf18478
--- /dev/null
+++ b/lib/web/mage/utils/main.js
@@ -0,0 +1,20 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define(function (require) {
+    'use strict';
+
+    var utils = {},
+        _ = require('underscore');
+
+    return _.extend(
+        utils,
+        require('./arrays'),
+        require('./compare'),
+        require('./misc'),
+        require('./objects'),
+        require('./strings'),
+        require('./template')
+    );
+});
diff --git a/lib/web/mage/utils/misc.js b/lib/web/mage/utils/misc.js
new file mode 100644
index 0000000000000000000000000000000000000000..5b24831adaf97483335f910fe97e5b026d58d796
--- /dev/null
+++ b/lib/web/mage/utils/misc.js
@@ -0,0 +1,117 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+    'underscore'
+], function (_) {
+    'use strict';
+
+    var map = {
+        'D': 'DDD',
+        'dd': 'DD',
+        'd': 'D',
+        'EEEE': 'dddd',
+        'EEE': 'ddd',
+        'e': 'd',
+        'y': 'YYYY',
+        'a': 'A'
+    };
+
+    function limitWrapper(data) {
+        var args = _.toArray(arguments).splice(1);
+
+        if (data.id) {
+            window.clearTimeout(data.id);
+        }
+
+        data.id = window.setTimeout(function () {
+            delete data.id;
+
+            data.fn.apply(data.owner, args);
+        }, data.limit);
+    }
+
+    return {
+        /**
+         * Generates a unique identifier.
+         *
+         * @param {Number} [size=7] - Length of a resulting identifier.
+         * @returns {String}
+         */
+        uniqueid: function (size) {
+            var code = Math.random() * 25 + 65 | 0,
+                idstr = String.fromCharCode(code);
+
+            size = size || 7;
+
+            while (idstr.length < size) {
+                code = Math.floor(Math.random() * 42 + 48);
+
+                if (code < 58 || code > 64) {
+                    idstr += String.fromCharCode(code);
+                }
+            }
+
+            return idstr;
+        },
+
+        limit: function (owner, target, limit) {
+            var data = {
+                owner: owner,
+                limit: limit,
+                fn: owner[target]
+            };
+
+            owner[target] = limitWrapper.bind(null, data);
+        },
+
+        /**
+         * Converts mage date format to a moment.js format.
+         *
+         * @param {String} mageFormat
+         * @returns {String}
+         */
+        normalizeDate: function (mageFormat) {
+            var result = mageFormat;
+
+            _.each(map, function (moment, mage) {
+                result = result.replace(mage, moment);
+            });
+
+            return result;
+        },
+
+        /**
+         * Serializes and sends data via POST request.
+         *
+         * @param {Object} options - Options object that consists of
+         *      a 'url' and 'data' properties.
+         */
+        submit: function (options) {
+            var form = document.createElement('form'),
+                data = this.serialize(options.data),
+                field;
+
+            data.form_key = FORM_KEY;
+
+            form.setAttribute('action', options.url);
+            form.setAttribute('method', 'post');
+
+            _.each(data, function (value, name) {
+                field = document.createElement('input');
+
+                field.setAttribute('name', name);
+                field.setAttribute('type', 'hidden');
+
+                field.value = value;
+
+                form.appendChild(field);
+            });
+
+            document.body.appendChild(form);
+
+            form.submit();
+        }
+    };
+});
diff --git a/lib/web/mage/utils/objects.js b/lib/web/mage/utils/objects.js
new file mode 100644
index 0000000000000000000000000000000000000000..c2d88f8386227a7779c310ff9890a11142c3c5d7
--- /dev/null
+++ b/lib/web/mage/utils/objects.js
@@ -0,0 +1,228 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+    'jquery',
+    'underscore'
+], function ($, _) {
+    'use strict';
+
+    /**
+     * Sets nested property of a specified object.
+     * @private
+     *
+     * @param {Object} parent - Object to look inside for the properties.
+     * @param {Array} path - Splitted path the property.
+     * @param {*} value - Value of the last property in 'path' array.
+     * returns {*} New value for the property.
+     */
+    function setNested(parent, path, value) {
+        var last = path.pop();
+
+        path.forEach(function (part) {
+            if (_.isUndefined(parent[part])) {
+                parent[part] = {};
+            }
+
+            parent = parent[part];
+        });
+
+        parent[last] = value;
+
+        return value;
+    }
+
+    /**
+     * Retrieves value of a nested property.
+     * @private
+     *
+     * @param {Object} parent - Object to look inside for the properties.
+     * @param {Array} path - Splitted path the property.
+     * @returns {*} Value of the property.
+     */
+    function getNested(parent, path) {
+        var exists;
+
+        exists = path.every(function (part) {
+            parent = parent[part];
+
+            return !_.isUndefined(parent);
+        });
+
+        if (exists) {
+            return parent;
+        }
+    }
+
+    /**
+     * Removes property from a specified object.
+     * @private
+     *
+     * @param {Object} parent - Object from which to remove property.
+     * @param {Array} path - Splitted path to the propery.
+     */
+    function removeNested(parent, path) {
+        var field = path.pop();
+
+        parent = getNested(parent, path);
+
+        if (_.isObject(parent)) {
+            delete parent[field];
+        }
+    }
+
+    return {
+        /**
+         * Retrieves or defines objects' property by a composite path.
+         *
+         * @param {Object} data - Container for the properties specified in path.
+         * @param {String} path - Objects' properties divided by dots.
+         * @param {*} [value] - New value for the last property.
+         * @returns {*} Returns value of the last property in chain.
+         *
+         * @example
+         *      utils.nested({}, 'one.two', 3);
+         *      => { one: {two: 3} }
+         */
+        nested: function (data, path, value) {
+            var action = arguments.length > 2 ? setNested : getNested;
+
+            path = path ? path.split('.') : [];
+
+            return action(data, path, value);
+        },
+
+        /**
+         * Removes nested property from an object.
+         *
+         * @param {Object} data - Data source.
+         * @param {String} path - Path to the property e.g. 'one.two.three'
+         */
+        nestedRemove: function (data, path) {
+            path = path.split('.');
+
+            removeNested(data, path);
+        },
+
+        /**
+         * Flattens objects' nested properties.
+         *
+         * @param {Object} data - Object to flatten.
+         * @param {String} [separator='.'] - Objects' keys separator.
+         * @returns {Object} Flattened object.
+         *
+         * @example Example with a default separator.
+         *      utils.flatten({one: { two: { three: 'value'} }});
+         *      => { 'one.two.three': 'value' };
+         *
+         * @example Example with a custom separator.
+         *      utils.flatten({one: { two: { three: 'value'} }}, '=>');
+         *      => {'one=>two=>three': 'value'};
+         */
+        flatten: function (data, separator, parent, result) {
+            separator = separator || '.';
+            result = result || {};
+
+            _.each(data, function (node, name) {
+                if (parent) {
+                    name = parent + separator + name;
+                }
+
+                typeof node === 'object' ?
+                    this.flatten(node, separator, name, result) :
+                    result[name] = node;
+
+            }, this);
+
+            return result;
+        },
+
+        /**
+         * Opposite operation of the 'flatten' method.
+         *
+         * @param {Object} data - Previously flattened object.
+         * @param {String} [separator='.'] - Keys separator.
+         * @returns {Object} Object with nested properties.
+         *
+         * @example Example using custom separator.
+         *      utils.unflatten({'one=>two': 'value'}, '=>');
+         *      => {
+         *          one: { two: 'value' }
+         *      };
+         */
+        unflatten: function (data, separator) {
+            var result = {};
+
+            separator = separator || '.';
+
+            _.each(data, function (value, nodes) {
+                nodes = nodes.split(separator);
+
+                setNested(result, nodes, value);
+            });
+
+            return result;
+        },
+
+        /**
+         * Same operation as 'flatten' method,
+         * but returns objects' keys wrapped in '[]'.
+         *
+         * @param {Object} data - Object that should be serialized.
+         * @returns {Object} Serialized data.
+         *
+         * @example
+         *      utils.serialize({one: { two: { three: 'value'} }});
+         *      => { 'one[two][three]': 'value' }
+         */
+        serialize: function (data) {
+            var result = {};
+
+            data = this.flatten(data);
+
+            _.each(data, function (value, keys) {
+                keys = this.serializeName(keys);
+                value = _.isUndefined(value) ? '' : value;
+
+                result[keys] = value;
+            }, this);
+
+            return result;
+        },
+
+        extend: function (target) {
+            var extenders = _.toArray(arguments).splice(1),
+                clone,
+                src;
+
+            extenders.forEach(function (node) {
+                _.each(node, function (value, key) {
+                    src = target[key];
+
+                    if (this.isObject(value) || Array.isArray(value)) {
+                        if (Array.isArray(value)) {
+                            clone = src && Array.isArray(src) ? src : [];
+                        } else {
+                            clone = src && this.isObject(src) ? src : {};
+                        }
+
+                        target[key] = this.extend(clone, value);
+                    } else if (!_.isUndefined(value)) {
+                        target[key] = value;
+                    }
+                }, this);
+            }, this);
+
+            return target;
+        },
+
+        isObject: function (data) {
+            var objProto = Object.prototype;
+
+            return typeof data == 'object' ?
+                objProto.toString.call(data) === '[object Object]' :
+                false;
+        }
+    };
+});
diff --git a/lib/web/mage/utils/strings.js b/lib/web/mage/utils/strings.js
new file mode 100644
index 0000000000000000000000000000000000000000..185951886aaf3271e84cfc4d79d16016aec1d5ef
--- /dev/null
+++ b/lib/web/mage/utils/strings.js
@@ -0,0 +1,69 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+    'underscore'
+], function (_) {
+    'use strict';
+
+    return {
+        /**
+         * Splits string by separator if it's possible,
+         * otherwise returns the incoming value.
+         *
+         * @param {(String|Array|*)} str - String to split.
+         * @param {String} [separator=' '] - Seperator based on which to split the string.
+         * @returns {Array|*} Splitted string or the incoming value.
+         */
+        stringToArray: function (str, separator) {
+            separator = separator || ' ';
+
+            return typeof str === 'string' ?
+                str.split(separator) :
+                str;
+        },
+
+        /**
+         * Converts the incoming string which consists
+         * of a specified delimiters into a format commonly used in form elements.
+         *
+         * @param {String} name - The incoming string.
+         * @param {String} [separator='.']
+         * @returns {String} Serialized string.
+         *
+         * @example
+         *      utils.serializeName('one.two.three');
+         *      => 'one[two][three]';
+         */
+        serializeName: function (name, separator) {
+            var result;
+
+            separator = separator || '.';
+            name = name.split(separator);
+
+            result = name.shift();
+
+            name.forEach(function (part) {
+                result += '[' + part + ']';
+            });
+
+            return result;
+        },
+
+        /**
+         * Checks wether the incoming value is not empty,
+         * e.g. not 'null' or 'undefined'
+         *
+         * @param {*} value - Value to check.
+         * @returns {Boolean}
+         */
+        isEmpty: function (value) {
+            return value === '' || _.isUndefined(value) || _.isNull(value);
+        },
+
+        fullPath: function (prefix, part) {
+            return prefix ? prefix + '.' + part : part;
+        }
+    };
+});
diff --git a/lib/web/mage/utils/template.js b/lib/web/mage/utils/template.js
new file mode 100644
index 0000000000000000000000000000000000000000..86c53247dcf9776400136e09e5e56f434c50481e
--- /dev/null
+++ b/lib/web/mage/utils/template.js
@@ -0,0 +1,84 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+    'underscore',
+    'mage/utils/objects'
+], function (_, utils) {
+    'use strict';
+
+    var opener = '<%';
+
+    function isTemplate(value) {
+        return _.isString(value) && ~value.indexOf(opener);
+    }
+
+    function render(tmpl, data) {
+        var last = tmpl;
+
+        data = Object.create(data);
+
+        while (~tmpl.indexOf(opener)) {
+            tmpl = _.template(tmpl)(data);
+
+            if (tmpl === last) {
+                break;
+            }
+
+            last = tmpl;
+        }
+
+        return tmpl;
+    }
+
+    return {
+        /**
+         * Applies provided data to the template.
+         *
+         * @param {Object} tmpl
+         * @param {Object} [$data] - Data object to match with template.
+         * @returns {Object}
+         *
+         * @example Template defined as a string.
+         *      var source = { foo: 'Random Stuff', bar: 'Some' };
+         *
+         *      utils.template('{bar} {foo}', source);
+         *      => 'Some Random Stuff';
+         *
+         * @example Example of template defined as object.
+         *      var tpl = { key: { '{bar}_Baz': '{foo}' } };
+         *
+         *      utils.template(tpl, source);
+         *      => { key: { 'Some_Baz': 'Random Stuff' } };
+         */
+        template: function (tmpl, $data) {
+            tmpl = utils.extend({}, tmpl);
+
+            tmpl.$data = $data || {};
+
+            _.each(tmpl, function iterate(value, key, list) {
+                if (key === '$data') {
+                    return;
+                }
+
+                if (isTemplate(key)) {
+                    delete list[key];
+
+                    key = render(key, tmpl);
+                    list[key] = value;
+                }
+
+                if (isTemplate(value)) {
+                    list[key] = render(value, tmpl);
+                } else if (_.isObject(value)) {
+                    _.each(value, iterate);
+                }
+            });
+
+            delete tmpl.$data;
+
+            return tmpl;
+        }
+    };
+});
diff --git a/lib/web/underscore.js b/lib/web/underscore.js
index d5b3375f28d445b12ae8bdc7bbcebb8031ed48a2..e272fca43f7b6c59357fcf20d791e2295e44921f 100644
--- a/lib/web/underscore.js
+++ b/lib/web/underscore.js
@@ -1,6 +1,6 @@
-//     Underscore.js 1.7.0
+//     Underscore.js 1.8.2
 //     http://underscorejs.org
-//     (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+//     (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
 //     Underscore may be freely distributed under the MIT license.
 
 (function() {
@@ -21,7 +21,6 @@
   var
     push             = ArrayProto.push,
     slice            = ArrayProto.slice,
-    concat           = ArrayProto.concat,
     toString         = ObjProto.toString,
     hasOwnProperty   = ObjProto.hasOwnProperty;
 
@@ -30,7 +29,11 @@
   var
     nativeIsArray      = Array.isArray,
     nativeKeys         = Object.keys,
-    nativeBind         = FuncProto.bind;
+    nativeBind         = FuncProto.bind,
+    nativeCreate       = Object.create;
+
+  // Naked function reference for surrogate-prototype-swapping.
+  var Ctor = function(){};
 
   // Create a safe reference to the Underscore object for use below.
   var _ = function(obj) {
@@ -52,12 +55,12 @@
   }
 
   // Current version.
-  _.VERSION = '1.7.0';
+  _.VERSION = '1.8.2';
 
   // Internal function that returns an efficient (for current engines) version
   // of the passed-in callback, to be repeatedly applied in other Underscore
   // functions.
-  var createCallback = function(func, context, argCount) {
+  var optimizeCb = function(func, context, argCount) {
     if (context === void 0) return func;
     switch (argCount == null ? 3 : argCount) {
       case 1: return function(value) {
@@ -81,12 +84,52 @@
   // A mostly-internal function to generate callbacks that can be applied
   // to each element in a collection, returning the desired result — either
   // identity, an arbitrary callback, a property matcher, or a property accessor.
-  _.iteratee = function(value, context, argCount) {
+  var cb = function(value, context, argCount) {
     if (value == null) return _.identity;
-    if (_.isFunction(value)) return createCallback(value, context, argCount);
-    if (_.isObject(value)) return _.matches(value);
+    if (_.isFunction(value)) return optimizeCb(value, context, argCount);
+    if (_.isObject(value)) return _.matcher(value);
     return _.property(value);
   };
+  _.iteratee = function(value, context) {
+    return cb(value, context, Infinity);
+  };
+
+  // An internal function for creating assigner functions.
+  var createAssigner = function(keysFunc, undefinedOnly) {
+    return function(obj) {
+      var length = arguments.length;
+      if (length < 2 || obj == null) return obj;
+      for (var index = 1; index < length; index++) {
+        var source = arguments[index],
+            keys = keysFunc(source),
+            l = keys.length;
+        for (var i = 0; i < l; i++) {
+          var key = keys[i];
+          if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key];
+        }
+      }
+      return obj;
+    };
+  };
+
+  // An internal function for creating a new object that inherits from another.
+  var baseCreate = function(prototype) {
+    if (!_.isObject(prototype)) return {};
+    if (nativeCreate) return nativeCreate(prototype);
+    Ctor.prototype = prototype;
+    var result = new Ctor;
+    Ctor.prototype = null;
+    return result;
+  };
+
+  // Helper for collection methods to determine whether a collection
+  // should be iterated as an array or as an object
+  // Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength
+  var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;
+  var isArrayLike = function(collection) {
+    var length = collection && collection.length;
+    return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX;
+  };
 
   // Collection Functions
   // --------------------
@@ -95,11 +138,10 @@
   // Handles raw objects in addition to array-likes. Treats all
   // sparse array-likes as if they were dense.
   _.each = _.forEach = function(obj, iteratee, context) {
-    if (obj == null) return obj;
-    iteratee = createCallback(iteratee, context);
-    var i, length = obj.length;
-    if (length === +length) {
-      for (i = 0; i < length; i++) {
+    iteratee = optimizeCb(iteratee, context);
+    var i, length;
+    if (isArrayLike(obj)) {
+      for (i = 0, length = obj.length; i < length; i++) {
         iteratee(obj[i], i, obj);
       }
     } else {
@@ -113,77 +155,66 @@
 
   // Return the results of applying the iteratee to each element.
   _.map = _.collect = function(obj, iteratee, context) {
-    if (obj == null) return [];
-    iteratee = _.iteratee(iteratee, context);
-    var keys = obj.length !== +obj.length && _.keys(obj),
+    iteratee = cb(iteratee, context);
+    var keys = !isArrayLike(obj) && _.keys(obj),
         length = (keys || obj).length,
-        results = Array(length),
-        currentKey;
+        results = Array(length);
     for (var index = 0; index < length; index++) {
-      currentKey = keys ? keys[index] : index;
+      var currentKey = keys ? keys[index] : index;
       results[index] = iteratee(obj[currentKey], currentKey, obj);
     }
     return results;
   };
 
-  var reduceError = 'Reduce of empty array with no initial value';
+  // Create a reducing function iterating left or right.
+  function createReduce(dir) {
+    // Optimized iterator function as using arguments.length
+    // in the main function will deoptimize the, see #1991.
+    function iterator(obj, iteratee, memo, keys, index, length) {
+      for (; index >= 0 && index < length; index += dir) {
+        var currentKey = keys ? keys[index] : index;
+        memo = iteratee(memo, obj[currentKey], currentKey, obj);
+      }
+      return memo;
+    }
+
+    return function(obj, iteratee, memo, context) {
+      iteratee = optimizeCb(iteratee, context, 4);
+      var keys = !isArrayLike(obj) && _.keys(obj),
+          length = (keys || obj).length,
+          index = dir > 0 ? 0 : length - 1;
+      // Determine the initial value if none is provided.
+      if (arguments.length < 3) {
+        memo = obj[keys ? keys[index] : index];
+        index += dir;
+      }
+      return iterator(obj, iteratee, memo, keys, index, length);
+    };
+  }
 
   // **Reduce** builds up a single result from a list of values, aka `inject`,
   // or `foldl`.
-  _.reduce = _.foldl = _.inject = function(obj, iteratee, memo, context) {
-    if (obj == null) obj = [];
-    iteratee = createCallback(iteratee, context, 4);
-    var keys = obj.length !== +obj.length && _.keys(obj),
-        length = (keys || obj).length,
-        index = 0, currentKey;
-    if (arguments.length < 3) {
-      if (!length) throw new TypeError(reduceError);
-      memo = obj[keys ? keys[index++] : index++];
-    }
-    for (; index < length; index++) {
-      currentKey = keys ? keys[index] : index;
-      memo = iteratee(memo, obj[currentKey], currentKey, obj);
-    }
-    return memo;
-  };
+  _.reduce = _.foldl = _.inject = createReduce(1);
 
   // The right-associative version of reduce, also known as `foldr`.
-  _.reduceRight = _.foldr = function(obj, iteratee, memo, context) {
-    if (obj == null) obj = [];
-    iteratee = createCallback(iteratee, context, 4);
-    var keys = obj.length !== + obj.length && _.keys(obj),
-        index = (keys || obj).length,
-        currentKey;
-    if (arguments.length < 3) {
-      if (!index) throw new TypeError(reduceError);
-      memo = obj[keys ? keys[--index] : --index];
-    }
-    while (index--) {
-      currentKey = keys ? keys[index] : index;
-      memo = iteratee(memo, obj[currentKey], currentKey, obj);
-    }
-    return memo;
-  };
+  _.reduceRight = _.foldr = createReduce(-1);
 
   // Return the first value which passes a truth test. Aliased as `detect`.
   _.find = _.detect = function(obj, predicate, context) {
-    var result;
-    predicate = _.iteratee(predicate, context);
-    _.some(obj, function(value, index, list) {
-      if (predicate(value, index, list)) {
-        result = value;
-        return true;
-      }
-    });
-    return result;
+    var key;
+    if (isArrayLike(obj)) {
+      key = _.findIndex(obj, predicate, context);
+    } else {
+      key = _.findKey(obj, predicate, context);
+    }
+    if (key !== void 0 && key !== -1) return obj[key];
   };
 
   // Return all the elements that pass a truth test.
   // Aliased as `select`.
   _.filter = _.select = function(obj, predicate, context) {
     var results = [];
-    if (obj == null) return results;
-    predicate = _.iteratee(predicate, context);
+    predicate = cb(predicate, context);
     _.each(obj, function(value, index, list) {
       if (predicate(value, index, list)) results.push(value);
     });
@@ -192,19 +223,17 @@
 
   // Return all the elements for which a truth test fails.
   _.reject = function(obj, predicate, context) {
-    return _.filter(obj, _.negate(_.iteratee(predicate)), context);
+    return _.filter(obj, _.negate(cb(predicate)), context);
   };
 
   // Determine whether all of the elements match a truth test.
   // Aliased as `all`.
   _.every = _.all = function(obj, predicate, context) {
-    if (obj == null) return true;
-    predicate = _.iteratee(predicate, context);
-    var keys = obj.length !== +obj.length && _.keys(obj),
-        length = (keys || obj).length,
-        index, currentKey;
-    for (index = 0; index < length; index++) {
-      currentKey = keys ? keys[index] : index;
+    predicate = cb(predicate, context);
+    var keys = !isArrayLike(obj) && _.keys(obj),
+        length = (keys || obj).length;
+    for (var index = 0; index < length; index++) {
+      var currentKey = keys ? keys[index] : index;
       if (!predicate(obj[currentKey], currentKey, obj)) return false;
     }
     return true;
@@ -213,24 +242,21 @@
   // Determine if at least one element in the object matches a truth test.
   // Aliased as `any`.
   _.some = _.any = function(obj, predicate, context) {
-    if (obj == null) return false;
-    predicate = _.iteratee(predicate, context);
-    var keys = obj.length !== +obj.length && _.keys(obj),
-        length = (keys || obj).length,
-        index, currentKey;
-    for (index = 0; index < length; index++) {
-      currentKey = keys ? keys[index] : index;
+    predicate = cb(predicate, context);
+    var keys = !isArrayLike(obj) && _.keys(obj),
+        length = (keys || obj).length;
+    for (var index = 0; index < length; index++) {
+      var currentKey = keys ? keys[index] : index;
       if (predicate(obj[currentKey], currentKey, obj)) return true;
     }
     return false;
   };
 
   // Determine if the array or object contains a given value (using `===`).
-  // Aliased as `include`.
-  _.contains = _.include = function(obj, target) {
-    if (obj == null) return false;
-    if (obj.length !== +obj.length) obj = _.values(obj);
-    return _.indexOf(obj, target) >= 0;
+  // Aliased as `includes` and `include`.
+  _.contains = _.includes = _.include = function(obj, target, fromIndex) {
+    if (!isArrayLike(obj)) obj = _.values(obj);
+    return _.indexOf(obj, target, typeof fromIndex == 'number' && fromIndex) >= 0;
   };
 
   // Invoke a method (with arguments) on every item in a collection.
@@ -238,7 +264,8 @@
     var args = slice.call(arguments, 2);
     var isFunc = _.isFunction(method);
     return _.map(obj, function(value) {
-      return (isFunc ? method : value[method]).apply(value, args);
+      var func = isFunc ? method : value[method];
+      return func == null ? func : func.apply(value, args);
     });
   };
 
@@ -250,13 +277,13 @@
   // Convenience version of a common use case of `filter`: selecting only objects
   // containing specific `key:value` pairs.
   _.where = function(obj, attrs) {
-    return _.filter(obj, _.matches(attrs));
+    return _.filter(obj, _.matcher(attrs));
   };
 
   // Convenience version of a common use case of `find`: getting the first object
   // containing specific `key:value` pairs.
   _.findWhere = function(obj, attrs) {
-    return _.find(obj, _.matches(attrs));
+    return _.find(obj, _.matcher(attrs));
   };
 
   // Return the maximum element (or element-based computation).
@@ -264,7 +291,7 @@
     var result = -Infinity, lastComputed = -Infinity,
         value, computed;
     if (iteratee == null && obj != null) {
-      obj = obj.length === +obj.length ? obj : _.values(obj);
+      obj = isArrayLike(obj) ? obj : _.values(obj);
       for (var i = 0, length = obj.length; i < length; i++) {
         value = obj[i];
         if (value > result) {
@@ -272,7 +299,7 @@
         }
       }
     } else {
-      iteratee = _.iteratee(iteratee, context);
+      iteratee = cb(iteratee, context);
       _.each(obj, function(value, index, list) {
         computed = iteratee(value, index, list);
         if (computed > lastComputed || computed === -Infinity && result === -Infinity) {
@@ -289,7 +316,7 @@
     var result = Infinity, lastComputed = Infinity,
         value, computed;
     if (iteratee == null && obj != null) {
-      obj = obj.length === +obj.length ? obj : _.values(obj);
+      obj = isArrayLike(obj) ? obj : _.values(obj);
       for (var i = 0, length = obj.length; i < length; i++) {
         value = obj[i];
         if (value < result) {
@@ -297,7 +324,7 @@
         }
       }
     } else {
-      iteratee = _.iteratee(iteratee, context);
+      iteratee = cb(iteratee, context);
       _.each(obj, function(value, index, list) {
         computed = iteratee(value, index, list);
         if (computed < lastComputed || computed === Infinity && result === Infinity) {
@@ -312,7 +339,7 @@
   // Shuffle a collection, using the modern version of the
   // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
   _.shuffle = function(obj) {
-    var set = obj && obj.length === +obj.length ? obj : _.values(obj);
+    var set = isArrayLike(obj) ? obj : _.values(obj);
     var length = set.length;
     var shuffled = Array(length);
     for (var index = 0, rand; index < length; index++) {
@@ -328,7 +355,7 @@
   // The internal `guard` argument allows it to work with `map`.
   _.sample = function(obj, n, guard) {
     if (n == null || guard) {
-      if (obj.length !== +obj.length) obj = _.values(obj);
+      if (!isArrayLike(obj)) obj = _.values(obj);
       return obj[_.random(obj.length - 1)];
     }
     return _.shuffle(obj).slice(0, Math.max(0, n));
@@ -336,7 +363,7 @@
 
   // Sort the object's values by a criterion produced by an iteratee.
   _.sortBy = function(obj, iteratee, context) {
-    iteratee = _.iteratee(iteratee, context);
+    iteratee = cb(iteratee, context);
     return _.pluck(_.map(obj, function(value, index, list) {
       return {
         value: value,
@@ -358,7 +385,7 @@
   var group = function(behavior) {
     return function(obj, iteratee, context) {
       var result = {};
-      iteratee = _.iteratee(iteratee, context);
+      iteratee = cb(iteratee, context);
       _.each(obj, function(value, index) {
         var key = iteratee(value, index, obj);
         behavior(result, value, key);
@@ -386,37 +413,24 @@
     if (_.has(result, key)) result[key]++; else result[key] = 1;
   });
 
-  // Use a comparator function to figure out the smallest index at which
-  // an object should be inserted so as to maintain order. Uses binary search.
-  _.sortedIndex = function(array, obj, iteratee, context) {
-    iteratee = _.iteratee(iteratee, context, 1);
-    var value = iteratee(obj);
-    var low = 0, high = array.length;
-    while (low < high) {
-      var mid = low + high >>> 1;
-      if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;
-    }
-    return low;
-  };
-
   // Safely create a real, live array from anything iterable.
   _.toArray = function(obj) {
     if (!obj) return [];
     if (_.isArray(obj)) return slice.call(obj);
-    if (obj.length === +obj.length) return _.map(obj, _.identity);
+    if (isArrayLike(obj)) return _.map(obj, _.identity);
     return _.values(obj);
   };
 
   // Return the number of elements in an object.
   _.size = function(obj) {
     if (obj == null) return 0;
-    return obj.length === +obj.length ? obj.length : _.keys(obj).length;
+    return isArrayLike(obj) ? obj.length : _.keys(obj).length;
   };
 
   // Split a collection into two arrays: one whose elements all satisfy the given
   // predicate, and one whose elements all do not satisfy the predicate.
   _.partition = function(obj, predicate, context) {
-    predicate = _.iteratee(predicate, context);
+    predicate = cb(predicate, context);
     var pass = [], fail = [];
     _.each(obj, function(value, key, obj) {
       (predicate(value, key, obj) ? pass : fail).push(value);
@@ -433,30 +447,27 @@
   _.first = _.head = _.take = function(array, n, guard) {
     if (array == null) return void 0;
     if (n == null || guard) return array[0];
-    if (n < 0) return [];
-    return slice.call(array, 0, n);
+    return _.initial(array, array.length - n);
   };
 
   // Returns everything but the last entry of the array. Especially useful on
   // the arguments object. Passing **n** will return all the values in
-  // the array, excluding the last N. The **guard** check allows it to work with
-  // `_.map`.
+  // the array, excluding the last N.
   _.initial = function(array, n, guard) {
     return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));
   };
 
   // Get the last element of an array. Passing **n** will return the last N
-  // values in the array. The **guard** check allows it to work with `_.map`.
+  // values in the array.
   _.last = function(array, n, guard) {
     if (array == null) return void 0;
     if (n == null || guard) return array[array.length - 1];
-    return slice.call(array, Math.max(array.length - n, 0));
+    return _.rest(array, Math.max(0, array.length - n));
   };
 
   // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
   // Especially useful on the arguments object. Passing an **n** will return
-  // the rest N values in the array. The **guard**
-  // check allows it to work with `_.map`.
+  // the rest N values in the array.
   _.rest = _.tail = _.drop = function(array, n, guard) {
     return slice.call(array, n == null || guard ? 1 : n);
   };
@@ -467,18 +478,20 @@
   };
 
   // Internal implementation of a recursive `flatten` function.
-  var flatten = function(input, shallow, strict, output) {
-    if (shallow && _.every(input, _.isArray)) {
-      return concat.apply(output, input);
-    }
-    for (var i = 0, length = input.length; i < length; i++) {
+  var flatten = function(input, shallow, strict, startIndex) {
+    var output = [], idx = 0;
+    for (var i = startIndex || 0, length = input && input.length; i < length; i++) {
       var value = input[i];
-      if (!_.isArray(value) && !_.isArguments(value)) {
-        if (!strict) output.push(value);
-      } else if (shallow) {
-        push.apply(output, value);
-      } else {
-        flatten(value, shallow, strict, output);
+      if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) {
+        //flatten current level of array or arguments object
+        if (!shallow) value = flatten(value, shallow, strict);
+        var j = 0, len = value.length;
+        output.length += len;
+        while (j < len) {
+          output[idx++] = value[j++];
+        }
+      } else if (!strict) {
+        output[idx++] = value;
       }
     }
     return output;
@@ -486,7 +499,7 @@
 
   // Flatten out an array, either recursively (by default), or just one level.
   _.flatten = function(array, shallow) {
-    return flatten(array, shallow, false, []);
+    return flatten(array, shallow, false);
   };
 
   // Return a version of the array that does not contain the specified value(s).
@@ -504,21 +517,21 @@
       iteratee = isSorted;
       isSorted = false;
     }
-    if (iteratee != null) iteratee = _.iteratee(iteratee, context);
+    if (iteratee != null) iteratee = cb(iteratee, context);
     var result = [];
     var seen = [];
     for (var i = 0, length = array.length; i < length; i++) {
-      var value = array[i];
+      var value = array[i],
+          computed = iteratee ? iteratee(value, i, array) : value;
       if (isSorted) {
-        if (!i || seen !== value) result.push(value);
-        seen = value;
+        if (!i || seen !== computed) result.push(value);
+        seen = computed;
       } else if (iteratee) {
-        var computed = iteratee(value, i, array);
-        if (_.indexOf(seen, computed) < 0) {
+        if (!_.contains(seen, computed)) {
           seen.push(computed);
           result.push(value);
         }
-      } else if (_.indexOf(result, value) < 0) {
+      } else if (!_.contains(result, value)) {
         result.push(value);
       }
     }
@@ -528,7 +541,7 @@
   // Produce an array that contains the union: each distinct element from all of
   // the passed-in arrays.
   _.union = function() {
-    return _.uniq(flatten(arguments, true, true, []));
+    return _.uniq(flatten(arguments, true, true));
   };
 
   // Produce an array that contains every item shared between all the
@@ -551,7 +564,7 @@
   // Take the difference between one array and a number of other arrays.
   // Only the elements present in just the first array will remain.
   _.difference = function(array) {
-    var rest = flatten(slice.call(arguments, 1), true, true, []);
+    var rest = flatten(arguments, true, true, 1);
     return _.filter(array, function(value){
       return !_.contains(rest, value);
     });
@@ -559,23 +572,28 @@
 
   // Zip together multiple lists into a single array -- elements that share
   // an index go together.
-  _.zip = function(array) {
-    if (array == null) return [];
-    var length = _.max(arguments, 'length').length;
-    var results = Array(length);
-    for (var i = 0; i < length; i++) {
-      results[i] = _.pluck(arguments, i);
+  _.zip = function() {
+    return _.unzip(arguments);
+  };
+
+  // Complement of _.zip. Unzip accepts an array of arrays and groups
+  // each array's elements on shared indices
+  _.unzip = function(array) {
+    var length = array && _.max(array, 'length').length || 0;
+    var result = Array(length);
+
+    for (var index = 0; index < length; index++) {
+      result[index] = _.pluck(array, index);
     }
-    return results;
+    return result;
   };
 
   // Converts lists into objects. Pass either a single array of `[key, value]`
   // pairs, or two parallel arrays of the same length -- one of keys, and one of
   // the corresponding values.
   _.object = function(list, values) {
-    if (list == null) return {};
     var result = {};
-    for (var i = 0, length = list.length; i < length; i++) {
+    for (var i = 0, length = list && list.length; i < length; i++) {
       if (values) {
         result[list[i]] = values[i];
       } else {
@@ -590,30 +608,63 @@
   // If the array is large and already in sort order, pass `true`
   // for **isSorted** to use binary search.
   _.indexOf = function(array, item, isSorted) {
-    if (array == null) return -1;
-    var i = 0, length = array.length;
-    if (isSorted) {
-      if (typeof isSorted == 'number') {
-        i = isSorted < 0 ? Math.max(0, length + isSorted) : isSorted;
-      } else {
-        i = _.sortedIndex(array, item);
-        return array[i] === item ? i : -1;
-      }
+    var i = 0, length = array && array.length;
+    if (typeof isSorted == 'number') {
+      i = isSorted < 0 ? Math.max(0, length + isSorted) : isSorted;
+    } else if (isSorted && length) {
+      i = _.sortedIndex(array, item);
+      return array[i] === item ? i : -1;
+    }
+    if (item !== item) {
+      return _.findIndex(slice.call(array, i), _.isNaN);
     }
     for (; i < length; i++) if (array[i] === item) return i;
     return -1;
   };
 
   _.lastIndexOf = function(array, item, from) {
-    if (array == null) return -1;
-    var idx = array.length;
+    var idx = array ? array.length : 0;
     if (typeof from == 'number') {
       idx = from < 0 ? idx + from + 1 : Math.min(idx, from + 1);
     }
+    if (item !== item) {
+      return _.findLastIndex(slice.call(array, 0, idx), _.isNaN);
+    }
     while (--idx >= 0) if (array[idx] === item) return idx;
     return -1;
   };
 
+  // Generator function to create the findIndex and findLastIndex functions
+  function createIndexFinder(dir) {
+    return function(array, predicate, context) {
+      predicate = cb(predicate, context);
+      var length = array != null && array.length;
+      var index = dir > 0 ? 0 : length - 1;
+      for (; index >= 0 && index < length; index += dir) {
+        if (predicate(array[index], index, array)) return index;
+      }
+      return -1;
+    };
+  }
+
+  // Returns the first index on an array-like that passes a predicate test
+  _.findIndex = createIndexFinder(1);
+
+  _.findLastIndex = createIndexFinder(-1);
+
+  // Use a comparator function to figure out the smallest index at which
+  // an object should be inserted so as to maintain order. Uses binary search.
+  _.sortedIndex = function(array, obj, iteratee, context) {
+    iteratee = cb(iteratee, context, 1);
+    var value = iteratee(obj);
+    var low = 0, high = array.length;
+    while (low < high) {
+      var mid = Math.floor((low + high) / 2);
+      if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;
+    }
+    return low;
+  };
+
   // Generate an integer Array containing an arithmetic progression. A port of
   // the native Python `range()` function. See
   // [the Python documentation](http://docs.python.org/library/functions.html#range).
@@ -637,25 +688,25 @@
   // Function (ahem) Functions
   // ------------------
 
-  // Reusable constructor function for prototype setting.
-  var Ctor = function(){};
+  // Determines whether to execute a function as a constructor
+  // or a normal function with the provided arguments
+  var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) {
+    if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);
+    var self = baseCreate(sourceFunc.prototype);
+    var result = sourceFunc.apply(self, args);
+    if (_.isObject(result)) return result;
+    return self;
+  };
 
   // Create a function bound to a given object (assigning `this`, and arguments,
   // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
   // available.
   _.bind = function(func, context) {
-    var args, bound;
     if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
     if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function');
-    args = slice.call(arguments, 2);
-    bound = function() {
-      if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
-      Ctor.prototype = func.prototype;
-      var self = new Ctor;
-      Ctor.prototype = null;
-      var result = func.apply(self, args.concat(slice.call(arguments)));
-      if (_.isObject(result)) return result;
-      return self;
+    var args = slice.call(arguments, 2);
+    var bound = function() {
+      return executeBound(func, bound, context, this, args.concat(slice.call(arguments)));
     };
     return bound;
   };
@@ -665,15 +716,16 @@
   // as a placeholder, allowing any combination of arguments to be pre-filled.
   _.partial = function(func) {
     var boundArgs = slice.call(arguments, 1);
-    return function() {
-      var position = 0;
-      var args = boundArgs.slice();
-      for (var i = 0, length = args.length; i < length; i++) {
-        if (args[i] === _) args[i] = arguments[position++];
+    var bound = function() {
+      var position = 0, length = boundArgs.length;
+      var args = Array(length);
+      for (var i = 0; i < length; i++) {
+        args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i];
       }
       while (position < arguments.length) args.push(arguments[position++]);
-      return func.apply(this, args);
+      return executeBound(func, bound, this, this, args);
     };
+    return bound;
   };
 
   // Bind a number of an object's methods to that object. Remaining arguments
@@ -693,7 +745,7 @@
   _.memoize = function(func, hasher) {
     var memoize = function(key) {
       var cache = memoize.cache;
-      var address = hasher ? hasher.apply(this, arguments) : key;
+      var address = '' + (hasher ? hasher.apply(this, arguments) : key);
       if (!_.has(cache, address)) cache[address] = func.apply(this, arguments);
       return cache[address];
     };
@@ -712,9 +764,7 @@
 
   // Defers a function, scheduling it to run after the current call stack has
   // cleared.
-  _.defer = function(func) {
-    return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
-  };
+  _.defer = _.partial(_.delay, _, 1);
 
   // Returns a function, that, when invoked, will only be triggered at most once
   // during a given window of time. Normally, the throttled function will run
@@ -739,8 +789,10 @@
       context = this;
       args = arguments;
       if (remaining <= 0 || remaining > wait) {
-        clearTimeout(timeout);
-        timeout = null;
+        if (timeout) {
+          clearTimeout(timeout);
+          timeout = null;
+        }
         previous = now;
         result = func.apply(context, args);
         if (!timeout) context = args = null;
@@ -761,7 +813,7 @@
     var later = function() {
       var last = _.now() - timestamp;
 
-      if (last < wait && last > 0) {
+      if (last < wait && last >= 0) {
         timeout = setTimeout(later, wait - last);
       } else {
         timeout = null;
@@ -814,7 +866,7 @@
     };
   };
 
-  // Returns a function that will only be executed after being called N times.
+  // Returns a function that will only be executed on and after the Nth call.
   _.after = function(times, func) {
     return function() {
       if (--times < 1) {
@@ -823,15 +875,14 @@
     };
   };
 
-  // Returns a function that will only be executed before being called N times.
+  // Returns a function that will only be executed up to (but not including) the Nth call.
   _.before = function(times, func) {
     var memo;
     return function() {
       if (--times > 0) {
         memo = func.apply(this, arguments);
-      } else {
-        func = null;
       }
+      if (times <= 1) func = null;
       return memo;
     };
   };
@@ -843,13 +894,47 @@
   // Object Functions
   // ----------------
 
-  // Retrieve the names of an object's properties.
+  // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.
+  var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString');
+  var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',
+                      'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];
+
+  function collectNonEnumProps(obj, keys) {
+    var nonEnumIdx = nonEnumerableProps.length;
+    var constructor = obj.constructor;
+    var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto;
+
+    // Constructor is a special case.
+    var prop = 'constructor';
+    if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop);
+
+    while (nonEnumIdx--) {
+      prop = nonEnumerableProps[nonEnumIdx];
+      if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) {
+        keys.push(prop);
+      }
+    }
+  }
+
+  // Retrieve the names of an object's own properties.
   // Delegates to **ECMAScript 5**'s native `Object.keys`
   _.keys = function(obj) {
     if (!_.isObject(obj)) return [];
     if (nativeKeys) return nativeKeys(obj);
     var keys = [];
     for (var key in obj) if (_.has(obj, key)) keys.push(key);
+    // Ahem, IE < 9.
+    if (hasEnumBug) collectNonEnumProps(obj, keys);
+    return keys;
+  };
+
+  // Retrieve all the property names of an object.
+  _.allKeys = function(obj) {
+    if (!_.isObject(obj)) return [];
+    var keys = [];
+    for (var key in obj) keys.push(key);
+    // Ahem, IE < 9.
+    if (hasEnumBug) collectNonEnumProps(obj, keys);
     return keys;
   };
 
@@ -864,6 +949,21 @@
     return values;
   };
 
+  // Returns the results of applying the iteratee to each element of the object
+  // In contrast to _.map it returns an object
+  _.mapObject = function(obj, iteratee, context) {
+    iteratee = cb(iteratee, context);
+    var keys =  _.keys(obj),
+          length = keys.length,
+          results = {},
+          currentKey;
+      for (var index = 0; index < length; index++) {
+        currentKey = keys[index];
+        results[currentKey] = iteratee(obj[currentKey], currentKey, obj);
+      }
+      return results;
+  };
+
   // Convert an object into a list of `[key, value]` pairs.
   _.pairs = function(obj) {
     var keys = _.keys(obj);
@@ -896,37 +996,38 @@
   };
 
   // Extend a given object with all the properties in passed-in object(s).
-  _.extend = function(obj) {
-    if (!_.isObject(obj)) return obj;
-    var source, prop;
-    for (var i = 1, length = arguments.length; i < length; i++) {
-      source = arguments[i];
-      for (prop in source) {
-        if (hasOwnProperty.call(source, prop)) {
-            obj[prop] = source[prop];
-        }
-      }
+  _.extend = createAssigner(_.allKeys);
+
+  // Assigns a given object with all the own properties in the passed-in object(s)
+  // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
+  _.extendOwn = _.assign = createAssigner(_.keys);
+
+  // Returns the first key on an object that passes a predicate test
+  _.findKey = function(obj, predicate, context) {
+    predicate = cb(predicate, context);
+    var keys = _.keys(obj), key;
+    for (var i = 0, length = keys.length; i < length; i++) {
+      key = keys[i];
+      if (predicate(obj[key], key, obj)) return key;
     }
-    return obj;
   };
 
   // Return a copy of the object only containing the whitelisted properties.
-  _.pick = function(obj, iteratee, context) {
-    var result = {}, key;
+  _.pick = function(object, oiteratee, context) {
+    var result = {}, obj = object, iteratee, keys;
     if (obj == null) return result;
-    if (_.isFunction(iteratee)) {
-      iteratee = createCallback(iteratee, context);
-      for (key in obj) {
-        var value = obj[key];
-        if (iteratee(value, key, obj)) result[key] = value;
-      }
+    if (_.isFunction(oiteratee)) {
+      keys = _.allKeys(obj);
+      iteratee = optimizeCb(oiteratee, context);
     } else {
-      var keys = concat.apply([], slice.call(arguments, 1));
-      obj = new Object(obj);
-      for (var i = 0, length = keys.length; i < length; i++) {
-        key = keys[i];
-        if (key in obj) result[key] = obj[key];
-      }
+      keys = flatten(arguments, false, false, 1);
+      iteratee = function(value, key, obj) { return key in obj; };
+      obj = Object(obj);
+    }
+    for (var i = 0, length = keys.length; i < length; i++) {
+      var key = keys[i];
+      var value = obj[key];
+      if (iteratee(value, key, obj)) result[key] = value;
     }
     return result;
   };
@@ -936,7 +1037,7 @@
     if (_.isFunction(iteratee)) {
       iteratee = _.negate(iteratee);
     } else {
-      var keys = _.map(concat.apply([], slice.call(arguments, 1)), String);
+      var keys = _.map(flatten(arguments, false, false, 1), String);
       iteratee = function(value, key) {
         return !_.contains(keys, key);
       };
@@ -945,16 +1046,7 @@
   };
 
   // Fill in a given object with default properties.
-  _.defaults = function(obj) {
-    if (!_.isObject(obj)) return obj;
-    for (var i = 1, length = arguments.length; i < length; i++) {
-      var source = arguments[i];
-      for (var prop in source) {
-        if (obj[prop] === void 0) obj[prop] = source[prop];
-      }
-    }
-    return obj;
-  };
+  _.defaults = createAssigner(_.allKeys, true);
 
   // Create a (shallow-cloned) duplicate of an object.
   _.clone = function(obj) {
@@ -970,6 +1062,19 @@
     return obj;
   };
 
+  // Returns whether an object has a given set of `key:value` pairs.
+  _.isMatch = function(object, attrs) {
+    var keys = _.keys(attrs), length = keys.length;
+    if (object == null) return !length;
+    var obj = Object(object);
+    for (var i = 0; i < length; i++) {
+      var key = keys[i];
+      if (attrs[key] !== obj[key] || !(key in obj)) return false;
+    }
+    return true;
+  };
+
+
   // Internal recursive comparison function for `isEqual`.
   var eq = function(a, b, aStack, bStack) {
     // Identical objects are equal. `0 === -0`, but they aren't identical.
@@ -1004,74 +1109,76 @@
         // of `NaN` are not equivalent.
         return +a === +b;
     }
-    if (typeof a != 'object' || typeof b != 'object') return false;
+
+    var areArrays = className === '[object Array]';
+    if (!areArrays) {
+      if (typeof a != 'object' || typeof b != 'object') return false;
+
+      // Objects with different constructors are not equivalent, but `Object`s or `Array`s
+      // from different frames are.
+      var aCtor = a.constructor, bCtor = b.constructor;
+      if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor &&
+                               _.isFunction(bCtor) && bCtor instanceof bCtor)
+                          && ('constructor' in a && 'constructor' in b)) {
+        return false;
+      }
+    }
     // Assume equality for cyclic structures. The algorithm for detecting cyclic
     // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
+    
+    // Initializing stack of traversed objects.
+    // It's done here since we only need them for objects and arrays comparison.
+    aStack = aStack || [];
+    bStack = bStack || [];
     var length = aStack.length;
     while (length--) {
       // Linear search. Performance is inversely proportional to the number of
       // unique nested structures.
       if (aStack[length] === a) return bStack[length] === b;
     }
-    // Objects with different constructors are not equivalent, but `Object`s
-    // from different frames are.
-    var aCtor = a.constructor, bCtor = b.constructor;
-    if (
-      aCtor !== bCtor &&
-      // Handle Object.create(x) cases
-      'constructor' in a && 'constructor' in b &&
-      !(_.isFunction(aCtor) && aCtor instanceof aCtor &&
-        _.isFunction(bCtor) && bCtor instanceof bCtor)
-    ) {
-      return false;
-    }
+
     // Add the first object to the stack of traversed objects.
     aStack.push(a);
     bStack.push(b);
-    var size, result;
+
     // Recursively compare objects and arrays.
-    if (className === '[object Array]') {
+    if (areArrays) {
       // Compare array lengths to determine if a deep comparison is necessary.
-      size = a.length;
-      result = size === b.length;
-      if (result) {
-        // Deep compare the contents, ignoring non-numeric properties.
-        while (size--) {
-          if (!(result = eq(a[size], b[size], aStack, bStack))) break;
-        }
+      length = a.length;
+      if (length !== b.length) return false;
+      // Deep compare the contents, ignoring non-numeric properties.
+      while (length--) {
+        if (!eq(a[length], b[length], aStack, bStack)) return false;
       }
     } else {
       // Deep compare objects.
       var keys = _.keys(a), key;
-      size = keys.length;
+      length = keys.length;
       // Ensure that both objects contain the same number of properties before comparing deep equality.
-      result = _.keys(b).length === size;
-      if (result) {
-        while (size--) {
-          // Deep compare each member
-          key = keys[size];
-          if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break;
-        }
+      if (_.keys(b).length !== length) return false;
+      while (length--) {
+        // Deep compare each member
+        key = keys[length];
+        if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false;
       }
     }
     // Remove the first object from the stack of traversed objects.
     aStack.pop();
     bStack.pop();
-    return result;
+    return true;
   };
 
   // Perform a deep comparison to check if two objects are equal.
   _.isEqual = function(a, b) {
-    return eq(a, b, [], []);
+    return eq(a, b);
   };
 
   // Is a given array, string, or object empty?
   // An "empty" object has no enumerable own-properties.
   _.isEmpty = function(obj) {
     if (obj == null) return true;
-    if (_.isArray(obj) || _.isString(obj) || _.isArguments(obj)) return obj.length === 0;
-    for (var key in obj) if (_.has(obj, key)) return false;
-    return true;
+    if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0;
+    return _.keys(obj).length === 0;
   };
 
   // Is a given value a DOM element?
@@ -1091,14 +1198,14 @@
     return type === 'function' || type === 'object' && !!obj;
   };
 
-  // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp.
-  _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) {
+  // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError.
+  _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) {
     _['is' + name] = function(obj) {
       return toString.call(obj) === '[object ' + name + ']';
     };
   });
 
-  // Define a fallback version of the method in browsers (ahem, IE), where
+  // Define a fallback version of the method in browsers (ahem, IE < 9), where
   // there isn't any inspectable "Arguments" type.
   if (!_.isArguments(arguments)) {
     _.isArguments = function(obj) {
@@ -1106,8 +1213,9 @@
     };
   }
 
-  // Optimize `isFunction` if appropriate. Work around an IE 11 bug.
-  if (typeof /./ !== 'function') {
+  // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8,
+  // IE 11 (#1621), and in Safari 8 (#1929).
+  if (typeof /./ != 'function' && typeof Int8Array != 'object') {
     _.isFunction = function(obj) {
       return typeof obj == 'function' || false;
     };
@@ -1170,28 +1278,30 @@
 
   _.property = function(key) {
     return function(obj) {
+      return obj == null ? void 0 : obj[key];
+    };
+  };
+
+  // Generates a function for a given object that returns a given property.
+  _.propertyOf = function(obj) {
+    return obj == null ? function(){} : function(key) {
       return obj[key];
     };
   };
 
-  // Returns a predicate for checking whether an object has a given set of `key:value` pairs.
-  _.matches = function(attrs) {
-    var pairs = _.pairs(attrs), length = pairs.length;
+  // Returns a predicate for checking whether an object has a given set of 
+  // `key:value` pairs.
+  _.matcher = _.matches = function(attrs) {
+    attrs = _.extendOwn({}, attrs);
     return function(obj) {
-      if (obj == null) return !length;
-      obj = new Object(obj);
-      for (var i = 0; i < length; i++) {
-        var pair = pairs[i], key = pair[0];
-        if (pair[1] !== obj[key] || !(key in obj)) return false;
-      }
-      return true;
+      return _.isMatch(obj, attrs);
     };
   };
 
   // Run a function **n** times.
   _.times = function(n, iteratee, context) {
     var accum = Array(Math.max(0, n));
-    iteratee = createCallback(iteratee, context, 1);
+    iteratee = optimizeCb(iteratee, context, 1);
     for (var i = 0; i < n; i++) accum[i] = iteratee(i);
     return accum;
   };
@@ -1240,10 +1350,12 @@
 
   // If the value of the named `property` is a function then invoke it with the
   // `object` as context; otherwise, return it.
-  _.result = function(object, property) {
-    if (object == null) return void 0;
-    var value = object[property];
-    return _.isFunction(value) ? object[property]() : value;
+  _.result = function(object, property, fallback) {
+    var value = object == null ? void 0 : object[property];
+    if (value === void 0) {
+      value = fallback;
+    }
+    return _.isFunction(value) ? value.call(object) : value;
   };
 
   // Generate a unique integer id (unique within the entire client session).
@@ -1358,8 +1470,8 @@
   // underscore functions. Wrapped objects may be chained.
 
   // Helper function to continue chaining intermediate results.
-  var result = function(obj) {
-    return this._chain ? _(obj).chain() : obj;
+  var result = function(instance, obj) {
+    return instance._chain ? _(obj).chain() : obj;
   };
 
   // Add your own custom functions to the Underscore object.
@@ -1369,7 +1481,7 @@
       _.prototype[name] = function() {
         var args = [this._wrapped];
         push.apply(args, arguments);
-        return result.call(this, func.apply(_, args));
+        return result(this, func.apply(_, args));
       };
     });
   };
@@ -1384,7 +1496,7 @@
       var obj = this._wrapped;
       method.apply(obj, arguments);
       if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0];
-      return result.call(this, obj);
+      return result(this, obj);
     };
   });
 
@@ -1392,7 +1504,7 @@
   _.each(['concat', 'join', 'slice'], function(name) {
     var method = ArrayProto[name];
     _.prototype[name] = function() {
-      return result.call(this, method.apply(this._wrapped, arguments));
+      return result(this, method.apply(this._wrapped, arguments));
     };
   });
 
@@ -1401,6 +1513,14 @@
     return this._wrapped;
   };
 
+  // Provide unwrapping proxy for some methods used in engine operations
+  // such as arithmetic and JSON stringification.
+  _.prototype.valueOf = _.prototype.toJSON = _.prototype.value;
+  
+  _.prototype.toString = function() {
+    return '' + this._wrapped;
+  };
+
   // AMD registration happens at the end for compatibility with AMD loaders
   // that may not enforce next-turn semantics on modules. Even though general
   // practice for AMD registration is to be anonymous, underscore registers
diff --git a/package.json b/package.json
index eaee4e18e2484b09731ec9a8e2a165eef83ae29c..69657eb7702c63f3d94d50a5d2f613ae6643f33e 100644
--- a/package.json
+++ b/package.json
@@ -21,7 +21,7 @@
     "grunt-contrib-watch": "^0.6.1",
     "grunt-exec": "^0.4.6",
     "grunt-styledocco": "^0.1.4",
-    "grunt-template-jasmine-requirejs": "^0.2.0",
+    "grunt-template-jasmine-requirejs": "^0.2.3",
     "grunt-text-replace": "^0.4.0",
     "imagemin-svgo": "^4.0.1",
     "load-grunt-config": "^0.16.0",
diff --git a/setup/performance-toolkit/README.txt b/setup/performance-toolkit/README.txt
index fda8a78c11c5827b18ccb364bd39f78b41ed58d3..f290b25553df3596233e5c767e0d1bb7f7fd2d1d 100644
--- a/setup/performance-toolkit/README.txt
+++ b/setup/performance-toolkit/README.txt
@@ -32,8 +32,8 @@ Scenario can accept parameters that are described bellow in format <parameter_na
 <customer_checkout_percent:4/> Percentage of users that will reach the (logged-in) customer checkout stage. Default is '4'.
 <loops:1/> Number of loops to run. Default is '1'.
 <admin_path:admin/> Admin backend path. Default is 'admin'.
-<admin_user:admin/> Admin backend user. Default is 'admin'.
-<admin_password:123123q/> Admin backend password. Default is '123123q'.
+<admin-user:admin/> Admin backend user. Default is 'admin'.
+<admin-password:123123q/> Admin backend password. Default is '123123q'.
 <think_time_deviation:1000> Deviation (ms) for "think time" emulation. Default is '1000'.
 <think_time_delay_offset:2000> Constant delay offset (ms) for "think time" emulation. Default is '2000'.
 
@@ -85,22 +85,3 @@ Details http://jmeter.apache.org/usermanual/component_reference.html#View_Result
 
 About other types read on
 http://jmeter.apache.org/usermanual/component_reference.html
-
-
-Testing environment
------------
-
-jMeter: apache-jmeter-2.11
-OS (where jMeter is running): Windows 7 SP1
-Server (where Magento is hosted): Intel(R) Core(TM)2 Duo CPU T7700  @2.40GHz, memtotal 4gb.
-PHP:  5.4.19 (memory_limit 2Gb)
-MySQL: 5.5.29 MySQL Community Server
-Magento version:  ver. 2.0.0.0-dev70 (rev 16b68a0f8e0fad4375f33b7238e2f2964ac3aadc)
-Magento database (Small plan in Fixture Generation Tool):
-jMeter parameters (all default parameters):
-  users: 100
-  ramp_period: 300
-  view_product_add_to_cart_percent: 62
-  view_catalog_percent: 30
-  guest_checkout_percent: 4
-  customer_checkout_percent: 4
diff --git a/setup/performance-toolkit/benchmark.jmx b/setup/performance-toolkit/benchmark.jmx
index 7d3d7aef7fa0ab39b7dce61fa73f45e9972e59bd..71ae48eb022bf32341f74c857d55ce8dc3de2785 100644
--- a/setup/performance-toolkit/benchmark.jmx
+++ b/setup/performance-toolkit/benchmark.jmx
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
 -->
-<jmeterTestPlan version="1.2" properties="2.6" jmeter="2.11 r1554548">
+<jmeterTestPlan version="1.2" properties="2.7" jmeter="2.12 r1636949">
   <hashTree>
     <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Toolkit" enabled="true">
       <stringProp name="TestPlan.comments"></stringProp>
@@ -83,14 +83,14 @@
             <stringProp name="Argument.value">${__P(admin_path,admin)}</stringProp>
             <stringProp name="Argument.metadata">=</stringProp>
           </elementProp>
-          <elementProp name="admin_user" elementType="Argument">
-            <stringProp name="Argument.name">admin_user</stringProp>
-            <stringProp name="Argument.value">${__P(admin_user,admin)}</stringProp>
+          <elementProp name="admin-user" elementType="Argument">
+            <stringProp name="Argument.name">admin-user</stringProp>
+            <stringProp name="Argument.value">${__P(admin-user,admin)}</stringProp>
             <stringProp name="Argument.metadata">=</stringProp>
           </elementProp>
-          <elementProp name="admin_password" elementType="Argument">
-            <stringProp name="Argument.name">admin_password</stringProp>
-            <stringProp name="Argument.value">${__P(admin_password,123123q)}</stringProp>
+          <elementProp name="admin-password" elementType="Argument">
+            <stringProp name="Argument.name">admin-password</stringProp>
+            <stringProp name="Argument.value">${__P(admin-password,123123q)}</stringProp>
             <stringProp name="Argument.metadata">=</stringProp>
           </elementProp>
           <elementProp name="website_id" elementType="Argument">
@@ -122,9 +122,10 @@
         <stringProp name="HTTPSampler.port"></stringProp>
         <stringProp name="HTTPSampler.connect_timeout"></stringProp>
         <stringProp name="HTTPSampler.response_timeout"></stringProp>
-        <stringProp name="HTTPSampler.protocol"></stringProp>
-        <stringProp name="HTTPSampler.contentEncoding"></stringProp>
+        <stringProp name="HTTPSampler.protocol">http</stringProp>
+        <stringProp name="HTTPSampler.contentEncoding">utf-8</stringProp>
         <stringProp name="HTTPSampler.path"></stringProp>
+        <stringProp name="HTTPSampler.implementation">HttpClient4</stringProp>
         <stringProp name="HTTPSampler.concurrentPool">4</stringProp>
       </ConfigTestElement>
       <hashTree/>
@@ -249,7 +250,6 @@ if (!slash.equals(path.substring(path.length() -1)) || !slash.equals(path.substr
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
           <stringProp name="TestPlan.comments">Site - Get Category 1</stringProp>
@@ -322,7 +322,6 @@ props.put(&quot;category_name&quot;, vars.get(&quot;category_name&quot;));</stri
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -340,7 +339,7 @@ props.put(&quot;category_name&quot;, vars.get(&quot;category_name&quot;));</stri
           <RegexExtractor guiclass="RegexExtractorGui" testclass="RegexExtractor" testname="Regular Expression Extractor: Extract product url keys" enabled="true">
             <stringProp name="RegexExtractor.useHeaders">false</stringProp>
             <stringProp name="RegexExtractor.refname">simple_products_url_keys</stringProp>
-            <stringProp name="RegexExtractor.regex">&lt;a class=&quot;product-item-link&quot; href=&quot;http://${host}${base_path}(index.php/)?([^&apos;&quot;]+)${url_suffix}&quot;&gt;Simple</stringProp>
+            <stringProp name="RegexExtractor.regex">&lt;a class=&quot;product-item-link&quot;\s*href=&quot;http://${host}${base_path}(index.php/)?([^&apos;&quot;]+)${url_suffix}&quot;&gt;</stringProp>
             <stringProp name="RegexExtractor.template">$2$</stringProp>
             <stringProp name="RegexExtractor.default"></stringProp>
             <stringProp name="RegexExtractor.match_number">-1</stringProp>
@@ -369,7 +368,6 @@ props.put(&quot;category_name&quot;, vars.get(&quot;category_name&quot;));</stri
             <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
             <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
             <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-            <stringProp name="HTTPSampler.implementation">Java</stringProp>
             <boolProp name="HTTPSampler.monitor">false</boolProp>
             <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
           </HTTPSamplerProxy>
@@ -477,7 +475,6 @@ productList.add(productMap);                        </stringProp>
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -495,7 +492,7 @@ productList.add(productMap);                        </stringProp>
           <RegexExtractor guiclass="RegexExtractorGui" testclass="RegexExtractor" testname="Regular Expression Extractor: Extract product url keys" enabled="true">
             <stringProp name="RegexExtractor.useHeaders">false</stringProp>
             <stringProp name="RegexExtractor.refname">configurable_products_url_keys</stringProp>
-            <stringProp name="RegexExtractor.regex">&lt;a class=&quot;product-item-link&quot; href=&quot;http://${host}${base_path}(index.php/)?([^&apos;&quot;]+)${url_suffix}&quot;&gt;Configurable</stringProp>
+            <stringProp name="RegexExtractor.regex">&lt;a class=&quot;product-item-link&quot;\s*href=&quot;http://${host}${base_path}(index.php/)?([^&apos;&quot;]+)${url_suffix}&quot;&gt;\s*Configurable</stringProp>
             <stringProp name="RegexExtractor.template">$2$</stringProp>
             <stringProp name="RegexExtractor.default"></stringProp>
             <stringProp name="RegexExtractor.match_number">-1</stringProp>
@@ -524,7 +521,6 @@ productList.add(productMap);                        </stringProp>
             <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
             <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
             <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-            <stringProp name="HTTPSampler.implementation">Java</stringProp>
             <boolProp name="HTTPSampler.monitor">false</boolProp>
             <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
           </HTTPSamplerProxy>
@@ -674,7 +670,6 @@ productList.add(productMap);                 </stringProp>
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -729,14 +724,14 @@ productList.add(productMap);                 </stringProp>
               </elementProp>
               <elementProp name="login[password]" elementType="HTTPArgument">
                 <boolProp name="HTTPArgument.always_encode">true</boolProp>
-                <stringProp name="Argument.value">${admin_password}</stringProp>
+                <stringProp name="Argument.value">${admin-password}</stringProp>
                 <stringProp name="Argument.metadata">=</stringProp>
                 <boolProp name="HTTPArgument.use_equals">true</boolProp>
                 <stringProp name="Argument.name">login[password]</stringProp>
               </elementProp>
               <elementProp name="login[username]" elementType="HTTPArgument">
                 <boolProp name="HTTPArgument.always_encode">true</boolProp>
-                <stringProp name="Argument.value">${admin_user}</stringProp>
+                <stringProp name="Argument.value">${admin-user}</stringProp>
                 <stringProp name="Argument.metadata">=</stringProp>
                 <boolProp name="HTTPArgument.use_equals">true</boolProp>
                 <stringProp name="Argument.name">login[username]</stringProp>
@@ -755,7 +750,6 @@ productList.add(productMap);                 </stringProp>
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -786,7 +780,6 @@ productList.add(productMap);                 </stringProp>
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -856,7 +849,6 @@ vars.put(&quot;searchData&quot;, new String(Base64Encoder.encode(searchData)));<
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -996,7 +988,6 @@ if (orders &gt; 0) {
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -1074,7 +1065,6 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -1110,7 +1100,6 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -1146,7 +1135,6 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -1183,7 +1171,6 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -1220,7 +1207,6 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -1314,7 +1300,6 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -1350,7 +1335,6 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -1386,7 +1370,6 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -1404,7 +1387,7 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
           <RegexExtractor guiclass="RegexExtractorGui" testclass="RegexExtractor" testname="Extract form action" enabled="true">
             <stringProp name="RegexExtractor.useHeaders">false</stringProp>
             <stringProp name="RegexExtractor.refname">simple_product_1_form_action</stringProp>
-            <stringProp name="RegexExtractor.regex">&lt;form action=&quot;([^&apos;&quot;]+)&quot; method=&quot;post&quot; id=&quot;product_addtocart_form&quot;&gt;</stringProp>
+            <stringProp name="RegexExtractor.regex">&lt;form action=&quot;([^&apos;&quot;]+)&quot;\s*method=&quot;post&quot;\s*id=&quot;product_addtocart_form&quot;&gt;</stringProp>
             <stringProp name="RegexExtractor.template">$1$</stringProp>
             <stringProp name="RegexExtractor.default"></stringProp>
             <stringProp name="RegexExtractor.match_number">1</stringProp>
@@ -1479,7 +1462,6 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -1524,7 +1506,6 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -1542,7 +1523,7 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
           <RegexExtractor guiclass="RegexExtractorGui" testclass="RegexExtractor" testname="Extract form action" enabled="true">
             <stringProp name="RegexExtractor.useHeaders">false</stringProp>
             <stringProp name="RegexExtractor.refname">simple_product_2_form_action</stringProp>
-            <stringProp name="RegexExtractor.regex">&lt;form action=&quot;([^&apos;&quot;]+)&quot; method=&quot;post&quot; id=&quot;product_addtocart_form&quot;&gt;</stringProp>
+            <stringProp name="RegexExtractor.regex">&lt;form action=&quot;([^&apos;&quot;]+)&quot;\s*method=&quot;post&quot;\s*id=&quot;product_addtocart_form&quot;&gt;</stringProp>
             <stringProp name="RegexExtractor.template">$1$</stringProp>
             <stringProp name="RegexExtractor.default"></stringProp>
             <stringProp name="RegexExtractor.match_number">1</stringProp>
@@ -1617,7 +1598,6 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -1662,7 +1642,6 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -1680,7 +1659,7 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
           <RegexExtractor guiclass="RegexExtractorGui" testclass="RegexExtractor" testname="Extract form action" enabled="true">
             <stringProp name="RegexExtractor.useHeaders">false</stringProp>
             <stringProp name="RegexExtractor.refname">configurable_product_form_action</stringProp>
-            <stringProp name="RegexExtractor.regex">&lt;form action=&quot;([^&apos;&quot;]+)&quot; method=&quot;post&quot; id=&quot;product_addtocart_form&quot;&gt;</stringProp>
+            <stringProp name="RegexExtractor.regex">&lt;form action=&quot;([^&apos;&quot;]+)&quot;\s*method=&quot;post&quot;\s*id=&quot;product_addtocart_form&quot;&gt;</stringProp>
             <stringProp name="RegexExtractor.template">$1$</stringProp>
             <stringProp name="RegexExtractor.default"></stringProp>
             <stringProp name="RegexExtractor.match_number">1</stringProp>
@@ -1762,7 +1741,6 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -1864,7 +1842,6 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -1900,7 +1877,6 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -1936,7 +1912,6 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -1954,7 +1929,7 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
           <RegexExtractor guiclass="RegexExtractorGui" testclass="RegexExtractor" testname="Extract form action" enabled="true">
             <stringProp name="RegexExtractor.useHeaders">false</stringProp>
             <stringProp name="RegexExtractor.refname">simple_product_1_form_action</stringProp>
-            <stringProp name="RegexExtractor.regex">&lt;form action=&quot;([^&apos;&quot;]+)&quot; method=&quot;post&quot; id=&quot;product_addtocart_form&quot;&gt;</stringProp>
+            <stringProp name="RegexExtractor.regex">&lt;form action=&quot;([^&apos;&quot;]+)&quot;\s*method=&quot;post&quot;\s*id=&quot;product_addtocart_form&quot;&gt;</stringProp>
             <stringProp name="RegexExtractor.template">$1$</stringProp>
             <stringProp name="RegexExtractor.default"></stringProp>
             <stringProp name="RegexExtractor.match_number">1</stringProp>
@@ -2029,7 +2004,6 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -2074,7 +2048,6 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -2092,7 +2065,7 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
           <RegexExtractor guiclass="RegexExtractorGui" testclass="RegexExtractor" testname="Extract form action" enabled="true">
             <stringProp name="RegexExtractor.useHeaders">false</stringProp>
             <stringProp name="RegexExtractor.refname">simple_product_2_form_action</stringProp>
-            <stringProp name="RegexExtractor.regex">&lt;form action=&quot;([^&apos;&quot;]+)&quot; method=&quot;post&quot; id=&quot;product_addtocart_form&quot;&gt;</stringProp>
+            <stringProp name="RegexExtractor.regex">&lt;form action=&quot;([^&apos;&quot;]+)&quot;\s*method=&quot;post&quot;\s*id=&quot;product_addtocart_form&quot;&gt;</stringProp>
             <stringProp name="RegexExtractor.template">$1$</stringProp>
             <stringProp name="RegexExtractor.default"></stringProp>
             <stringProp name="RegexExtractor.match_number">1</stringProp>
@@ -2167,7 +2140,6 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -2212,7 +2184,6 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -2230,7 +2201,7 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
           <RegexExtractor guiclass="RegexExtractorGui" testclass="RegexExtractor" testname="Extract form action" enabled="true">
             <stringProp name="RegexExtractor.useHeaders">false</stringProp>
             <stringProp name="RegexExtractor.refname">configurable_product_form_action</stringProp>
-            <stringProp name="RegexExtractor.regex">&lt;form action=&quot;([^&apos;&quot;]+)&quot; method=&quot;post&quot; id=&quot;product_addtocart_form&quot;&gt;</stringProp>
+            <stringProp name="RegexExtractor.regex">&lt;form action=&quot;([^&apos;&quot;]+)&quot;\s*method=&quot;post&quot;\s*id=&quot;product_addtocart_form&quot;&gt;</stringProp>
             <stringProp name="RegexExtractor.template">$1$</stringProp>
             <stringProp name="RegexExtractor.default"></stringProp>
             <stringProp name="RegexExtractor.match_number">1</stringProp>
@@ -2312,7 +2283,6 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -2357,7 +2327,6 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -2444,7 +2413,6 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -2630,7 +2598,6 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -2697,7 +2664,6 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -2771,7 +2737,6 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -2837,7 +2802,6 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -2873,7 +2837,6 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -2983,7 +2946,6 @@ if (emailsCount &lt; 1) {
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -3019,7 +2981,6 @@ if (emailsCount &lt; 1) {
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -3055,7 +3016,6 @@ if (emailsCount &lt; 1) {
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -3073,7 +3033,7 @@ if (emailsCount &lt; 1) {
           <RegexExtractor guiclass="RegexExtractorGui" testclass="RegexExtractor" testname="Extract form action" enabled="true">
             <stringProp name="RegexExtractor.useHeaders">false</stringProp>
             <stringProp name="RegexExtractor.refname">simple_product_1_form_action</stringProp>
-            <stringProp name="RegexExtractor.regex">&lt;form action=&quot;([^&apos;&quot;]+)&quot; method=&quot;post&quot; id=&quot;product_addtocart_form&quot;&gt;</stringProp>
+            <stringProp name="RegexExtractor.regex">&lt;form action=&quot;([^&apos;&quot;]+)&quot;\s*method=&quot;post&quot;\s*id=&quot;product_addtocart_form&quot;&gt;</stringProp>
             <stringProp name="RegexExtractor.template">$1$</stringProp>
             <stringProp name="RegexExtractor.default"></stringProp>
             <stringProp name="RegexExtractor.match_number">1</stringProp>
@@ -3148,7 +3108,6 @@ if (emailsCount &lt; 1) {
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -3193,7 +3152,6 @@ if (emailsCount &lt; 1) {
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -3211,7 +3169,7 @@ if (emailsCount &lt; 1) {
           <RegexExtractor guiclass="RegexExtractorGui" testclass="RegexExtractor" testname="Extract form action" enabled="true">
             <stringProp name="RegexExtractor.useHeaders">false</stringProp>
             <stringProp name="RegexExtractor.refname">simple_product_2_form_action</stringProp>
-            <stringProp name="RegexExtractor.regex">&lt;form action=&quot;([^&apos;&quot;]+)&quot; method=&quot;post&quot; id=&quot;product_addtocart_form&quot;&gt;</stringProp>
+            <stringProp name="RegexExtractor.regex">&lt;form action=&quot;([^&apos;&quot;]+)&quot;\s*method=&quot;post&quot;\s*id=&quot;product_addtocart_form&quot;&gt;</stringProp>
             <stringProp name="RegexExtractor.template">$1$</stringProp>
             <stringProp name="RegexExtractor.default"></stringProp>
             <stringProp name="RegexExtractor.match_number">1</stringProp>
@@ -3286,7 +3244,6 @@ if (emailsCount &lt; 1) {
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -3331,7 +3288,6 @@ if (emailsCount &lt; 1) {
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -3349,7 +3305,7 @@ if (emailsCount &lt; 1) {
           <RegexExtractor guiclass="RegexExtractorGui" testclass="RegexExtractor" testname="Extract form action" enabled="true">
             <stringProp name="RegexExtractor.useHeaders">false</stringProp>
             <stringProp name="RegexExtractor.refname">configurable_product_form_action</stringProp>
-            <stringProp name="RegexExtractor.regex">&lt;form action=&quot;([^&apos;&quot;]+)&quot; method=&quot;post&quot; id=&quot;product_addtocart_form&quot;&gt;</stringProp>
+            <stringProp name="RegexExtractor.regex">&lt;form action=&quot;([^&apos;&quot;]+)&quot;\s*method=&quot;post&quot;\s*id=&quot;product_addtocart_form&quot;&gt;</stringProp>
             <stringProp name="RegexExtractor.template">$1$</stringProp>
             <stringProp name="RegexExtractor.default"></stringProp>
             <stringProp name="RegexExtractor.match_number">1</stringProp>
@@ -3431,7 +3387,6 @@ if (emailsCount &lt; 1) {
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -3476,7 +3431,6 @@ if (emailsCount &lt; 1) {
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -3570,7 +3524,6 @@ if (emailsCount &lt; 1) {
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -3728,7 +3681,6 @@ if (emailsCount &lt; 1) {
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -3800,7 +3752,6 @@ if (emailsCount &lt; 1) {
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -3865,7 +3816,6 @@ if (emailsCount &lt; 1) {
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -3931,7 +3881,6 @@ if (emailsCount &lt; 1) {
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -3967,7 +3916,6 @@ if (emailsCount &lt; 1) {
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
           <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.implementation">Java</stringProp>
           <boolProp name="HTTPSampler.monitor">false</boolProp>
           <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
         </HTTPSamplerProxy>
@@ -4054,6 +4002,9 @@ props.remove(&quot;customer_emails_list&quot;);</stringProp>
             <saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>
             <assertionsResultsToSave>0</assertionsResultsToSave>
             <bytes>true</bytes>
+            <hostname>true</hostname>
+            <threadCounts>true</threadCounts>
+            <sampleCount>true</sampleCount>
           </value>
         </objProp>
         <stringProp name="filename">${report_save_path}/view-results-tree.log</stringProp>
@@ -4086,6 +4037,9 @@ props.remove(&quot;customer_emails_list&quot;);</stringProp>
             <saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>
             <assertionsResultsToSave>0</assertionsResultsToSave>
             <url>true</url>
+            <hostname>true</hostname>
+            <threadCounts>true</threadCounts>
+            <sampleCount>true</sampleCount>
           </value>
         </objProp>
         <stringProp name="filename">${report_save_path}/detailed-urls-report.log</stringProp>
@@ -4118,6 +4072,9 @@ props.remove(&quot;customer_emails_list&quot;);</stringProp>
             <saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>
             <assertionsResultsToSave>0</assertionsResultsToSave>
             <bytes>true</bytes>
+            <hostname>true</hostname>
+            <threadCounts>true</threadCounts>
+            <sampleCount>true</sampleCount>
           </value>
         </objProp>
         <stringProp name="filename">${report_save_path}/summary-report.log</stringProp>
diff --git a/setup/performance-toolkit/profiles/ce/extra_large.xml b/setup/performance-toolkit/profiles/ce/extra_large.xml
index 25575c3a77f66d0a75ec7ad2b4cb5d85938256b4..9d5767fbfba33f62963bed898213dc28ae30d95c 100644
--- a/setup/performance-toolkit/profiles/ce/extra_large.xml
+++ b/setup/performance-toolkit/profiles/ce/extra_large.xml
@@ -18,6 +18,8 @@
         <cart_price_rules>100</cart_price_rules> <!-- Number of shopping cart price rules -->
         <cart_price_rules_floor>5</cart_price_rules_floor> <!-- The price rule condition: minimum products amount in shopping cart for price rule to be applied -->
         <customers>5000</customers> <!-- Number of customers to generate -->
+        <tax_rates_file>tax_rates.csv</tax_rates_file> <!-- Tax rates file in fixtures directory-->
+        <orders>80000</orders> <!-- Orders count -->
         <configs> <!-- Config variables and values for change -->
             <config>
                 <path>admin/security/use_form_key</path>
@@ -32,5 +34,39 @@
                 <value>1</value>
             </config>
         </configs>
+        <indexers> <!-- Indexer mode value (true - Update by Schedule, false - Update on Save) -->
+            <indexer>
+                <id>catalog_category_product</id>
+                <set_scheduled>true</set_scheduled>
+            </indexer>
+            <indexer>
+                <id>catalog_product_category</id>
+                <set_scheduled>true</set_scheduled>
+            </indexer>
+            <indexer>
+                <id>catalog_product_price</id>
+                <set_scheduled>true</set_scheduled>
+            </indexer>
+            <indexer>
+                <id>catalog_product_attribute</id>
+                <set_scheduled>true</set_scheduled>
+            </indexer>
+            <indexer>
+                <id>cataloginventory_stock</id>
+                <set_scheduled>true</set_scheduled>
+            </indexer>
+            <indexer>
+                <id>catalogrule_rule</id>
+                <set_scheduled>true</set_scheduled>
+            </indexer>
+            <indexer>
+                <id>catalogrule_product</id>
+                <set_scheduled>true</set_scheduled>
+            </indexer>
+            <indexer>
+                <id>catalogsearch_fulltext</id>
+                <set_scheduled>true</set_scheduled>
+            </indexer>
+        </indexers>
     </profile>
 </config>
diff --git a/setup/performance-toolkit/profiles/ce/large.xml b/setup/performance-toolkit/profiles/ce/large.xml
index 093f2868fe3a738ef7647958f2c4360620e11162..bdbce2f2b8b7ca464606e3b5b351cc658f5ce624 100644
--- a/setup/performance-toolkit/profiles/ce/large.xml
+++ b/setup/performance-toolkit/profiles/ce/large.xml
@@ -18,6 +18,8 @@
         <cart_price_rules>50</cart_price_rules> <!-- Number of shopping cart price rules -->
         <cart_price_rules_floor>2</cart_price_rules_floor> <!-- The price rule condition: minimum products amount in shopping cart for price rule to be applied -->
         <customers>2000</customers> <!-- Number of customers to generate -->
+        <tax_rates_file>tax_rates.csv</tax_rates_file> <!-- Tax rates file in fixtures directory-->
+        <orders>40000</orders> <!-- Orders count -->
         <configs> <!-- Config variables and values for change -->
             <config>
                 <path>admin/security/use_form_key</path>
@@ -32,5 +34,39 @@
                 <value>1</value>
             </config>
         </configs>
+        <indexers> <!-- Indexer mode value (true - Update by Schedule, false - Update on Save) -->
+            <indexer>
+                <id>catalog_category_product</id>
+                <set_scheduled>true</set_scheduled>
+            </indexer>
+            <indexer>
+                <id>catalog_product_category</id>
+                <set_scheduled>true</set_scheduled>
+            </indexer>
+            <indexer>
+                <id>catalog_product_price</id>
+                <set_scheduled>true</set_scheduled>
+            </indexer>
+            <indexer>
+                <id>catalog_product_attribute</id>
+                <set_scheduled>true</set_scheduled>
+            </indexer>
+            <indexer>
+                <id>cataloginventory_stock</id>
+                <set_scheduled>true</set_scheduled>
+            </indexer>
+            <indexer>
+                <id>catalogrule_rule</id>
+                <set_scheduled>true</set_scheduled>
+            </indexer>
+            <indexer>
+                <id>catalogrule_product</id>
+                <set_scheduled>true</set_scheduled>
+            </indexer>
+            <indexer>
+                <id>catalogsearch_fulltext</id>
+                <set_scheduled>true</set_scheduled>
+            </indexer>
+        </indexers>
     </profile>
 </config>
diff --git a/setup/performance-toolkit/profiles/ce/medium.xml b/setup/performance-toolkit/profiles/ce/medium.xml
index edada57536f59043eb423dce5181a405676e49c4..8c91400d50bd697ab080985541bf35c760067642 100644
--- a/setup/performance-toolkit/profiles/ce/medium.xml
+++ b/setup/performance-toolkit/profiles/ce/medium.xml
@@ -18,6 +18,8 @@
         <cart_price_rules>20</cart_price_rules> <!-- Number of shopping cart price rules -->
         <cart_price_rules_floor>2</cart_price_rules_floor> <!-- The price rule condition: minimum products amount in shopping cart for price rule to be applied -->
         <customers>200</customers> <!-- Number of customers to generate -->
+        <tax_rates_file>tax_rates.csv</tax_rates_file> <!-- Tax rates file in fixtures directory-->
+        <orders>1600</orders> <!-- Orders count -->
         <configs> <!-- Config variables and values for change -->
             <config>
                 <path>admin/security/use_form_key</path>
@@ -32,5 +34,39 @@
                 <value>1</value>
             </config>
         </configs>
+        <indexers> <!-- Indexer mode value (true - Update by Schedule, false - Update on Save) -->
+            <indexer>
+                <id>catalog_category_product</id>
+                <set_scheduled>false</set_scheduled>
+            </indexer>
+            <indexer>
+                <id>catalog_product_category</id>
+                <set_scheduled>false</set_scheduled>
+            </indexer>
+            <indexer>
+                <id>catalog_product_price</id>
+                <set_scheduled>false</set_scheduled>
+            </indexer>
+            <indexer>
+                <id>catalog_product_attribute</id>
+                <set_scheduled>false</set_scheduled>
+            </indexer>
+            <indexer>
+                <id>cataloginventory_stock</id>
+                <set_scheduled>false</set_scheduled>
+            </indexer>
+            <indexer>
+                <id>catalogrule_rule</id>
+                <set_scheduled>false</set_scheduled>
+            </indexer>
+            <indexer>
+                <id>catalogrule_product</id>
+                <set_scheduled>false</set_scheduled>
+            </indexer>
+            <indexer>
+                <id>catalogsearch_fulltext</id>
+                <set_scheduled>false</set_scheduled>
+            </indexer>
+        </indexers>
     </profile>
 </config>
diff --git a/setup/performance-toolkit/profiles/ce/small.xml b/setup/performance-toolkit/profiles/ce/small.xml
index 578d2feec9e43cf4337db2b6066e4e7a3d6cd66d..79f2605bc775d7c3fdb0fe92106df966c6330c0c 100644
--- a/setup/performance-toolkit/profiles/ce/small.xml
+++ b/setup/performance-toolkit/profiles/ce/small.xml
@@ -18,6 +18,8 @@
         <cart_price_rules>10</cart_price_rules> <!-- Number of shopping cart price rules -->
         <cart_price_rules_floor>2</cart_price_rules_floor> <!-- The price rule condition: minimum products amount in shopping cart for price rule to be applied -->
         <customers>20</customers> <!-- Number of customers to generate -->
+        <tax_rates_file>tax_rates.csv</tax_rates_file> <!-- Tax rates file in fixtures directory-->
+        <orders>80</orders> <!-- Orders count -->
         <configs> <!-- Config variables and values for change -->
             <config>
                 <path>admin/security/use_form_key</path>
@@ -32,5 +34,39 @@
                 <value>1</value>
             </config>
         </configs>
+        <indexers> <!-- Indexer mode value (true - Update by Schedule, false - Update on Save) -->
+            <indexer>
+                <id>catalog_category_product</id>
+                <set_scheduled>false</set_scheduled>
+            </indexer>
+            <indexer>
+                <id>catalog_product_category</id>
+                <set_scheduled>false</set_scheduled>
+            </indexer>
+            <indexer>
+                <id>catalog_product_price</id>
+                <set_scheduled>false</set_scheduled>
+            </indexer>
+            <indexer>
+                <id>catalog_product_attribute</id>
+                <set_scheduled>false</set_scheduled>
+            </indexer>
+            <indexer>
+                <id>cataloginventory_stock</id>
+                <set_scheduled>false</set_scheduled>
+            </indexer>
+            <indexer>
+                <id>catalogrule_rule</id>
+                <set_scheduled>false</set_scheduled>
+            </indexer>
+            <indexer>
+                <id>catalogrule_product</id>
+                <set_scheduled>false</set_scheduled>
+            </indexer>
+            <indexer>
+                <id>catalogsearch_fulltext</id>
+                <set_scheduled>false</set_scheduled>
+            </indexer>
+        </indexers>
     </profile>
 </config>
diff --git a/setup/pub/styles/setup.css b/setup/pub/styles/setup.css
index ebe7d360aa51a5727093b1b86326a529a7fc3c07..d667b416c7a211c9990db9a8b32bf896fdadc6a6 100644
--- a/setup/pub/styles/setup.css
+++ b/setup/pub/styles/setup.css
@@ -3,4 +3,4 @@
  * See COPYING.txt for license details.
  */
 
-html{box-sizing:border-box;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}*,:after,:before{box-sizing:inherit}:focus{box-shadow:none;outline:0}._keyfocus :focus{box-shadow:0 0 0 1px #008bdb}body{margin:0}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}mark{background:#ff0;color:#000}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}embed,img,object,video{max-width:100%}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}:after,:before{box-sizing:content-box}.abs-clearer:after,.form-row:after,.header:after,.nav:after,.row:after{content:"";display:table;clear:both}.ng-cloak{display:none!important}.hide.hide{display:none}.show.show{display:block}.text-center{text-align:center}.text-right{text-align:right}@font-face{font-family:'Open Sans';src:url(../../pub/fonts/opensans/light/opensans-300.eot);src:url(../../pub/fonts/opensans/light/opensans-300.eot?#iefix) format('embedded-opentype'),url(../../pub/fonts/opensans/light/opensans-300.woff2) format('woff2'),url(../../pub/fonts/opensans/light/opensans-300.woff) format('woff'),url(../../pub/fonts/opensans/light/opensans-300.ttf) format('truetype'),url('../../pub/fonts/opensans/light/opensans-300.svg#Open Sans') format('svg');font-weight:300;font-style:normal}@font-face{font-family:'Open Sans';src:url(../../pub/fonts/opensans/regular/opensans-400.eot);src:url(../../pub/fonts/opensans/regular/opensans-400.eot?#iefix) format('embedded-opentype'),url(../../pub/fonts/opensans/regular/opensans-400.woff2) format('woff2'),url(../../pub/fonts/opensans/regular/opensans-400.woff) format('woff'),url(../../pub/fonts/opensans/regular/opensans-400.ttf) format('truetype'),url('../../pub/fonts/opensans/regular/opensans-400.svg#Open Sans') format('svg');font-weight:400;font-style:normal}@font-face{font-family:'Open Sans';src:url(../../pub/fonts/opensans/semibold/opensans-600.eot);src:url(../../pub/fonts/opensans/semibold/opensans-600.eot?#iefix) format('embedded-opentype'),url(../../pub/fonts/opensans/semibold/opensans-600.woff2) format('woff2'),url(../../pub/fonts/opensans/semibold/opensans-600.woff) format('woff'),url(../../pub/fonts/opensans/semibold/opensans-600.ttf) format('truetype'),url('../../pub/fonts/opensans/semibold/opensans-600.svg#Open Sans') format('svg');font-weight:600;font-style:normal}@font-face{font-family:'Open Sans';src:url(../../pub/fonts/opensans/bold/opensans-700.eot);src:url(../../pub/fonts/opensans/bold/opensans-700.eot?#iefix) format('embedded-opentype'),url(../../pub/fonts/opensans/bold/opensans-700.woff2) format('woff2'),url(../../pub/fonts/opensans/bold/opensans-700.woff) format('woff'),url(../../pub/fonts/opensans/bold/opensans-700.ttf) format('truetype'),url('../../pub/fonts/opensans/bold/opensans-700.svg#Open Sans') format('svg');font-weight:700;font-style:normal}html{font-size:62.5%}body{color:#303030;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:400;line-height:1.4}h1,h2,h3,h4,h5,h6{font-weight:400;margin-top:0}p{margin:0 0 1em}a{color:#008bdb;text-decoration:none}a:hover{color:#0fa7ff;text-decoration:underline}@font-face{font-family:Icons;src:url(../../pub/fonts/icons/icons.eot);src:url(../../pub/fonts/icons/icons.eot?#iefix) format('embedded-opentype'),url(../../pub/fonts/icons/icons.woff2) format('woff2'),url(../../pub/fonts/icons/icons.woff) format('woff'),url(../../pub/fonts/icons/icons.ttf) format('truetype'),url(../../pub/fonts/icons/icons.svg#Icons) format('svg');font-weight:400;font-style:normal}[class*=icon-]{display:inline-block;line-height:1}[class*=icon-]:after{font-family:Icons}.icon-success-thick:after{content:'\e600'}.icon-success:after{content:'\e601'}.icon-collapse:after{content:'\e602'}.icon-failed-thick:after{content:'\e603'}.icon-failed:after{content:'\e604'}.icon-expand:after{content:'\e605'}.icon-warning:after{content:'\e606'}.icon-failed-round,.icon-success-round{border-radius:100%;color:#fff;font-size:2.5rem;height:1em;position:relative;text-align:center;width:1em}.icon-failed-round:after,.icon-success-round:after{bottom:0;font-size:.8em;left:0;position:absolute;right:0;top:.15em}.icon-success-round{background-color:#79a22e}.icon-success-round:after{content:'\e600'}.icon-failed-round{background-color:#e22626}.icon-failed-round:after{content:'\e603'}dl,ol,ul{margin-top:0}.list{margin-bottom:1em;padding-left:0}.list>li{display:block;margin-bottom:.75em;position:relative}.list>li>.icon-failed,.list>li>.icon-success{font-size:1.6em;left:-.1em;position:absolute;top:0}.list>li>.icon-success{color:#79a22e}.list>li>.icon-failed{color:#e22626}.list-item-failed,.list-item-icon,.list-item-success{padding-left:3.5rem}.list-item-failed:before,.list-item-success:before{font-family:Icons;font-size:1.6em;left:-.1em;position:absolute;top:-.2em}.list-item-success:before{color:#79a22e;content:'\e601'}.list-item-failed:before{color:#e22626;content:'\e604'}.list-definition{margin:0 0 3rem;padding:0}.list-definition>dt{clear:left;float:left}.list-definition>dd{margin-bottom:1em;margin-left:20rem}.btn-wrap{margin:0 auto}.btn-wrap .btn{width:100%}.btn{background:#e3e3e3;border:none;color:#514943;display:inline-block;font-size:1.6rem;font-weight:600;padding:.45em .5em;text-align:center}.btn:hover{background-color:#dbdbdb;color:#514943;text-decoration:none}.btn:active{background-color:#d6d6d6}.btn.disabled,.btn[disabled]{cursor:default;opacity:.5;pointer-events:none}.ie9 .btn.disabled,.ie9 .btn[disabled]{background-color:#f0f0f0;opacity:1;text-shadow:none}.btn-large{padding:.75em 1.25em}.btn-link{background-color:transparent;border:none;color:#008bdb;font-family:1.6rem;font-size:1.5rem}.btn-link:hover{background-color:transparent;color:#0fa7ff}.btn-prime{background-color:#eb5202;color:#fff;text-shadow:1px 1px 0 rgba(0,0,0,.25)}.btn-prime:hover{background-color:#f65405;background-repeat:repeat-x;background-image:linear-gradient(to right,#e04f00 0,#f65405 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#e04f00', endColorstr='#f65405', GradientType=1);color:#fff}.btn-prime:active{background-color:#e04f00;background-repeat:repeat-x;background-image:linear-gradient(to right,#f65405 0,#e04f00 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f65405', endColorstr='#e04f00', GradientType=1)}.ie9 .btn-prime.disabled,.ie9 .btn-prime[disabled]{background-color:#fd6e23}.ie9 .btn-prime.disabled:active,.ie9 .btn-prime.disabled:hover,.ie9 .btn-prime[disabled]:active,.ie9 .btn-prime[disabled]:hover{background-color:#fd6e23;-webkit-filter:none;filter:none}.btn-secondary{background-color:#514943;color:#fff}.btn-secondary:hover{background-color:#5f564f;color:#fff}.btn-secondary:active{background-color:#574e48}.ie9 .btn-secondary.disabled,.ie9 .btn-secondary[disabled]{background-color:#514943}.ie9 .btn-secondary.disabled:active,.ie9 .btn-secondary.disabled:hover,.ie9 .btn-secondary[disabled]:active,.ie9 .btn-secondary[disabled]:hover{background-color:#514943;-webkit-filter:none;filter:none}[class*=btn-wrap-triangle]{overflow:hidden;position:relative}[class*=btn-wrap-triangle] .btn:after{border-style:solid;content:'';height:0;position:absolute;top:0;width:0}.btn-wrap-triangle-right{display:inline-block;padding-right:1.74rem;position:relative}.btn-wrap-triangle-right .btn{text-indent:.92rem}.btn-wrap-triangle-right .btn:after{border-color:transparent transparent transparent #e3e3e3;border-width:1.84rem 0 1.84rem 1.84rem;left:100%;margin-left:-1.74rem}.btn-wrap-triangle-right .btn:hover:after{border-left-color:#dbdbdb}.btn-wrap-triangle-right .btn:active:after{border-left-color:#d6d6d6}.btn-wrap-triangle-right .btn:not(.disabled):active,.btn-wrap-triangle-right .btn:not([disabled]):active{left:1px}.ie9 .btn-wrap-triangle-right .btn.disabled:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:after{border-color:transparent transparent transparent #f0f0f0}.ie9 .btn-wrap-triangle-right .btn.disabled:active:after,.ie9 .btn-wrap-triangle-right .btn.disabled:hover:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:active:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:hover:after{border-left-color:#f0f0f0}.btn-wrap-triangle-right .btn-prime:after{border-color:transparent transparent transparent #eb5202}.btn-wrap-triangle-right .btn-prime:hover:after{border-left-color:#f65405}.btn-wrap-triangle-right .btn-prime:active:after{border-left-color:#e04f00}.btn-wrap-triangle-right .btn-prime:not(.disabled):active,.btn-wrap-triangle-right .btn-prime:not([disabled]):active{left:1px}.ie9 .btn-wrap-triangle-right .btn-prime.disabled:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:after{border-color:transparent transparent transparent #fd6e23}.ie9 .btn-wrap-triangle-right .btn-prime.disabled:active:after,.ie9 .btn-wrap-triangle-right .btn-prime.disabled:hover:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:active:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:hover:after{border-left-color:#fd6e23}.btn-wrap-triangle-left{display:inline-block;padding-left:1.74rem}.btn-wrap-triangle-left .btn{text-indent:-.92rem}.btn-wrap-triangle-left .btn:after{border-color:transparent #e3e3e3 transparent transparent;border-width:1.84rem 1.84rem 1.84rem 0;margin-right:-1.74rem;right:100%}.btn-wrap-triangle-left .btn:hover:after{border-right-color:#dbdbdb}.btn-wrap-triangle-left .btn:active:after{border-right-color:#d6d6d6}.btn-wrap-triangle-left .btn:not(.disabled):active,.btn-wrap-triangle-left .btn:not([disabled]):active{right:1px}.ie9 .btn-wrap-triangle-left .btn.disabled:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:after{border-color:transparent #f0f0f0 transparent transparent}.ie9 .btn-wrap-triangle-left .btn.disabled:active:after,.ie9 .btn-wrap-triangle-left .btn.disabled:hover:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:active:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:hover:after{border-right-color:#f0f0f0}.btn-wrap-triangle-left .btn-prime:after{border-color:transparent #eb5202 transparent transparent}.btn-wrap-triangle-left .btn-prime:hover:after{border-right-color:#e04f00}.btn-wrap-triangle-left .btn-prime:active:after{border-right-color:#f65405}.btn-wrap-triangle-left .btn-prime:not(.disabled):active,.btn-wrap-triangle-left .btn-prime:not([disabled]):active{right:1px}.ie9 .btn-wrap-triangle-left .btn-prime.disabled:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:after{border-color:transparent #fd6e23 transparent transparent}.ie9 .btn-wrap-triangle-left .btn-prime.disabled:active:after,.ie9 .btn-wrap-triangle-left .btn-prime.disabled:hover:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:active:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:hover:after{border-right-color:#fd6e23}.btn-expand{background-color:transparent;border:none;color:#303030;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:700;padding:0;position:relative}.btn-expand.expanded:after{border-color:transparent transparent #303030;border-width:0 .285em .36em}.btn-expand.expanded:hover:after{border-color:transparent transparent #3d3d3d}.btn-expand:hover{background-color:transparent;border:none;color:#3d3d3d}.btn-expand:hover:after{border-color:#3d3d3d transparent transparent}.btn-expand:after{border-color:#303030 transparent transparent;border-style:solid;border-width:.36em .285em 0;content:'';height:0;left:100%;margin-left:.5em;margin-top:-.18em;position:absolute;top:50%;width:0}[class*=col-] .form-el-input,[class*=col-] .form-el-select{width:100%}.form-fieldset{border:none;margin:0 0 1em;padding:0}.form-row{margin-bottom:2.2rem}.form-row .form-row{margin-bottom:.4rem}.form-row .form-label{display:block;font-weight:600;padding:.6rem 2.1em 0 0;text-align:right}.form-row .form-label.required{position:relative}.form-row .form-label.required:after{color:#eb5202;content:'*';font-size:1.15em;position:absolute;right:.7em;top:.5em}.form-row .form-el-checkbox+.form-label:before,.form-row .form-el-radio+.form-label:before{top:.7rem}.form-row .form-el-checkbox+.form-label:after,.form-row .form-el-radio+.form-label:after{top:1.1rem}input:not([disabled]):focus,textarea:not([disabled]):focus{box-shadow:none}.form-el-input{border:1px solid #adadad;border-radius:2px;color:#303030;padding:.35em .55em .5em}.form-el-input:hover{border-color:#949494}.form-el-input:focus{border-color:#008bdb}.form-label{margin-bottom:.5em}[class*=form-label][for]{cursor:pointer}.form-el-insider-wrap{display:table;width:100%}.form-el-insider-input{display:table-cell;width:100%}.form-el-insider{border-radius:2px;display:table-cell;vertical-align:top;padding:.43em .55em .5em 0}.form-legend,.form-legend-expand,.form-legend-light{display:block;margin:0}.form-legend,.form-legend-expand{margin-bottom:2.5em;padding-top:1.5em;font-weight:600;font-size:1.25em}.form-legend{width:100%;border-top:1px solid #ccc}.form-legend-light{margin-bottom:1.5em;font-size:1em}.form-legend-expand{transition:opacity .2s linear;cursor:pointer}.form-legend-expand:hover{opacity:.85}.form-legend-expand.expanded:after{content:'\e602'}.form-legend-expand:after{margin-left:.5em;font-weight:400;font-size:1.15em;font-family:Icons;content:'\e605';vertical-align:sub}.form-el-checkbox,.form-el-radio{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.form-el-checkbox.disabled+.form-label,.form-el-checkbox.disabled+.form-label:before,.form-el-checkbox[disabled]+.form-label,.form-el-checkbox[disabled]+.form-label:before,.form-el-radio.disabled+.form-label,.form-el-radio.disabled+.form-label:before,.form-el-radio[disabled]+.form-label,.form-el-radio[disabled]+.form-label:before{cursor:default;opacity:.5;pointer-events:none}.form-el-checkbox:not(.disabled)+.form-label:hover:before,.form-el-checkbox:not([disabled])+.form-label:hover:before,.form-el-radio:not(.disabled)+.form-label:hover:before,.form-el-radio:not([disabled])+.form-label:hover:before{border-color:#514943}.form-el-checkbox+.form-label,.form-el-radio+.form-label{font-weight:400;padding-left:2em;padding-right:0;position:relative;text-align:left;transition:border-color .1s linear}.form-el-checkbox+.form-label:before,.form-el-radio+.form-label:before{border:1px solid;content:'';left:0;position:absolute;top:.1rem;transition:border-color .1s linear}.form-el-checkbox+.form-label:before{border-color:#adadad;border-radius:2px;height:1.4rem;line-height:1;width:1.4rem}.form-el-checkbox:checked+.form-label::before{content:'\e600';font-family:Icons}.form-el-radio+.form-label:before{background-color:#fff;border:1px solid #adadad;border-radius:100%;height:1.6rem;width:1.6rem}.form-el-radio+.form-label:after{background:0 0;border:.5rem solid transparent;border-radius:100%;content:'';height:0;left:.4rem;position:absolute;top:.5rem;transition:background .3s linear;width:0}.form-el-radio:checked+.form-label{cursor:default}.form-el-radio:checked+.form-label:after{border-color:#514943}.form-select-label{border:1px solid #adadad;border-radius:2px;color:#303030;cursor:pointer;display:block;overflow:hidden;position:relative}.form-select-label:hover,.form-select-label:hover:after{border-color:#949494}.form-select-label:active,.form-select-label:active:after,.form-select-label:focus,.form-select-label:focus:after{border-color:#008bdb}.form-select-label:after{background:#e3e3e3;border-left:1px solid #adadad;bottom:0;content:'';position:absolute;right:0;top:0;width:2.36em;z-index:-2}.ie9 .form-select-label:after{display:none}.form-select-label:before{border-color:#303030 transparent transparent;border-style:solid;border-width:5px 4px 0;content:'';height:0;margin-right:-4px;margin-top:-2.5px;position:absolute;right:1.18em;top:50%;width:0;z-index:-1}.ie9 .form-select-label:before{display:none}.form-select-label .form-el-select{background:0 0;border:none;border-radius:0;content:'';display:block;margin:0;padding:.35em calc(2.36em + 10%) .5em .55em;width:110%}.ie9 .form-select-label .form-el-select{padding-right:.55em;width:100%}.form-el-select{background:#fff;border:1px solid #adadad;border-radius:2px;color:#303030;display:block;padding:.35em .55em}.multiselect-custom{position:relative;height:45.2rem;border:1px solid #adadad;overflow:auto;margin:0 0 1.5rem}.multiselect-custom ul{margin:0;padding:0;list-style:none;min-width:29rem}.multiselect-custom .item{padding:1rem 1.4rem}.multiselect-custom .selected{background-color:#e0f6fe}.multiselect-custom .form-label{margin-bottom:0}[class*=form-el-].invalid{border-color:#e22626}[class*=form-el-].invalid+.error-container{display:block}.error-container{background-color:#fffbbb;border:1px solid #ee7d7d;border-radius:2px;color:#514943;display:none;font-size:1.19rem;margin-top:.2rem;padding:.4235em .6655em .605em}.check-result-message{margin-left:.5em;min-height:3.68rem;-webkit-align-items:center;-ms-align-items:center;-ms-flex-align:center;align-items:center;display:-webkit-flex;display:-ms-flexbox;display:flex}.check-result-text{margin-left:.5em}.pseudo-table{display:table}.pseudo-td{display:table-cell}.messages{margin:0 0 2rem}.message{background:#fffbbb;border:none;border-radius:0;color:#333;font-size:14px;margin:0 0 1px;padding:1.8rem 4rem 1.8rem 5.5rem;position:relative;text-shadow:none}.message:before{background:0 0;border:0;color:#007bdb;content:'\e61a';font-family:Icons;font-size:1.9rem;font-style:normal;font-weight:400;height:auto;left:1.9rem;line-height:inherit;margin-top:-1.3rem;position:absolute;speak:none;text-shadow:none;top:50%;width:auto}.message-notice:before{color:#007bdb;content:'\e61a'}.message-warning:before{color:#eb5202;content:'\e623'}.message-error{background:#fcc}.message-error:before{color:#e22626;content:'\e632';font-size:1.5rem;left:2.2rem;margin-top:-1rem}.message-success:before{color:#79a22e;content:'\e62d'}.message-spinner:before{display:none}.message-spinner .spinner{font-size:2.5rem;left:1.5rem;position:absolute;top:1.5rem}.message-in-rating-edit{margin-left:1.8rem;margin-right:1.8rem}.message{margin-bottom:3rem}.container{display:block;margin:0 auto 4rem;max-width:100rem;padding:0 2rem}.row{margin-left:0;margin-right:0}.col-l-1,.col-l-10,.col-l-11,.col-l-12,.col-l-2,.col-l-3,.col-l-4,.col-l-5,.col-l-6,.col-l-7,.col-l-8,.col-l-9,.col-m-1,.col-m-10,.col-m-11,.col-m-12,.col-m-2,.col-m-3,.col-m-4,.col-m-5,.col-m-6,.col-m-7,.col-m-8,.col-m-9,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{min-height:1px;padding-left:0;padding-right:0;position:relative}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}.nav{background-color:#f8f8f8;border-bottom:1px solid #e3e3e3;border-top:1px solid #e3e3e3;display:none;padding:2.2rem 1.5rem 0 0}.nav .btn-group,.nav-bar-outer-actions{float:right;margin-bottom:1.7rem}.nav .btn-group .btn-wrap,.nav-bar-outer-actions .btn-wrap{float:right;margin-left:.5rem;margin-right:.5rem}.nav-bar-outer-actions{margin-top:-10.6rem;padding-right:1.5rem}.btn-wrap-try-again{width:9.5rem}.btn-wrap-next,.btn-wrap-prev{width:8.5rem}.nav-bar{counter-reset:i;float:left;margin:0 1rem 1.7rem 0;padding:0;position:relative;white-space:nowrap}.nav-bar:before{background-color:#d4d4d4;background-repeat:repeat-x;background-image:linear-gradient(to bottom,#d1d1d1 0,#d4d4d4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#d1d1d1', endColorstr='#d4d4d4', GradientType=0);border-bottom:1px solid #d9d9d9;border-top:1px solid #bfbfbf;content:'';height:.8rem;left:5.15rem;position:absolute;right:5.15rem;top:.7rem}.nav-bar>li{display:inline-block;font-size:0;position:relative;vertical-align:top;width:10.3rem}.nav-bar>li:first-child:after{display:none}.nav-bar>li:after{background-color:#514943;content:'';height:.5rem;left:calc(-50% + .25rem);position:absolute;right:calc(50% + .7rem);top:.9rem}.nav-bar>li.disabled:before{bottom:0;content:'';left:0;position:absolute;right:0;top:0;z-index:1}.nav-bar>li.active~li:after{display:none}.nav-bar>li.active~li a:after{background-color:transparent;border-color:transparent;color:#a6a6a6}.nav-bar>li.active a{color:#000}.nav-bar>li.active a:hover{cursor:default}.nav-bar>li.active a:after{background-color:#fff;content:''}.nav-bar a{color:#514943;display:block;font-size:1.2rem;font-weight:600;line-height:1.2;overflow:hidden;padding:3rem .5em 0;position:relative;text-align:center;text-overflow:ellipsis}.nav-bar a:hover{text-decoration:none}.nav-bar a:after{background-color:#514943;border:.4rem solid #514943;border-radius:100%;color:#fff;content:counter(i);counter-increment:i;height:.7rem;left:50%;line-height:.6;margin-left:-.8rem;position:absolute;right:auto;text-align:center;top:.4rem;width:.7rem}.nav-bar a:before{background-color:#d6d6d6;border:1px solid transparent;border-bottom-color:#d9d9d9;border-radius:100%;border-top-color:#bfbfbf;content:'';height:2.1rem;left:50%;line-height:1;margin-left:-1.2rem;position:absolute;top:0;width:2.1rem}.tooltip{display:block;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.19rem;font-weight:400;line-height:1.4;opacity:0;position:absolute;visibility:visible;z-index:10}.tooltip.in{opacity:.9}.tooltip.top{margin-top:-4px;padding:8px 0}.tooltip.right{margin-left:4px;padding:0 8px}.tooltip.bottom{margin-top:4px;padding:8px 0}.tooltip.left{margin-left:-4px;padding:0 8px}.tooltip-inner{background-color:#fff;border:1px solid #adadad;border-radius:0;box-shadow:1px 1px 1px #ccc;color:#41362f;max-width:20rem;padding:.5em 1em;text-decoration:none}.tooltip-arrow,.tooltip-arrow:after{border:solid transparent;height:0;position:absolute;width:0}.tooltip-arrow:after{content:'';position:absolute}.tooltip.top .tooltip-arrow,.tooltip.top .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;left:50%;margin-left:-8px}.tooltip.top-left .tooltip-arrow,.tooltip.top-left .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;margin-bottom:-8px;right:8px}.tooltip.top-right .tooltip-arrow,.tooltip.top-right .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;left:8px;margin-bottom:-8px}.tooltip.right .tooltip-arrow,.tooltip.right .tooltip-arrow:after{border-right-color:#949494;border-width:8px 8px 8px 0;left:1px;margin-top:-8px;top:50%}.tooltip.right .tooltip-arrow:after{border-right-color:#fff;border-width:6px 7px 6px 0;margin-left:0;margin-top:-6px}.tooltip.left .tooltip-arrow,.tooltip.left .tooltip-arrow:after{border-left-color:#949494;border-width:8px 0 8px 8px;margin-top:-8px;right:0;top:50%}.tooltip.bottom .tooltip-arrow,.tooltip.bottom .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;left:50%;margin-left:-8px;top:0}.tooltip.bottom-left .tooltip-arrow,.tooltip.bottom-left .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;margin-top:-8px;right:8px;top:0}.tooltip.bottom-right .tooltip-arrow,.tooltip.bottom-right .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;left:8px;margin-top:-8px;top:0}.password-strength{display:block;margin:0 -.3rem 1em;white-space:nowrap}.password-strength.password-strength-too-short .password-strength-item:first-child,.password-strength.password-strength-weak .password-strength-item:first-child,.password-strength.password-strength-weak .password-strength-item:first-child+.password-strength-item{background-color:#e22626}.password-strength.password-strength-fair .password-strength-item:first-child,.password-strength.password-strength-fair .password-strength-item:first-child+.password-strength-item,.password-strength.password-strength-fair .password-strength-item:first-child+.password-strength-item+.password-strength-item{background-color:#ef672f}.password-strength.password-strength-good .password-strength-item:first-child,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item+.password-strength-item,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item+.password-strength-item+.password-strength-item,.password-strength.password-strength-strong .password-strength-item{background-color:#79a22e}.password-strength .password-strength-item{background-color:#ccc;display:inline-block;font-size:0;height:1.4rem;margin-right:.3rem;width:calc(20% - .6rem)}@-webkit-keyframes progress-bar-stripes{from{background-position:4rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:4rem 0}to{background-position:0 0}}.progress{background-color:#fafafa;border:1px solid #ccc;height:3rem;margin-bottom:3rem;overflow:hidden}.progress-bar{background-color:#79a22e;color:#fff;float:left;font-size:1.19rem;height:100%;line-height:3rem;text-align:center;transition:width .6s ease;width:0}.progress-bar.active{-webkit-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.spinner{display:inline-block;font-size:4rem;height:1em;margin-right:1.5rem;position:relative;width:1em}@-webkit-keyframes fade{0%{background-color:#514943}100%{background-color:#fff}}@-ms-keyframes fade{0%{background-color:#514943}100%{background-color:#fff}}@keyframes fade{0%{background-color:#514943}100%{background-color:#fff}}.spinner>span:nth-child(1){-webkit-animation-delay:.27s;-ms-animation-delay:.27s;animation-delay:.27s;-webkit-transform:rotate(-315deg);-ms-transform:rotate(-315deg);transform:rotate(-315deg)}.spinner>span:nth-child(2){-webkit-animation-delay:.36s;-ms-animation-delay:.36s;animation-delay:.36s;-webkit-transform:rotate(-270deg);-ms-transform:rotate(-270deg);transform:rotate(-270deg)}.spinner>span:nth-child(3){-webkit-animation-delay:.45s;-ms-animation-delay:.45s;animation-delay:.45s;-webkit-transform:rotate(-225deg);-ms-transform:rotate(-225deg);transform:rotate(-225deg)}.spinner>span:nth-child(4){-webkit-animation-delay:.54s;-ms-animation-delay:.54s;animation-delay:.54s;-webkit-transform:rotate(-180deg);-ms-transform:rotate(-180deg);transform:rotate(-180deg)}.spinner>span:nth-child(5){-webkit-animation-delay:.63s;-ms-animation-delay:.63s;animation-delay:.63s;-webkit-transform:rotate(-135deg);-ms-transform:rotate(-135deg);transform:rotate(-135deg)}.spinner>span:nth-child(6){-webkit-animation-delay:.72s;-ms-animation-delay:.72s;animation-delay:.72s;-webkit-transform:rotate(-90deg);-ms-transform:rotate(-90deg);transform:rotate(-90deg)}.spinner>span:nth-child(7){-webkit-animation-delay:.81s;-ms-animation-delay:.81s;animation-delay:.81s;-webkit-transform:rotate(-45deg);-ms-transform:rotate(-45deg);transform:rotate(-45deg)}.spinner>span:nth-child(8){-webkit-animation-delay:.9;-ms-animation-delay:.9;animation-delay:.9;-webkit-transform:rotate(0deg);-ms-transform:rotate(0deg);transform:rotate(0deg)}.spinner>span{-webkit-animation-direction:linear;-ms-animation-direction:linear;animation-direction:linear;-webkit-animation-duration:.72s;-ms-animation-duration:.72s;animation-duration:.72s;-webkit-animation-iteration-count:infinite;-ms-animation-iteration-count:infinite;animation-iteration-count:infinite;-webkit-animation-name:fade;-ms-animation-name:fade;animation-name:fade;-webkit-transform:scale(0.4);-ms-transform:scale(0.4);transform:scale(0.4);background-color:#fff;border-radius:6px;clip:rect(0 .28571429em .1em 0);height:.1em;margin-top:.5em;position:absolute;width:1em}.ie9 .spinner{background:url(../../pub/images/ajax-loader.gif) center no-repeat}.ie9 .spinner>span{display:none}.main{padding-bottom:2rem;padding-top:3rem}.header{display:none}.header .logo{float:left;height:4.1rem;width:3.5rem}.header-title{font-size:2.8rem;letter-spacing:.02em;margin:2.5rem 0 3.5rem 5rem}.page-title{font-size:2rem;margin-bottom:1.3em}.accent-box{margin-bottom:2rem}.accent-box .btn-prime{margin-top:1.5rem}.page-landing{margin:7.6% auto 0;max-width:44rem;text-align:center}.page-landing .logo{height:5.6rem;margin-bottom:2rem;width:19.2rem}.page-landing .text-version{margin-bottom:3rem}.page-landing .text-welcome{margin-bottom:6.5rem}.page-landing .text-terms{margin-bottom:2.5rem;text-align:center}.page-landing .btn-submit{margin-bottom:20px}.page-license .license-text{margin-bottom:2rem}.page-license .page-license-footer{text-align:right}.rediness-check-item{margin-bottom:4rem}.readiness-check-title{font-size:1.4rem;font-weight:700;margin-bottom:.1rem;margin-left:7.5rem}.readiness-check-content{margin-left:7.5rem;margin-right:22rem}.readiness-check-content .readiness-check-title{margin-left:0}.readiness-check-content .list{margin-top:-.3rem}.rediness-check-side{float:right;padding-left:2.4rem;width:22rem}.rediness-check-side .side-title{margin-bottom:0}.readiness-check-icon{float:left;margin-left:2rem;margin-top:.7rem}.page-web-configuration .form-el-insider-wrap{width:auto}.page-web-configuration .form-el-insider{width:15.4rem}.page-web-configuration .form-el-insider-input .form-el-input{width:16.5rem}.customize-your-store .customize-your-store-default .legend{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.customize-your-store .advanced-modules-count,.customize-your-store .advanced-modules-select{padding-left:1.5rem}.customize-your-store .customize-your-store-advanced{min-width:0}.customize-your-store .message-error:before{margin-top:0;top:1.8rem}.customize-your-store .message-error a{color:#333;text-decoration:underline}.customize-your-store .message-error .form-label:before{background:#fff}.content-install{margin-bottom:2rem}.console{border:1px solid #ccc;font-family:'Courier New',Courier,monospace;font-weight:300;margin:1rem 0 2rem;max-height:20rem;overflow-y:auto;padding:1.5rem 2rem 2rem}.console .text-danger{color:#e22626}.console .text-success{color:#090}.console .hidden{display:none}.content-success .btn-prime{margin-top:1.5rem}.jumbo-title{font-size:3.6rem}.jumbo-title .jumbo-icon{font-size:3.8rem;margin-right:.25em;position:relative;top:.15em}@media all and (max-width:1047px){.nav{padding-bottom:5.38rem;padding-left:1.5rem;text-align:center}.nav-bar{display:inline-block;float:none;margin-right:0;vertical-align:top}.nav .btn-group,.nav-bar-outer-actions{display:inline-block;float:none;margin-top:-8.48rem;text-align:center;vertical-align:top;width:100%}.nav-bar-outer-actions{padding-right:0}.nav-bar-outer-actions .outer-actions-inner-wrap{display:inline-block}}@media all and (min-width:768px){.col-m-1,.col-m-10,.col-m-11,.col-m-12,.col-m-2,.col-m-3,.col-m-4,.col-m-5,.col-m-6,.col-m-7,.col-m-8,.col-m-9{float:left}.col-m-12{width:100%}.col-m-11{width:91.66666667%}.col-m-10{width:83.33333333%}.col-m-9{width:75%}.col-m-8{width:66.66666667%}.col-m-7{width:58.33333333%}.col-m-6{width:50%}.col-m-5{width:41.66666667%}.col-m-4{width:33.33333333%}.col-m-3{width:25%}.col-m-2{width:16.66666667%}.col-m-1{width:8.33333333%}.col-m-pull-12{right:100%}.col-m-pull-11{right:91.66666667%}.col-m-pull-10{right:83.33333333%}.col-m-pull-9{right:75%}.col-m-pull-8{right:66.66666667%}.col-m-pull-7{right:58.33333333%}.col-m-pull-6{right:50%}.col-m-pull-5{right:41.66666667%}.col-m-pull-4{right:33.33333333%}.col-m-pull-3{right:25%}.col-m-pull-2{right:16.66666667%}.col-m-pull-1{right:8.33333333%}.col-m-pull-0{right:auto}.col-m-push-12{left:100%}.col-m-push-11{left:91.66666667%}.col-m-push-10{left:83.33333333%}.col-m-push-9{left:75%}.col-m-push-8{left:66.66666667%}.col-m-push-7{left:58.33333333%}.col-m-push-6{left:50%}.col-m-push-5{left:41.66666667%}.col-m-push-4{left:33.33333333%}.col-m-push-3{left:25%}.col-m-push-2{left:16.66666667%}.col-m-push-1{left:8.33333333%}.col-m-push-0{left:auto}.col-m-offset-12{margin-left:100%}.col-m-offset-11{margin-left:91.66666667%}.col-m-offset-10{margin-left:83.33333333%}.col-m-offset-9{margin-left:75%}.col-m-offset-8{margin-left:66.66666667%}.col-m-offset-7{margin-left:58.33333333%}.col-m-offset-6{margin-left:50%}.col-m-offset-5{margin-left:41.66666667%}.col-m-offset-4{margin-left:33.33333333%}.col-m-offset-3{margin-left:25%}.col-m-offset-2{margin-left:16.66666667%}.col-m-offset-1{margin-left:8.33333333%}.col-m-offset-0{margin-left:0}}@media all and (min-width:1048px){.col-l-1,.col-l-10,.col-l-11,.col-l-12,.col-l-2,.col-l-3,.col-l-4,.col-l-5,.col-l-6,.col-l-7,.col-l-8,.col-l-9{float:left}.col-l-12{width:100%}.col-l-11{width:91.66666667%}.col-l-10{width:83.33333333%}.col-l-9{width:75%}.col-l-8{width:66.66666667%}.col-l-7{width:58.33333333%}.col-l-6{width:50%}.col-l-5{width:41.66666667%}.col-l-4{width:33.33333333%}.col-l-3{width:25%}.col-l-2{width:16.66666667%}.col-l-1{width:8.33333333%}.col-l-pull-12{right:100%}.col-l-pull-11{right:91.66666667%}.col-l-pull-10{right:83.33333333%}.col-l-pull-9{right:75%}.col-l-pull-8{right:66.66666667%}.col-l-pull-7{right:58.33333333%}.col-l-pull-6{right:50%}.col-l-pull-5{right:41.66666667%}.col-l-pull-4{right:33.33333333%}.col-l-pull-3{right:25%}.col-l-pull-2{right:16.66666667%}.col-l-pull-1{right:8.33333333%}.col-l-pull-0{right:auto}.col-l-push-12{left:100%}.col-l-push-11{left:91.66666667%}.col-l-push-10{left:83.33333333%}.col-l-push-9{left:75%}.col-l-push-8{left:66.66666667%}.col-l-push-7{left:58.33333333%}.col-l-push-6{left:50%}.col-l-push-5{left:41.66666667%}.col-l-push-4{left:33.33333333%}.col-l-push-3{left:25%}.col-l-push-2{left:16.66666667%}.col-l-push-1{left:8.33333333%}.col-l-push-0{left:auto}.col-l-offset-12{margin-left:100%}.col-l-offset-11{margin-left:91.66666667%}.col-l-offset-10{margin-left:83.33333333%}.col-l-offset-9{margin-left:75%}.col-l-offset-8{margin-left:66.66666667%}.col-l-offset-7{margin-left:58.33333333%}.col-l-offset-6{margin-left:50%}.col-l-offset-5{margin-left:41.66666667%}.col-l-offset-4{margin-left:33.33333333%}.col-l-offset-3{margin-left:25%}.col-l-offset-2{margin-left:16.66666667%}.col-l-offset-1{margin-left:8.33333333%}.col-l-offset-0{margin-left:0}}@media all and (min-width:1440px){.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9{float:left}.col-xl-12{width:100%}.col-xl-11{width:91.66666667%}.col-xl-10{width:83.33333333%}.col-xl-9{width:75%}.col-xl-8{width:66.66666667%}.col-xl-7{width:58.33333333%}.col-xl-6{width:50%}.col-xl-5{width:41.66666667%}.col-xl-4{width:33.33333333%}.col-xl-3{width:25%}.col-xl-2{width:16.66666667%}.col-xl-1{width:8.33333333%}.col-xl-pull-12{right:100%}.col-xl-pull-11{right:91.66666667%}.col-xl-pull-10{right:83.33333333%}.col-xl-pull-9{right:75%}.col-xl-pull-8{right:66.66666667%}.col-xl-pull-7{right:58.33333333%}.col-xl-pull-6{right:50%}.col-xl-pull-5{right:41.66666667%}.col-xl-pull-4{right:33.33333333%}.col-xl-pull-3{right:25%}.col-xl-pull-2{right:16.66666667%}.col-xl-pull-1{right:8.33333333%}.col-xl-pull-0{right:auto}.col-xl-push-12{left:100%}.col-xl-push-11{left:91.66666667%}.col-xl-push-10{left:83.33333333%}.col-xl-push-9{left:75%}.col-xl-push-8{left:66.66666667%}.col-xl-push-7{left:58.33333333%}.col-xl-push-6{left:50%}.col-xl-push-5{left:41.66666667%}.col-xl-push-4{left:33.33333333%}.col-xl-push-3{left:25%}.col-xl-push-2{left:16.66666667%}.col-xl-push-1{left:8.33333333%}.col-xl-push-0{left:auto}.col-xl-offset-12{margin-left:100%}.col-xl-offset-11{margin-left:91.66666667%}.col-xl-offset-10{margin-left:83.33333333%}.col-xl-offset-9{margin-left:75%}.col-xl-offset-8{margin-left:66.66666667%}.col-xl-offset-7{margin-left:58.33333333%}.col-xl-offset-6{margin-left:50%}.col-xl-offset-5{margin-left:41.66666667%}.col-xl-offset-4{margin-left:33.33333333%}.col-xl-offset-3{margin-left:25%}.col-xl-offset-2{margin-left:16.66666667%}.col-xl-offset-1{margin-left:8.33333333%}.col-xl-offset-0{margin-left:0}}@media all and (max-width:767px){.list-definition>dt{float:none}.list-definition>dd{margin-left:0}.form-row .form-label{text-align:left}.form-row .form-label.required:after{position:static}.nav{padding-bottom:0;padding-left:0;padding-right:0}.nav-bar-outer-actions{margin-top:0}.nav-bar{display:block;margin-bottom:0;margin-left:auto;margin-right:auto;width:30.9rem}.nav-bar:before{display:none}.nav-bar>li{float:left;min-height:9rem}.nav-bar>li:after{display:none}.nav-bar>li:nth-child(4n){clear:both}.nav-bar a{line-height:1.4}.tooltip{display:none!important}.readiness-check-content{margin-right:2rem}.form-el-insider,.form-el-insider-wrap,.page-web-configuration .form-el-insider-input,.page-web-configuration .form-el-insider-input .form-el-input{display:block;width:100%}}@media all and (max-width:479px){.nav-bar{width:23.175rem}.nav-bar>li{width:7.725rem}.nav .btn-group .btn-wrap-try-again,.nav-bar-outer-actions .btn-wrap-try-again{clear:both;display:block;float:none;margin-left:auto;margin-right:auto;margin-top:1rem;padding-top:1rem}}
\ No newline at end of file
+html{box-sizing:border-box;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}*,:after,:before{box-sizing:inherit}:focus{box-shadow:none;outline:0}._keyfocus :focus{box-shadow:0 0 0 1px #008bdb}body{margin:0}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}mark{background:#ff0;color:#000}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}embed,img,object,video{max-width:100%}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}:after,:before{box-sizing:content-box}.abs-clearer:after,.form-row:after,.header:after,.nav:after,.row:after{content:"";display:table;clear:both}.ng-cloak{display:none!important}.hide.hide{display:none}.show.show{display:block}.text-center{text-align:center}.text-right{text-align:right}@font-face{font-family:'Open Sans';src:url(../../pub/fonts/opensans/light/opensans-300.eot);src:url(../../pub/fonts/opensans/light/opensans-300.eot?#iefix) format('embedded-opentype'),url(../../pub/fonts/opensans/light/opensans-300.woff2) format('woff2'),url(../../pub/fonts/opensans/light/opensans-300.woff) format('woff'),url(../../pub/fonts/opensans/light/opensans-300.ttf) format('truetype'),url('../../pub/fonts/opensans/light/opensans-300.svg#Open Sans') format('svg');font-weight:300;font-style:normal}@font-face{font-family:'Open Sans';src:url(../../pub/fonts/opensans/regular/opensans-400.eot);src:url(../../pub/fonts/opensans/regular/opensans-400.eot?#iefix) format('embedded-opentype'),url(../../pub/fonts/opensans/regular/opensans-400.woff2) format('woff2'),url(../../pub/fonts/opensans/regular/opensans-400.woff) format('woff'),url(../../pub/fonts/opensans/regular/opensans-400.ttf) format('truetype'),url('../../pub/fonts/opensans/regular/opensans-400.svg#Open Sans') format('svg');font-weight:400;font-style:normal}@font-face{font-family:'Open Sans';src:url(../../pub/fonts/opensans/semibold/opensans-600.eot);src:url(../../pub/fonts/opensans/semibold/opensans-600.eot?#iefix) format('embedded-opentype'),url(../../pub/fonts/opensans/semibold/opensans-600.woff2) format('woff2'),url(../../pub/fonts/opensans/semibold/opensans-600.woff) format('woff'),url(../../pub/fonts/opensans/semibold/opensans-600.ttf) format('truetype'),url('../../pub/fonts/opensans/semibold/opensans-600.svg#Open Sans') format('svg');font-weight:600;font-style:normal}@font-face{font-family:'Open Sans';src:url(../../pub/fonts/opensans/bold/opensans-700.eot);src:url(../../pub/fonts/opensans/bold/opensans-700.eot?#iefix) format('embedded-opentype'),url(../../pub/fonts/opensans/bold/opensans-700.woff2) format('woff2'),url(../../pub/fonts/opensans/bold/opensans-700.woff) format('woff'),url(../../pub/fonts/opensans/bold/opensans-700.ttf) format('truetype'),url('../../pub/fonts/opensans/bold/opensans-700.svg#Open Sans') format('svg');font-weight:700;font-style:normal}html{font-size:62.5%}body{color:#303030;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:400;line-height:1.4}h1,h2,h3,h4,h5,h6{font-weight:400;margin-top:0}p{margin:0 0 1em}a{color:#008bdb;text-decoration:none}a:hover{color:#0fa7ff;text-decoration:underline}@font-face{font-family:Icons;src:url(../../pub/fonts/icons/icons.eot);src:url(../../pub/fonts/icons/icons.eot?#iefix) format('embedded-opentype'),url(../../pub/fonts/icons/icons.woff2) format('woff2'),url(../../pub/fonts/icons/icons.woff) format('woff'),url(../../pub/fonts/icons/icons.ttf) format('truetype'),url(../../pub/fonts/icons/icons.svg#Icons) format('svg');font-weight:400;font-style:normal}[class*=icon-]{display:inline-block;line-height:1}[class*=icon-]:after{font-family:Icons}.icon-success-thick:after{content:'\e600'}.icon-success:after{content:'\e601'}.icon-collapse:after{content:'\e602'}.icon-failed-thick:after{content:'\e603'}.icon-failed:after{content:'\e604'}.icon-expand:after{content:'\e605'}.icon-warning:after{content:'\e606'}.icon-failed-round,.icon-success-round{border-radius:100%;color:#fff;font-size:2.5rem;height:1em;position:relative;text-align:center;width:1em}.icon-failed-round:after,.icon-success-round:after{bottom:0;font-size:.8em;left:0;position:absolute;right:0;top:.15em}.icon-success-round{background-color:#79a22e}.icon-success-round:after{content:'\e600'}.icon-failed-round{background-color:#e22626}.icon-failed-round:after{content:'\e603'}dl,ol,ul{margin-top:0}.list{margin-bottom:1em;padding-left:0}.list>li{display:block;margin-bottom:.75em;position:relative}.list>li>.icon-failed,.list>li>.icon-success{font-size:1.6em;left:-.1em;position:absolute;top:0}.list>li>.icon-success{color:#79a22e}.list>li>.icon-failed{color:#e22626}.list-item-failed,.list-item-icon,.list-item-success{padding-left:3.5rem}.list-item-failed:before,.list-item-success:before{font-family:Icons;font-size:1.6em;left:-.1em;position:absolute;top:-.2em}.list-item-success:before{color:#79a22e;content:'\e601'}.list-item-failed:before{color:#e22626;content:'\e604'}.list-definition{margin:0 0 3rem;padding:0}.list-definition>dt{clear:left;float:left}.list-definition>dd{margin-bottom:1em;margin-left:20rem}.btn-wrap{margin:0 auto}.btn-wrap .btn{width:100%}.btn{background:#e3e3e3;border:none;color:#514943;display:inline-block;font-size:1.6rem;font-weight:600;padding:.45em .5em;text-align:center}.btn:hover{background-color:#dbdbdb;color:#514943;text-decoration:none}.btn:active{background-color:#d6d6d6}.btn.disabled,.btn[disabled]{cursor:default;opacity:.5;pointer-events:none}.ie9 .btn.disabled,.ie9 .btn[disabled]{background-color:#f0f0f0;opacity:1;text-shadow:none}.btn-large{padding:.75em 1.25em}.btn-link{background-color:transparent;border:none;color:#008bdb;font-family:1.6rem;font-size:1.5rem}.btn-link:hover{background-color:transparent;color:#0fa7ff}.btn-prime{background-color:#eb5202;color:#fff;text-shadow:1px 1px 0 rgba(0,0,0,.25)}.btn-prime:hover{background-color:#f65405;background-repeat:repeat-x;background-image:linear-gradient(to right,#e04f00 0,#f65405 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#e04f00', endColorstr='#f65405', GradientType=1);color:#fff}.btn-prime:active{background-color:#e04f00;background-repeat:repeat-x;background-image:linear-gradient(to right,#f65405 0,#e04f00 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f65405', endColorstr='#e04f00', GradientType=1)}.ie9 .btn-prime.disabled,.ie9 .btn-prime[disabled]{background-color:#fd6e23}.ie9 .btn-prime.disabled:active,.ie9 .btn-prime.disabled:hover,.ie9 .btn-prime[disabled]:active,.ie9 .btn-prime[disabled]:hover{background-color:#fd6e23;-webkit-filter:none;filter:none}.btn-secondary{background-color:#514943;color:#fff}.btn-secondary:hover{background-color:#5f564f;color:#fff}.btn-secondary:active{background-color:#574e48}.ie9 .btn-secondary.disabled,.ie9 .btn-secondary[disabled]{background-color:#514943}.ie9 .btn-secondary.disabled:active,.ie9 .btn-secondary.disabled:hover,.ie9 .btn-secondary[disabled]:active,.ie9 .btn-secondary[disabled]:hover{background-color:#514943;-webkit-filter:none;filter:none}[class*=btn-wrap-triangle]{overflow:hidden;position:relative}[class*=btn-wrap-triangle] .btn:after{border-style:solid;content:'';height:0;position:absolute;top:0;width:0}.btn-wrap-triangle-right{display:inline-block;padding-right:1.74rem;position:relative}.btn-wrap-triangle-right .btn{text-indent:.92rem}.btn-wrap-triangle-right .btn:after{border-color:transparent transparent transparent #e3e3e3;border-width:1.84rem 0 1.84rem 1.84rem;left:100%;margin-left:-1.74rem}.btn-wrap-triangle-right .btn:hover:after{border-left-color:#dbdbdb}.btn-wrap-triangle-right .btn:active:after{border-left-color:#d6d6d6}.btn-wrap-triangle-right .btn:not(.disabled):active,.btn-wrap-triangle-right .btn:not([disabled]):active{left:1px}.ie9 .btn-wrap-triangle-right .btn.disabled:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:after{border-color:transparent transparent transparent #f0f0f0}.ie9 .btn-wrap-triangle-right .btn.disabled:active:after,.ie9 .btn-wrap-triangle-right .btn.disabled:hover:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:active:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:hover:after{border-left-color:#f0f0f0}.btn-wrap-triangle-right .btn-prime:after{border-color:transparent transparent transparent #eb5202}.btn-wrap-triangle-right .btn-prime:hover:after{border-left-color:#f65405}.btn-wrap-triangle-right .btn-prime:active:after{border-left-color:#e04f00}.btn-wrap-triangle-right .btn-prime:not(.disabled):active,.btn-wrap-triangle-right .btn-prime:not([disabled]):active{left:1px}.ie9 .btn-wrap-triangle-right .btn-prime.disabled:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:after{border-color:transparent transparent transparent #fd6e23}.ie9 .btn-wrap-triangle-right .btn-prime.disabled:active:after,.ie9 .btn-wrap-triangle-right .btn-prime.disabled:hover:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:active:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:hover:after{border-left-color:#fd6e23}.btn-wrap-triangle-left{display:inline-block;padding-left:1.74rem}.btn-wrap-triangle-left .btn{text-indent:-.92rem}.btn-wrap-triangle-left .btn:after{border-color:transparent #e3e3e3 transparent transparent;border-width:1.84rem 1.84rem 1.84rem 0;margin-right:-1.74rem;right:100%}.btn-wrap-triangle-left .btn:hover:after{border-right-color:#dbdbdb}.btn-wrap-triangle-left .btn:active:after{border-right-color:#d6d6d6}.btn-wrap-triangle-left .btn:not(.disabled):active,.btn-wrap-triangle-left .btn:not([disabled]):active{right:1px}.ie9 .btn-wrap-triangle-left .btn.disabled:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:after{border-color:transparent #f0f0f0 transparent transparent}.ie9 .btn-wrap-triangle-left .btn.disabled:active:after,.ie9 .btn-wrap-triangle-left .btn.disabled:hover:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:active:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:hover:after{border-right-color:#f0f0f0}.btn-wrap-triangle-left .btn-prime:after{border-color:transparent #eb5202 transparent transparent}.btn-wrap-triangle-left .btn-prime:hover:after{border-right-color:#e04f00}.btn-wrap-triangle-left .btn-prime:active:after{border-right-color:#f65405}.btn-wrap-triangle-left .btn-prime:not(.disabled):active,.btn-wrap-triangle-left .btn-prime:not([disabled]):active{right:1px}.ie9 .btn-wrap-triangle-left .btn-prime.disabled:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:after{border-color:transparent #fd6e23 transparent transparent}.ie9 .btn-wrap-triangle-left .btn-prime.disabled:active:after,.ie9 .btn-wrap-triangle-left .btn-prime.disabled:hover:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:active:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:hover:after{border-right-color:#fd6e23}.btn-expand{background-color:transparent;border:none;color:#303030;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:700;padding:0;position:relative}.btn-expand.expanded:after{border-color:transparent transparent #303030;border-width:0 .285em .36em}.btn-expand.expanded:hover:after{border-color:transparent transparent #3d3d3d}.btn-expand:hover{background-color:transparent;border:none;color:#3d3d3d}.btn-expand:hover:after{border-color:#3d3d3d transparent transparent}.btn-expand:after{border-color:#303030 transparent transparent;border-style:solid;border-width:.36em .285em 0;content:'';height:0;left:100%;margin-left:.5em;margin-top:-.18em;position:absolute;top:50%;width:0}[class*=col-] .form-el-input,[class*=col-] .form-el-select{width:100%}.form-fieldset{border:none;margin:0 0 1em;padding:0}.form-row{margin-bottom:2.2rem}.form-row .form-row{margin-bottom:.4rem}.form-row .form-label{display:block;font-weight:600;padding:.6rem 2.1em 0 0;text-align:right}.form-row .form-label.required{position:relative}.form-row .form-label.required:after{color:#eb5202;content:'*';font-size:1.15em;position:absolute;right:.7em;top:.5em}.form-row .form-el-checkbox+.form-label:before,.form-row .form-el-radio+.form-label:before{top:.7rem}.form-row .form-el-checkbox+.form-label:after,.form-row .form-el-radio+.form-label:after{top:1.1rem}input:not([disabled]):focus,textarea:not([disabled]):focus{box-shadow:none}.form-el-input{border:1px solid #adadad;border-radius:2px;color:#303030;padding:.35em .55em .5em}.form-el-input:hover{border-color:#949494}.form-el-input:focus{border-color:#008bdb}.form-label{margin-bottom:.5em}[class*=form-label][for]{cursor:pointer}.form-el-insider-wrap{display:table;width:100%}.form-el-insider-input{display:table-cell;width:100%}.form-el-insider{border-radius:2px;display:table-cell;vertical-align:top;padding:.43em .55em .5em 0}.form-legend,.form-legend-expand,.form-legend-light{display:block;margin:0}.form-legend,.form-legend-expand{margin-bottom:2.5em;padding-top:1.5em;font-weight:600;font-size:1.25em}.form-legend{width:100%;border-top:1px solid #ccc}.form-legend-light{margin-bottom:1.5em;font-size:1em}.form-legend-expand{transition:opacity .2s linear;cursor:pointer}.form-legend-expand:hover{opacity:.85}.form-legend-expand.expanded:after{content:'\e602'}.form-legend-expand:after{margin-left:.5em;font-weight:400;font-size:1.15em;font-family:Icons;content:'\e605';vertical-align:sub}.form-el-checkbox,.form-el-radio{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.form-el-checkbox.disabled+.form-label,.form-el-checkbox.disabled+.form-label:before,.form-el-checkbox[disabled]+.form-label,.form-el-checkbox[disabled]+.form-label:before,.form-el-radio.disabled+.form-label,.form-el-radio.disabled+.form-label:before,.form-el-radio[disabled]+.form-label,.form-el-radio[disabled]+.form-label:before{cursor:default;opacity:.5;pointer-events:none}.form-el-checkbox:not(.disabled)+.form-label:hover:before,.form-el-checkbox:not([disabled])+.form-label:hover:before,.form-el-radio:not(.disabled)+.form-label:hover:before,.form-el-radio:not([disabled])+.form-label:hover:before{border-color:#514943}.form-el-checkbox+.form-label,.form-el-radio+.form-label{font-weight:400;padding-left:2em;padding-right:0;position:relative;text-align:left;transition:border-color .1s linear}.form-el-checkbox+.form-label:before,.form-el-radio+.form-label:before{border:1px solid;content:'';left:0;position:absolute;top:.1rem;transition:border-color .1s linear}.form-el-checkbox+.form-label:before{border-color:#adadad;border-radius:2px;height:1.4rem;line-height:1;width:1.4rem}.form-el-checkbox:checked+.form-label::before{content:'\e600';font-family:Icons}.form-el-radio+.form-label:before{background-color:#fff;border:1px solid #adadad;border-radius:100%;height:1.6rem;width:1.6rem}.form-el-radio+.form-label:after{background:0 0;border:.5rem solid transparent;border-radius:100%;content:'';height:0;left:.4rem;position:absolute;top:.5rem;transition:background .3s linear;width:0}.form-el-radio:checked+.form-label{cursor:default}.form-el-radio:checked+.form-label:after{border-color:#514943}.form-select-label{border:1px solid #adadad;border-radius:2px;color:#303030;cursor:pointer;display:block;overflow:hidden;position:relative}.form-select-label:hover,.form-select-label:hover:after{border-color:#949494}.form-select-label:active,.form-select-label:active:after,.form-select-label:focus,.form-select-label:focus:after{border-color:#008bdb}.form-select-label:after{background:#e3e3e3;border-left:1px solid #adadad;bottom:0;content:'';position:absolute;right:0;top:0;width:2.36em;z-index:-2}.ie9 .form-select-label:after{display:none}.form-select-label:before{border-color:#303030 transparent transparent;border-style:solid;border-width:5px 4px 0;content:'';height:0;margin-right:-4px;margin-top:-2.5px;position:absolute;right:1.18em;top:50%;width:0;z-index:-1}.ie9 .form-select-label:before{display:none}.form-select-label .form-el-select{background:0 0;border:none;border-radius:0;content:'';display:block;margin:0;padding:.35em calc(2.36em + 10%) .5em .55em;width:110%}.ie9 .form-select-label .form-el-select{padding-right:.55em;width:100%}.form-el-select{background:#fff;border:1px solid #adadad;border-radius:2px;color:#303030;display:block;padding:.35em .55em}.multiselect-custom{position:relative;height:45.2rem;border:1px solid #adadad;overflow:auto;margin:0 0 1.5rem}.multiselect-custom ul{margin:0;padding:0;list-style:none;min-width:29rem}.multiselect-custom .item{padding:1rem 1.4rem}.multiselect-custom .selected{background-color:#e0f6fe}.multiselect-custom .form-label{margin-bottom:0}[class*=form-el-].invalid{border-color:#e22626}[class*=form-el-].invalid+.error-container{display:block}.error-container{background-color:#fffbbb;border:1px solid #ee7d7d;border-radius:2px;color:#514943;display:none;font-size:1.19rem;margin-top:.2rem;padding:.4235em .6655em .605em}.check-result-message{margin-left:.5em;min-height:3.68rem;-webkit-align-items:center;-ms-align-items:center;-ms-flex-align:center;align-items:center;display:-webkit-flex;display:-ms-flexbox;display:flex}.check-result-text{margin-left:.5em}.pseudo-table{display:table}.pseudo-td{display:table-cell}.messages{margin:0 0 2rem}.message{background:#fffbbb;border:none;border-radius:0;color:#333;font-size:14px;margin:0 0 1px;padding:1.8rem 4rem 1.8rem 5.5rem;position:relative;text-shadow:none}.message:before{background:0 0;border:0;color:#007bdb;content:'\e61a';font-family:Icons;font-size:1.9rem;font-style:normal;font-weight:400;height:auto;left:1.9rem;line-height:inherit;margin-top:-1.3rem;position:absolute;speak:none;text-shadow:none;top:50%;width:auto}.message-notice:before{color:#007bdb;content:'\e61a'}.message-warning:before{color:#eb5202;content:'\e623'}.message-error{background:#fcc}.message-error:before{color:#e22626;content:'\e632';font-size:1.5rem;left:2.2rem;margin-top:-1rem}.message-success:before{color:#79a22e;content:'\e62d'}.message-spinner:before{display:none}.message-spinner .spinner{font-size:2.5rem;left:1.5rem;position:absolute;top:1.5rem}.message-in-rating-edit{margin-left:1.8rem;margin-right:1.8rem}.message{margin-bottom:3rem}.container{display:block;margin:0 auto 4rem;max-width:100rem;padding:0 2rem}.row{margin-left:0;margin-right:0}.col-l-1,.col-l-10,.col-l-11,.col-l-12,.col-l-2,.col-l-3,.col-l-4,.col-l-5,.col-l-6,.col-l-7,.col-l-8,.col-l-9,.col-m-1,.col-m-10,.col-m-11,.col-m-12,.col-m-2,.col-m-3,.col-m-4,.col-m-5,.col-m-6,.col-m-7,.col-m-8,.col-m-9,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{min-height:1px;padding-left:0;padding-right:0;position:relative}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}.nav{background-color:#f8f8f8;border-bottom:1px solid #e3e3e3;border-top:1px solid #e3e3e3;display:none;padding:2.2rem 1.5rem 0 0}.nav .btn-group,.nav-bar-outer-actions{float:right;margin-bottom:1.7rem}.nav .btn-group .btn-wrap,.nav-bar-outer-actions .btn-wrap{float:right;margin-left:.5rem;margin-right:.5rem}.nav-bar-outer-actions{margin-top:-10.6rem;padding-right:1.5rem}.btn-wrap-try-again{width:9.5rem}.btn-wrap-next,.btn-wrap-prev{width:8.5rem}.nav-bar{counter-reset:i;float:left;margin:0 1rem 1.7rem 0;padding:0;position:relative;white-space:nowrap}.nav-bar:before{background-color:#d4d4d4;background-repeat:repeat-x;background-image:linear-gradient(to bottom,#d1d1d1 0,#d4d4d4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#d1d1d1', endColorstr='#d4d4d4', GradientType=0);border-bottom:1px solid #d9d9d9;border-top:1px solid #bfbfbf;content:'';height:.8rem;left:5.15rem;position:absolute;right:5.15rem;top:.7rem}.nav-bar>li{display:inline-block;font-size:0;position:relative;vertical-align:top;width:10.3rem}.nav-bar>li:first-child:after{display:none}.nav-bar>li:after{background-color:#514943;content:'';height:.5rem;left:calc(-50% + .25rem);position:absolute;right:calc(50% + .7rem);top:.9rem}.nav-bar>li.disabled:before{bottom:0;content:'';left:0;position:absolute;right:0;top:0;z-index:1}.nav-bar>li.active~li:after{display:none}.nav-bar>li.active~li a:after{background-color:transparent;border-color:transparent;color:#a6a6a6}.nav-bar>li.active a{color:#000}.nav-bar>li.active a:hover{cursor:default}.nav-bar>li.active a:after{background-color:#fff;content:''}.nav-bar a{color:#514943;display:block;font-size:1.2rem;font-weight:600;line-height:1.2;overflow:hidden;padding:3rem .5em 0;position:relative;text-align:center;text-overflow:ellipsis}.nav-bar a:hover{text-decoration:none}.nav-bar a:after{background-color:#514943;border:.4rem solid #514943;border-radius:100%;color:#fff;content:counter(i);counter-increment:i;height:.7rem;left:50%;line-height:.6;margin-left:-.8rem;position:absolute;right:auto;text-align:center;top:.4rem;width:.7rem}.nav-bar a:before{background-color:#d6d6d6;border:1px solid transparent;border-bottom-color:#d9d9d9;border-radius:100%;border-top-color:#bfbfbf;content:'';height:2.1rem;left:50%;line-height:1;margin-left:-1.2rem;position:absolute;top:0;width:2.1rem}.tooltip{display:block;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.19rem;font-weight:400;line-height:1.4;opacity:0;position:absolute;visibility:visible;z-index:10}.tooltip.in{opacity:.9}.tooltip.top{margin-top:-4px;padding:8px 0}.tooltip.right{margin-left:4px;padding:0 8px}.tooltip.bottom{margin-top:4px;padding:8px 0}.tooltip.left{margin-left:-4px;padding:0 8px}.tooltip-inner{background-color:#fff;border:1px solid #adadad;border-radius:0;box-shadow:1px 1px 1px #ccc;color:#41362f;max-width:20rem;padding:.5em 1em;text-decoration:none}.tooltip-arrow,.tooltip-arrow:after{border:solid transparent;height:0;position:absolute;width:0}.tooltip-arrow:after{content:'';position:absolute}.tooltip.top .tooltip-arrow,.tooltip.top .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;left:50%;margin-left:-8px}.tooltip.top-left .tooltip-arrow,.tooltip.top-left .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;margin-bottom:-8px;right:8px}.tooltip.top-right .tooltip-arrow,.tooltip.top-right .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;left:8px;margin-bottom:-8px}.tooltip.right .tooltip-arrow,.tooltip.right .tooltip-arrow:after{border-right-color:#949494;border-width:8px 8px 8px 0;left:1px;margin-top:-8px;top:50%}.tooltip.right .tooltip-arrow:after{border-right-color:#fff;border-width:6px 7px 6px 0;margin-left:0;margin-top:-6px}.tooltip.left .tooltip-arrow,.tooltip.left .tooltip-arrow:after{border-left-color:#949494;border-width:8px 0 8px 8px;margin-top:-8px;right:0;top:50%}.tooltip.bottom .tooltip-arrow,.tooltip.bottom .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;left:50%;margin-left:-8px;top:0}.tooltip.bottom-left .tooltip-arrow,.tooltip.bottom-left .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;margin-top:-8px;right:8px;top:0}.tooltip.bottom-right .tooltip-arrow,.tooltip.bottom-right .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;left:8px;margin-top:-8px;top:0}.password-strength{display:block;margin:0 -.3rem 1em;white-space:nowrap}.password-strength.password-strength-too-short .password-strength-item:first-child,.password-strength.password-strength-weak .password-strength-item:first-child,.password-strength.password-strength-weak .password-strength-item:first-child+.password-strength-item{background-color:#e22626}.password-strength.password-strength-fair .password-strength-item:first-child,.password-strength.password-strength-fair .password-strength-item:first-child+.password-strength-item,.password-strength.password-strength-fair .password-strength-item:first-child+.password-strength-item+.password-strength-item{background-color:#ef672f}.password-strength.password-strength-good .password-strength-item:first-child,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item+.password-strength-item,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item+.password-strength-item+.password-strength-item,.password-strength.password-strength-strong .password-strength-item{background-color:#79a22e}.password-strength .password-strength-item{background-color:#ccc;display:inline-block;font-size:0;height:1.4rem;margin-right:.3rem;width:calc(20% - .6rem)}@-webkit-keyframes progress-bar-stripes{from{background-position:4rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:4rem 0}to{background-position:0 0}}.progress{background-color:#fafafa;border:1px solid #ccc;height:3rem;margin-bottom:3rem;overflow:hidden}.progress-bar{background-color:#79a22e;color:#fff;float:left;font-size:1.19rem;height:100%;line-height:3rem;text-align:center;transition:width .6s ease;width:0}.progress-bar.active{-webkit-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.spinner{display:inline-block;font-size:4rem;height:1em;margin-right:1.5rem;position:relative;width:1em}@-webkit-keyframes fade{0%{background-color:#514943}100%{background-color:#fff}}@keyframes fade{0%{background-color:#514943}100%{background-color:#fff}}.spinner>span:nth-child(1){-webkit-animation-delay:.27s;animation-delay:.27s;-webkit-transform:rotate(-315deg);-ms-transform:rotate(-315deg);transform:rotate(-315deg)}.spinner>span:nth-child(2){-webkit-animation-delay:.36s;animation-delay:.36s;-webkit-transform:rotate(-270deg);-ms-transform:rotate(-270deg);transform:rotate(-270deg)}.spinner>span:nth-child(3){-webkit-animation-delay:.45s;animation-delay:.45s;-webkit-transform:rotate(-225deg);-ms-transform:rotate(-225deg);transform:rotate(-225deg)}.spinner>span:nth-child(4){-webkit-animation-delay:.54s;animation-delay:.54s;-webkit-transform:rotate(-180deg);-ms-transform:rotate(-180deg);transform:rotate(-180deg)}.spinner>span:nth-child(5){-webkit-animation-delay:.63s;animation-delay:.63s;-webkit-transform:rotate(-135deg);-ms-transform:rotate(-135deg);transform:rotate(-135deg)}.spinner>span:nth-child(6){-webkit-animation-delay:.72s;animation-delay:.72s;-webkit-transform:rotate(-90deg);-ms-transform:rotate(-90deg);transform:rotate(-90deg)}.spinner>span:nth-child(7){-webkit-animation-delay:.81s;animation-delay:.81s;-webkit-transform:rotate(-45deg);-ms-transform:rotate(-45deg);transform:rotate(-45deg)}.spinner>span:nth-child(8){-webkit-animation-delay:.9;animation-delay:.9;-webkit-transform:rotate(0deg);-ms-transform:rotate(0deg);transform:rotate(0deg)}.spinner>span{-webkit-animation-direction:linear;animation-direction:linear;-webkit-animation-duration:.72s;animation-duration:.72s;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;-webkit-animation-name:fade;animation-name:fade;-webkit-transform:scale(0.4);-ms-transform:scale(0.4);transform:scale(0.4);background-color:#fff;border-radius:6px;clip:rect(0 .28571429em .1em 0);height:.1em;margin-top:.5em;position:absolute;width:1em}.ie9 .spinner{background:url(../../pub/images/ajax-loader.gif) center no-repeat}.ie9 .spinner>span{display:none}.main{padding-bottom:2rem;padding-top:3rem}.header{display:none}.header .logo{float:left;height:4.1rem;width:3.5rem}.header-title{font-size:2.8rem;letter-spacing:.02em;margin:2.5rem 0 3.5rem 5rem}.page-title{font-size:2rem;margin-bottom:1.3em}.accent-box{margin-bottom:2rem}.accent-box .btn-prime{margin-top:1.5rem}.page-landing{margin:7.6% auto 0;max-width:44rem;text-align:center}.page-landing .logo{height:5.6rem;margin-bottom:2rem;width:19.2rem}.page-landing .text-version{margin-bottom:3rem}.page-landing .text-welcome{margin-bottom:6.5rem}.page-landing .text-terms{margin-bottom:2.5rem;text-align:center}.page-landing .btn-submit{margin-bottom:20px}.page-license .license-text{margin-bottom:2rem}.page-license .page-license-footer{text-align:right}.rediness-check-item{margin-bottom:4rem}.readiness-check-title{font-size:1.4rem;font-weight:700;margin-bottom:.1rem;margin-left:7.5rem}.readiness-check-content{margin-left:7.5rem;margin-right:22rem}.readiness-check-content .readiness-check-title{margin-left:0}.readiness-check-content .list{margin-top:-.3rem}.rediness-check-side{float:right;padding-left:2.4rem;width:22rem}.rediness-check-side .side-title{margin-bottom:0}.readiness-check-icon{float:left;margin-left:2rem;margin-top:.7rem}.page-web-configuration .form-el-insider-wrap{width:auto}.page-web-configuration .form-el-insider{width:15.4rem}.page-web-configuration .form-el-insider-input .form-el-input{width:16.5rem}.customize-your-store .customize-your-store-default .legend{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.customize-your-store .advanced-modules-count,.customize-your-store .advanced-modules-select{padding-left:1.5rem}.customize-your-store .customize-your-store-advanced{min-width:0}.customize-your-store .message-error:before{margin-top:0;top:1.8rem}.customize-your-store .message-error a{color:#333;text-decoration:underline}.customize-your-store .message-error .form-label:before{background:#fff}.content-install{margin-bottom:2rem}.console{border:1px solid #ccc;font-family:'Courier New',Courier,monospace;font-weight:300;margin:1rem 0 2rem;max-height:20rem;overflow-y:auto;padding:1.5rem 2rem 2rem}.console .text-danger{color:#e22626}.console .text-success{color:#090}.console .hidden{display:none}.content-success .btn-prime{margin-top:1.5rem}.jumbo-title{font-size:3.6rem}.jumbo-title .jumbo-icon{font-size:3.8rem;margin-right:.25em;position:relative;top:.15em}@media all and (max-width:1047px){.nav{padding-bottom:5.38rem;padding-left:1.5rem;text-align:center}.nav-bar{display:inline-block;float:none;margin-right:0;vertical-align:top}.nav .btn-group,.nav-bar-outer-actions{display:inline-block;float:none;margin-top:-8.48rem;text-align:center;vertical-align:top;width:100%}.nav-bar-outer-actions{padding-right:0}.nav-bar-outer-actions .outer-actions-inner-wrap{display:inline-block}}@media all and (min-width:768px){.col-m-1,.col-m-10,.col-m-11,.col-m-12,.col-m-2,.col-m-3,.col-m-4,.col-m-5,.col-m-6,.col-m-7,.col-m-8,.col-m-9{float:left}.col-m-12{width:100%}.col-m-11{width:91.66666667%}.col-m-10{width:83.33333333%}.col-m-9{width:75%}.col-m-8{width:66.66666667%}.col-m-7{width:58.33333333%}.col-m-6{width:50%}.col-m-5{width:41.66666667%}.col-m-4{width:33.33333333%}.col-m-3{width:25%}.col-m-2{width:16.66666667%}.col-m-1{width:8.33333333%}.col-m-pull-12{right:100%}.col-m-pull-11{right:91.66666667%}.col-m-pull-10{right:83.33333333%}.col-m-pull-9{right:75%}.col-m-pull-8{right:66.66666667%}.col-m-pull-7{right:58.33333333%}.col-m-pull-6{right:50%}.col-m-pull-5{right:41.66666667%}.col-m-pull-4{right:33.33333333%}.col-m-pull-3{right:25%}.col-m-pull-2{right:16.66666667%}.col-m-pull-1{right:8.33333333%}.col-m-pull-0{right:auto}.col-m-push-12{left:100%}.col-m-push-11{left:91.66666667%}.col-m-push-10{left:83.33333333%}.col-m-push-9{left:75%}.col-m-push-8{left:66.66666667%}.col-m-push-7{left:58.33333333%}.col-m-push-6{left:50%}.col-m-push-5{left:41.66666667%}.col-m-push-4{left:33.33333333%}.col-m-push-3{left:25%}.col-m-push-2{left:16.66666667%}.col-m-push-1{left:8.33333333%}.col-m-push-0{left:auto}.col-m-offset-12{margin-left:100%}.col-m-offset-11{margin-left:91.66666667%}.col-m-offset-10{margin-left:83.33333333%}.col-m-offset-9{margin-left:75%}.col-m-offset-8{margin-left:66.66666667%}.col-m-offset-7{margin-left:58.33333333%}.col-m-offset-6{margin-left:50%}.col-m-offset-5{margin-left:41.66666667%}.col-m-offset-4{margin-left:33.33333333%}.col-m-offset-3{margin-left:25%}.col-m-offset-2{margin-left:16.66666667%}.col-m-offset-1{margin-left:8.33333333%}.col-m-offset-0{margin-left:0}}@media all and (min-width:1048px){.col-l-1,.col-l-10,.col-l-11,.col-l-12,.col-l-2,.col-l-3,.col-l-4,.col-l-5,.col-l-6,.col-l-7,.col-l-8,.col-l-9{float:left}.col-l-12{width:100%}.col-l-11{width:91.66666667%}.col-l-10{width:83.33333333%}.col-l-9{width:75%}.col-l-8{width:66.66666667%}.col-l-7{width:58.33333333%}.col-l-6{width:50%}.col-l-5{width:41.66666667%}.col-l-4{width:33.33333333%}.col-l-3{width:25%}.col-l-2{width:16.66666667%}.col-l-1{width:8.33333333%}.col-l-pull-12{right:100%}.col-l-pull-11{right:91.66666667%}.col-l-pull-10{right:83.33333333%}.col-l-pull-9{right:75%}.col-l-pull-8{right:66.66666667%}.col-l-pull-7{right:58.33333333%}.col-l-pull-6{right:50%}.col-l-pull-5{right:41.66666667%}.col-l-pull-4{right:33.33333333%}.col-l-pull-3{right:25%}.col-l-pull-2{right:16.66666667%}.col-l-pull-1{right:8.33333333%}.col-l-pull-0{right:auto}.col-l-push-12{left:100%}.col-l-push-11{left:91.66666667%}.col-l-push-10{left:83.33333333%}.col-l-push-9{left:75%}.col-l-push-8{left:66.66666667%}.col-l-push-7{left:58.33333333%}.col-l-push-6{left:50%}.col-l-push-5{left:41.66666667%}.col-l-push-4{left:33.33333333%}.col-l-push-3{left:25%}.col-l-push-2{left:16.66666667%}.col-l-push-1{left:8.33333333%}.col-l-push-0{left:auto}.col-l-offset-12{margin-left:100%}.col-l-offset-11{margin-left:91.66666667%}.col-l-offset-10{margin-left:83.33333333%}.col-l-offset-9{margin-left:75%}.col-l-offset-8{margin-left:66.66666667%}.col-l-offset-7{margin-left:58.33333333%}.col-l-offset-6{margin-left:50%}.col-l-offset-5{margin-left:41.66666667%}.col-l-offset-4{margin-left:33.33333333%}.col-l-offset-3{margin-left:25%}.col-l-offset-2{margin-left:16.66666667%}.col-l-offset-1{margin-left:8.33333333%}.col-l-offset-0{margin-left:0}}@media all and (min-width:1440px){.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9{float:left}.col-xl-12{width:100%}.col-xl-11{width:91.66666667%}.col-xl-10{width:83.33333333%}.col-xl-9{width:75%}.col-xl-8{width:66.66666667%}.col-xl-7{width:58.33333333%}.col-xl-6{width:50%}.col-xl-5{width:41.66666667%}.col-xl-4{width:33.33333333%}.col-xl-3{width:25%}.col-xl-2{width:16.66666667%}.col-xl-1{width:8.33333333%}.col-xl-pull-12{right:100%}.col-xl-pull-11{right:91.66666667%}.col-xl-pull-10{right:83.33333333%}.col-xl-pull-9{right:75%}.col-xl-pull-8{right:66.66666667%}.col-xl-pull-7{right:58.33333333%}.col-xl-pull-6{right:50%}.col-xl-pull-5{right:41.66666667%}.col-xl-pull-4{right:33.33333333%}.col-xl-pull-3{right:25%}.col-xl-pull-2{right:16.66666667%}.col-xl-pull-1{right:8.33333333%}.col-xl-pull-0{right:auto}.col-xl-push-12{left:100%}.col-xl-push-11{left:91.66666667%}.col-xl-push-10{left:83.33333333%}.col-xl-push-9{left:75%}.col-xl-push-8{left:66.66666667%}.col-xl-push-7{left:58.33333333%}.col-xl-push-6{left:50%}.col-xl-push-5{left:41.66666667%}.col-xl-push-4{left:33.33333333%}.col-xl-push-3{left:25%}.col-xl-push-2{left:16.66666667%}.col-xl-push-1{left:8.33333333%}.col-xl-push-0{left:auto}.col-xl-offset-12{margin-left:100%}.col-xl-offset-11{margin-left:91.66666667%}.col-xl-offset-10{margin-left:83.33333333%}.col-xl-offset-9{margin-left:75%}.col-xl-offset-8{margin-left:66.66666667%}.col-xl-offset-7{margin-left:58.33333333%}.col-xl-offset-6{margin-left:50%}.col-xl-offset-5{margin-left:41.66666667%}.col-xl-offset-4{margin-left:33.33333333%}.col-xl-offset-3{margin-left:25%}.col-xl-offset-2{margin-left:16.66666667%}.col-xl-offset-1{margin-left:8.33333333%}.col-xl-offset-0{margin-left:0}}@media all and (max-width:767px){.list-definition>dt{float:none}.list-definition>dd{margin-left:0}.form-row .form-label{text-align:left}.form-row .form-label.required:after{position:static}.nav{padding-bottom:0;padding-left:0;padding-right:0}.nav-bar-outer-actions{margin-top:0}.nav-bar{display:block;margin-bottom:0;margin-left:auto;margin-right:auto;width:30.9rem}.nav-bar:before{display:none}.nav-bar>li{float:left;min-height:9rem}.nav-bar>li:after{display:none}.nav-bar>li:nth-child(4n){clear:both}.nav-bar a{line-height:1.4}.tooltip{display:none!important}.readiness-check-content{margin-right:2rem}.form-el-insider,.form-el-insider-wrap,.page-web-configuration .form-el-insider-input,.page-web-configuration .form-el-insider-input .form-el-input{display:block;width:100%}}@media all and (max-width:479px){.nav-bar{width:23.175rem}.nav-bar>li{width:7.725rem}.nav .btn-group .btn-wrap-try-again,.nav-bar-outer-actions .btn-wrap-try-again{clear:both;display:block;float:none;margin-left:auto;margin-right:auto;margin-top:1rem;padding-top:1rem}}
\ No newline at end of file
diff --git a/setup/src/Magento/Setup/Console/Command/AbstractSetupCommand.php b/setup/src/Magento/Setup/Console/Command/AbstractSetupCommand.php
index 3b8975c02de354a3b9f94cd8763ce934429a4559..7803cacfed564b1b2a75329bb22eaa9610fedb3e 100644
--- a/setup/src/Magento/Setup/Console/Command/AbstractSetupCommand.php
+++ b/setup/src/Magento/Setup/Console/Command/AbstractSetupCommand.php
@@ -11,7 +11,7 @@ use Symfony\Component\Console\Input\InputOption;
 
 /**
  * An abstract class for all Magento Setup command.
- * It adds InitParamListener's magento_init_params option to all setup command.
+ * It adds InitParamListener's magento-init-params option to all setup command.
  */
 abstract class AbstractSetupCommand extends Command
 {
diff --git a/setup/src/Magento/Setup/Console/Command/InstallCommand.php b/setup/src/Magento/Setup/Console/Command/InstallCommand.php
index 2601e45b7aa1e5eb9fa960670e7055e7c9ce433f..d4dbcc4e44acab019cbb0a16750d3605a32687e3 100644
--- a/setup/src/Magento/Setup/Console/Command/InstallCommand.php
+++ b/setup/src/Magento/Setup/Console/Command/InstallCommand.php
@@ -14,23 +14,24 @@ use Magento\Setup\Model\ConfigModel;
 
 /**
  * Command to install Magento application
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
 class InstallCommand extends AbstractSetupCommand
 {
     /**
      * Parameter indicating command whether to cleanup database in the install routine
      */
-    const INPUT_KEY_CLEANUP_DB = 'cleanup_database';
+    const INPUT_KEY_CLEANUP_DB = 'cleanup-database';
 
     /**
      * Parameter to specify an order_increment_prefix
      */
-    const INPUT_KEY_SALES_ORDER_INCREMENT_PREFIX = 'sales_order_increment_prefix';
+    const INPUT_KEY_SALES_ORDER_INCREMENT_PREFIX = 'sales-order-increment-prefix';
 
     /**
      * Parameter indicating command whether to install Sample Data
      */
-    const INPUT_KEY_USE_SAMPLE_DATA = 'use_sample_data';
+    const INPUT_KEY_USE_SAMPLE_DATA = 'use-sample-data';
 
     /**
      * Installer service factory
diff --git a/setup/src/Magento/Setup/Fixtures/CartPriceRulesFixture.php b/setup/src/Magento/Setup/Fixtures/CartPriceRulesFixture.php
index b5d18c63d122fb8100f6b75413e9b606ece384e4..08373f57ea5d648c1e0e0554d141642387f0e06d 100644
--- a/setup/src/Magento/Setup/Fixtures/CartPriceRulesFixture.php
+++ b/setup/src/Magento/Setup/Fixtures/CartPriceRulesFixture.php
@@ -22,8 +22,14 @@ class CartPriceRulesFixture extends Fixture
     public function execute()
     {
         $this->fixtureModel->resetObjectManager();
-        $cartPriceRulesCount = $this->fixtureModel->getValue('cart_price_rules', 9);
-        $cartPriceRulesProductsFloor = $this->fixtureModel->getValue('cart_price_rules_floor', 3);
+        $cartPriceRulesCount = $this->fixtureModel->getValue('cart_price_rules', 0);
+        if (!$cartPriceRulesCount) {
+            return;
+        }
+        $cartPriceRulesProductsFloor = $this->fixtureModel->getValue(
+            'cart_price_rules_floor',
+            3
+        );
 
         /** @var \Magento\Store\Model\StoreManager $storeManager */
         $storeManager = $this->fixtureModel->getObjectManager()->create('Magento\Store\Model\StoreManager');
diff --git a/setup/src/Magento/Setup/Fixtures/CatalogPriceRulesFixture.php b/setup/src/Magento/Setup/Fixtures/CatalogPriceRulesFixture.php
index 4a33e4a3cded0014982c93868ff8486c0dfd604f..fef1b761bcb3019f46e1c4669fec3ba71867bdbc 100644
--- a/setup/src/Magento/Setup/Fixtures/CatalogPriceRulesFixture.php
+++ b/setup/src/Magento/Setup/Fixtures/CatalogPriceRulesFixture.php
@@ -21,7 +21,10 @@ class CatalogPriceRulesFixture extends Fixture
      */
     public function execute()
     {
-        $catalogPriceRulesCount = $this->fixtureModel->getValue('catalog_price_rules', 3);
+        $catalogPriceRulesCount = $this->fixtureModel->getValue('catalog_price_rules', 0);
+        if (!$catalogPriceRulesCount) {
+            return;
+        }
         $this->fixtureModel->resetObjectManager();
 
         /** @var \Magento\Store\Model\StoreManager $storeManager */
diff --git a/setup/src/Magento/Setup/Fixtures/CategoriesFixture.php b/setup/src/Magento/Setup/Fixtures/CategoriesFixture.php
index 9cbba51d1bef73f923a966b2319b11b8f79cb98e..7a512d026757df6caed19e77e5cc1af1a759d8b9 100644
--- a/setup/src/Magento/Setup/Fixtures/CategoriesFixture.php
+++ b/setup/src/Magento/Setup/Fixtures/CategoriesFixture.php
@@ -21,7 +21,10 @@ class CategoriesFixture extends Fixture
      */
     public function execute()
     {
-        $categoriesNumber = $this->fixtureModel->getValue('categories', 18);
+        $categoriesNumber = $this->fixtureModel->getValue('categories', 0);
+        if (!$categoriesNumber) {
+            return;
+        }
         $maxNestingLevel = $this->fixtureModel->getValue('categories_nesting_level', 3);
         $this->fixtureModel->resetObjectManager();
 
diff --git a/setup/src/Magento/Setup/Fixtures/ConfigsApplyFixture.php b/setup/src/Magento/Setup/Fixtures/ConfigsApplyFixture.php
index d69e54d3851f12f0d3d9f4ca69efe9051eb8016b..a4cb005c76a0588fd78abaa9254789f6ea6295a9 100644
--- a/setup/src/Magento/Setup/Fixtures/ConfigsApplyFixture.php
+++ b/setup/src/Magento/Setup/Fixtures/ConfigsApplyFixture.php
@@ -22,6 +22,9 @@ class ConfigsApplyFixture extends Fixture
     public function execute()
     {
         $configs = $this->fixtureModel->getValue('configs', array());
+        if (empty($configs)) {
+            return;
+        }
         $this->fixtureModel->resetObjectManager();
 
         foreach ($configs['config'] as $config) {
diff --git a/setup/src/Magento/Setup/Fixtures/ConfigurableProductsFixture.php b/setup/src/Magento/Setup/Fixtures/ConfigurableProductsFixture.php
index 73af579e0fc84f513391aed8b45bc45e56a90f8f..2d0f51e7cdc4b40bd1072a7b35d0023b7a18f5a3 100644
--- a/setup/src/Magento/Setup/Fixtures/ConfigurableProductsFixture.php
+++ b/setup/src/Magento/Setup/Fixtures/ConfigurableProductsFixture.php
@@ -825,7 +825,10 @@ class ConfigurableProductsFixture extends Fixture
      */
     public function execute()
     {
-        $configurablesCount = $this->fixtureModel->getValue('configurable_products', 90);
+        $configurablesCount = $this->fixtureModel->getValue('configurable_products', 0);
+        if (!$configurablesCount) {
+            return;
+        }
         $this->fixtureModel->resetObjectManager();
 
         /** @var \Magento\Store\Model\StoreManager $storeManager */
diff --git a/setup/src/Magento/Setup/Fixtures/CustomersFixture.php b/setup/src/Magento/Setup/Fixtures/CustomersFixture.php
index e1f7c7e7cf0c2fde7664c544fd178453b8101ae6..e96460fffa2549b7de3c8291df4b8c65856139d8 100644
--- a/setup/src/Magento/Setup/Fixtures/CustomersFixture.php
+++ b/setup/src/Magento/Setup/Fixtures/CustomersFixture.php
@@ -23,7 +23,10 @@ class CustomersFixture extends Fixture
      */
     public function execute()
     {
-        $customersNumber = $this->fixtureModel->getValue('customers', 10);
+        $customersNumber = $this->fixtureModel->getValue('customers', 0);
+        if (!$customersNumber) {
+            return;
+        }
         $this->fixtureModel->resetObjectManager();
 
         /** @var \Magento\Store\Model\StoreManager $storeManager */
diff --git a/setup/src/Magento/Setup/Fixtures/EavVariationsFixture.php b/setup/src/Magento/Setup/Fixtures/EavVariationsFixture.php
index b06da8f8612128b9c7bffac264d5838fa5dae664..e6baa1aabfb141d6daaa94dd766f8cc1ee4c3d10 100644
--- a/setup/src/Magento/Setup/Fixtures/EavVariationsFixture.php
+++ b/setup/src/Magento/Setup/Fixtures/EavVariationsFixture.php
@@ -23,6 +23,10 @@ class EavVariationsFixture extends Fixture
      */
     public function execute()
     {
+        $configurablesCount = $this->fixtureModel->getValue('configurable_products', 0);
+        if (!$configurablesCount) {
+            return;
+        }
         $this->fixtureModel->resetObjectManager();
 
         /* @var $model \Magento\Catalog\Model\Resource\Eav\Attribute */
diff --git a/setup/src/Magento/Setup/Fixtures/SimpleProductsFixture.php b/setup/src/Magento/Setup/Fixtures/SimpleProductsFixture.php
index ef1f39419151dbfd0d339fe96e90e159d30a30b8..56e255e87eabf52b85bb850a314c71fb9aba50eb 100644
--- a/setup/src/Magento/Setup/Fixtures/SimpleProductsFixture.php
+++ b/setup/src/Magento/Setup/Fixtures/SimpleProductsFixture.php
@@ -23,7 +23,10 @@ class SimpleProductsFixture extends Fixture
      */
     public function execute()
     {
-        $simpleProductsCount = $this->fixtureModel->getValue('simple_products', 180);
+        $simpleProductsCount = $this->fixtureModel->getValue('simple_products', 0);
+        if (!$simpleProductsCount) {
+            return;
+        }
         $this->fixtureModel->resetObjectManager();
 
         /** @var \Magento\Store\Model\StoreManager $storeManager */
diff --git a/setup/src/Magento/Setup/Fixtures/StoresFixture.php b/setup/src/Magento/Setup/Fixtures/StoresFixture.php
index 0a8a6c1fa77a17a30be8ecd0c663120f0338de57..da9186baeae3583dac213aa5c8e400a8e32ae0d3 100644
--- a/setup/src/Magento/Setup/Fixtures/StoresFixture.php
+++ b/setup/src/Magento/Setup/Fixtures/StoresFixture.php
@@ -21,9 +21,12 @@ class StoresFixture extends Fixture
      */
     public function execute()
     {
-        $websitesCount = $this->fixtureModel->getValue('websites', 2);
-        $storeGroupsCount = $this->fixtureModel->getValue('store_groups', 3);
-        $storesCount = $this->fixtureModel->getValue('store_views', 5);
+        $websitesCount = $this->fixtureModel->getValue('websites', 0);
+        $storeGroupsCount = $this->fixtureModel->getValue('store_groups', 0);
+        $storesCount = $this->fixtureModel->getValue('store_views', 0);
+        if (!$websitesCount || !$storeGroupsCount || !$storesCount) {
+            return;
+        }
         $this->fixtureModel->resetObjectManager();
 
         /** @var \Magento\Store\Model\StoreManager $storeManager */
diff --git a/setup/src/Magento/Setup/Fixtures/TaxRatesFixture.php b/setup/src/Magento/Setup/Fixtures/TaxRatesFixture.php
index 9380f683369d092b46c69baff6a1041216b5414d..818da63a4ceacdff3267b58101430700bfc42ff7 100644
--- a/setup/src/Magento/Setup/Fixtures/TaxRatesFixture.php
+++ b/setup/src/Magento/Setup/Fixtures/TaxRatesFixture.php
@@ -21,6 +21,10 @@ class TaxRatesFixture extends Fixture
      */
     public function execute()
     {
+        $taxRatesFile = $this->fixtureModel->getValue('tax_rates_file', null);
+        if (empty($taxRatesFile)) {
+            return;
+        }
         $this->fixtureModel->resetObjectManager();
         /** Clean predefined tax rates to maintain consistency */
         /** @var $collection Magento\Tax\Model\Resource\Calculation\Rate\Collection */
@@ -38,7 +42,7 @@ class TaxRatesFixture extends Fixture
         /**
          * Import tax rates with import handler
          */
-        $filename = realpath(__DIR__ . '/tax_rates.csv');
+        $filename = realpath(__DIR__ . '/' . $taxRatesFile);
         $file = [
             'name' => $filename,
             'type' => 'fixtureModel/vnd.ms-excel',
diff --git a/setup/src/Magento/Setup/Model/AdminAccount.php b/setup/src/Magento/Setup/Model/AdminAccount.php
index 7e52b2b604e10f76f660e28d50f26cf59f3d2c6e..5642dda6afb31035d259682e06f7cb078a01cd16 100644
--- a/setup/src/Magento/Setup/Model/AdminAccount.php
+++ b/setup/src/Magento/Setup/Model/AdminAccount.php
@@ -17,11 +17,11 @@ class AdminAccount
     /**#@+
      * Data keys
      */
-    const KEY_USER = 'admin_user';
-    const KEY_PASSWORD = 'admin_password';
-    const KEY_EMAIL = 'admin_email';
-    const KEY_FIRST_NAME = 'admin_firstname';
-    const KEY_LAST_NAME = 'admin_lastname';
+    const KEY_USER = 'admin-user';
+    const KEY_PASSWORD = 'admin-password';
+    const KEY_EMAIL = 'admin-email';
+    const KEY_FIRST_NAME = 'admin-firstname';
+    const KEY_LAST_NAME = 'admin-lastname';
     /**#@- */
 
     /**
diff --git a/setup/src/Magento/Setup/Model/Installer.php b/setup/src/Magento/Setup/Model/Installer.php
index 5db3a546a66113ea49ff556c9f346281ec8afc44..414ef89f37a612ce5dcbbe14f6438d30e11a11a5 100644
--- a/setup/src/Magento/Setup/Model/Installer.php
+++ b/setup/src/Magento/Setup/Model/Installer.php
@@ -787,6 +787,9 @@ class Installer
     public function installUserConfig($data)
     {
         $userConfig = new StoreConfigurationDataMapper();
+        /** @var \Magento\Framework\App\State $appState */
+        $appState = $this->objectManagerProvider->get()->get('Magento\Framework\App\State');
+        $appState->setAreaCode('setup');
         $configData = $userConfig->getConfigData($data);
         if (count($configData) === 0) {
             return;
diff --git a/setup/src/Magento/Setup/Model/Lists.php b/setup/src/Magento/Setup/Model/Lists.php
index e898ed40c16c383ac2fa1ccadbdab2419aae793d..e52e921594caec60421e975f3782c8abf552ac13 100644
--- a/setup/src/Magento/Setup/Model/Lists.php
+++ b/setup/src/Magento/Setup/Model/Lists.php
@@ -10,6 +10,7 @@ use Magento\Framework\Locale\Bundle\CurrencyBundle;
 use Magento\Framework\Locale\Bundle\LanguageBundle;
 use Magento\Framework\Locale\Bundle\RegionBundle;
 use Magento\Framework\Locale\ConfigInterface;
+use Magento\Framework\Locale\Resolver;
 use Magento\Framework\Locale\ResolverInterface;
 
 class Lists
@@ -42,7 +43,7 @@ class Lists
             $list[$code] = \IntlTimeZone::createTimeZone($code)->getDisplayName(
                 false,
                 \IntlTimeZone::DISPLAY_LONG,
-                ResolverInterface::DEFAULT_LOCALE
+                Resolver::DEFAULT_LOCALE
             ) . ' (' . $code . ')';
         }
         asort($list);
@@ -56,7 +57,7 @@ class Lists
      */
     public function getCurrencyList()
     {
-        $currencies = (new CurrencyBundle())->get(ResolverInterface::DEFAULT_LOCALE)['Currencies'];
+        $currencies = (new CurrencyBundle())->get(Resolver::DEFAULT_LOCALE)['Currencies'];
         $list = [];
         foreach ($currencies as $code => $data) {
             $list[$code] = $data[1] . ' (' . $code . ')';
@@ -72,8 +73,8 @@ class Lists
      */
     public function getLocaleList()
     {
-        $languages = (new LanguageBundle())->get(ResolverInterface::DEFAULT_LOCALE)['Languages'];
-        $countries = (new RegionBundle())->get(ResolverInterface::DEFAULT_LOCALE)['Countries'];
+        $languages = (new LanguageBundle())->get(Resolver::DEFAULT_LOCALE)['Languages'];
+        $countries = (new RegionBundle())->get(Resolver::DEFAULT_LOCALE)['Countries'];
         $locales = \ResourceBundle::getLocales(null);
 
         $list = [];
diff --git a/setup/src/Magento/Setup/Model/StoreConfigurationDataMapper.php b/setup/src/Magento/Setup/Model/StoreConfigurationDataMapper.php
index 0fa3c235244568c8a4e7dbf2595c658f87f9dd68..11a3a36e4cd388bb959d79368456f8927f1eeb4c 100644
--- a/setup/src/Magento/Setup/Model/StoreConfigurationDataMapper.php
+++ b/setup/src/Magento/Setup/Model/StoreConfigurationDataMapper.php
@@ -22,15 +22,15 @@ class StoreConfigurationDataMapper
     /**#@+
      * Model data keys
      */
-    const KEY_USE_SEF_URL = 'use_rewrites';
-    const KEY_BASE_URL = 'base_url';
-    const KEY_BASE_URL_SECURE = 'base_url_secure';
-    const KEY_IS_SECURE = 'use_secure';
-    const KEY_IS_SECURE_ADMIN = 'use_secure_admin';
+    const KEY_USE_SEF_URL = 'use-rewrites';
+    const KEY_BASE_URL = 'base-url';
+    const KEY_BASE_URL_SECURE = 'base-url-secure';
+    const KEY_IS_SECURE = 'use-secure';
+    const KEY_IS_SECURE_ADMIN = 'use-secure-admin';
     const KEY_LANGUAGE = 'language';
     const KEY_TIMEZONE = 'timezone';
     const KEY_CURRENCY = 'currency';
-    const KEY_ADMIN_USE_SECURITY_KEY = 'admin_use_security_key';
+    const KEY_ADMIN_USE_SECURITY_KEY = 'admin-use-security-key';
     /**#@- */
 
     /**
diff --git a/setup/src/Magento/Setup/Module/I18n/Pack/Generator.php b/setup/src/Magento/Setup/Module/I18n/Pack/Generator.php
index 8ed6beabb634b09230338d7a570a5c6baa0093cc..bbc0cecfa9ce6de7bc74c7fae3dd45acf35f8cc7 100644
--- a/setup/src/Magento/Setup/Module/I18n/Pack/Generator.php
+++ b/setup/src/Magento/Setup/Module/I18n/Pack/Generator.php
@@ -100,7 +100,7 @@ class Generator
             /** @var \Magento\Setup\Module\I18n\Dictionary\Phrase $phrase */
             $phrase = $phrases[0];
             $error .= sprintf(
-                "The phrase \"%s\" is translated differently in %d places.\n",
+                "The phrase \"%s\" is translated in %d places.\n",
                 $phrase->getPhrase(),
                 count($phrases)
             );
diff --git a/setup/src/Magento/Setup/Mvc/Bootstrap/InitParamListener.php b/setup/src/Magento/Setup/Mvc/Bootstrap/InitParamListener.php
index 1d229e825f9c8f43c165e93bf62574ea9b34c0af..e2525c9e4fbe10e2d3a10fa56372d3bb02d86687 100644
--- a/setup/src/Magento/Setup/Mvc/Bootstrap/InitParamListener.php
+++ b/setup/src/Magento/Setup/Mvc/Bootstrap/InitParamListener.php
@@ -30,7 +30,7 @@ class InitParamListener implements ListenerAggregateInterface, FactoryInterface
     /**
      * A CLI parameter for injecting bootstrap variables
      */
-    const BOOTSTRAP_PARAM = 'magento_init_params';
+    const BOOTSTRAP_PARAM = 'magento-init-params';
 
     /**
      * List of ZF event listeners
diff --git a/setup/src/Magento/Setup/Test/Unit/Console/Command/ConfigSetCommandTest.php b/setup/src/Magento/Setup/Test/Unit/Console/Command/ConfigSetCommandTest.php
index 11e08c4faf7784e8af19f186640dc30ef82b7461..5e7ee9a76a399cea8530457b78a04996861cf2c9 100644
--- a/setup/src/Magento/Setup/Test/Unit/Console/Command/ConfigSetCommandTest.php
+++ b/setup/src/Magento/Setup/Test/Unit/Console/Command/ConfigSetCommandTest.php
@@ -33,7 +33,7 @@ class ConfigSetCommandTest extends \PHPUnit_Framework_TestCase
         $option
             ->expects($this->any())
             ->method('getName')
-            ->will($this->returnValue('db_host'));
+            ->will($this->returnValue('db-host'));
         $this->configModel = $this->getMock('Magento\Setup\Model\ConfigModel', [], [], '', false);
         $this->configModel
             ->expects($this->exactly(2))
@@ -53,9 +53,9 @@ class ConfigSetCommandTest extends \PHPUnit_Framework_TestCase
         $this->configModel
             ->expects($this->once())
             ->method('process')
-            ->with(['db_host' => 'host']);
+            ->with(['db-host' => 'host']);
         $commandTester = new CommandTester($this->command);
-        $commandTester->execute(['--db_host' => 'host']);
+        $commandTester->execute(['--db-host' => 'host']);
         $this->assertSame(
             'You saved the new configuration.' . PHP_EOL,
             $commandTester->getDisplay()
@@ -71,7 +71,7 @@ class ConfigSetCommandTest extends \PHPUnit_Framework_TestCase
         $this->configModel
             ->expects($this->once())
             ->method('process')
-            ->with(['db_host' => 'host']);
+            ->with(['db-host' => 'host']);
         $this->checkInteraction(true);
     }
 
@@ -112,7 +112,7 @@ class ConfigSetCommandTest extends \PHPUnit_Framework_TestCase
         $this->command->setHelperSet($helperSet);
 
         $commandTester = new CommandTester($this->command);
-        $commandTester->execute(['--db_host' => 'host']);
+        $commandTester->execute(['--db-host' => 'host']);
         if ($interactionType) {
             $message = 'You saved the new configuration.' . PHP_EOL;
         } else {
diff --git a/setup/src/Magento/Setup/Test/Unit/Model/InstallerTest.php b/setup/src/Magento/Setup/Test/Unit/Model/InstallerTest.php
index 553c5c8ed4c1ec544a824a240237a1b0eb505dca..e3e44ebd20a3b43114e32d7df801c2c86591bf02 100644
--- a/setup/src/Magento/Setup/Test/Unit/Model/InstallerTest.php
+++ b/setup/src/Magento/Setup/Test/Unit/Model/InstallerTest.php
@@ -234,12 +234,21 @@ class InstallerTest extends \PHPUnit_Framework_TestCase
         $cacheManager = $this->getMock('Magento\Framework\App\Cache\Manager', [], [], '', false);
         $cacheManager->expects($this->once())->method('getAvailableTypes')->willReturn(['foo', 'bar']);
         $cacheManager->expects($this->once())->method('setEnabled')->willReturn(['foo', 'bar']);
+        $appState = (new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this))->getObject(
+            'Magento\Framework\App\State'
+        );
         $this->objectManager->expects($this->any())
             ->method('create')
             ->will($this->returnValueMap([
                 ['Magento\Setup\Module\Setup', ['resource' => $resource], $setup],
                 ['Magento\Setup\Module\DataSetup', [], $dataSetup],
                 ['Magento\Framework\App\Cache\Manager', [], $cacheManager],
+                ['Magento\Framework\App\State', [], $appState],
+            ]));
+        $this->objectManager->expects($this->any())
+            ->method('get')
+            ->will($this->returnValueMap([
+                ['Magento\Framework\App\State', $appState],
             ]));
         $this->adminFactory->expects($this->once())->method('create')->willReturn(
             $this->getMock('Magento\Setup\Model\AdminAccount', [], [], '', false)
diff --git a/setup/src/Magento/Setup/Test/Unit/Module/I18n/Pack/GeneratorTest.php b/setup/src/Magento/Setup/Test/Unit/Module/I18n/Pack/GeneratorTest.php
index b8b74152993606d8c1b42535931f5831e67a8de9..0866b50cf75aa2843100f24c9d9be920e510b6c4 100644
--- a/setup/src/Magento/Setup/Test/Unit/Module/I18n/Pack/GeneratorTest.php
+++ b/setup/src/Magento/Setup/Test/Unit/Module/I18n/Pack/GeneratorTest.php
@@ -110,8 +110,8 @@ class GeneratorTest extends \PHPUnit_Framework_TestCase
     public function testGenerateWithNotAllowedDuplicatesAndDuplicatesExist()
     {
         $error = "Duplicated translation is found, but it is not allowed.\n"
-            . "The phrase \"phrase1\" is translated differently in 1 places.\n"
-            . "The phrase \"phrase2\" is translated differently in 1 places.\n";
+            . "The phrase \"phrase1\" is translated in 1 places.\n"
+            . "The phrase \"phrase2\" is translated in 1 places.\n";
         $this->setExpectedException('\RuntimeException', $error);
 
         $allowDuplicates = false;
diff --git a/setup/src/Magento/Setup/Test/Unit/Mvc/Bootstrap/InitParamListenerTest.php b/setup/src/Magento/Setup/Test/Unit/Mvc/Bootstrap/InitParamListenerTest.php
index 778c734d7e599e59722858d38fa04c110adc3fc5..d0e06963c70effdab4950e340dbb0012f57db37e 100644
--- a/setup/src/Magento/Setup/Test/Unit/Mvc/Bootstrap/InitParamListenerTest.php
+++ b/setup/src/Magento/Setup/Test/Unit/Mvc/Bootstrap/InitParamListenerTest.php
@@ -119,7 +119,7 @@ class InitParamListenerTest extends \PHPUnit_Framework_TestCase
         $request->expects($this->any())
             ->method('getContent')
             ->willReturn(
-                $cliParam ? ['install', '--magento_init_params=' . $cliParam ] : ['install']
+                $cliParam ? ['install', '--magento-init-params=' . $cliParam ] : ['install']
             );
         $mvcApplication->expects($this->any())->method('getConfig')->willReturn(
             $zfAppConfig ? [InitParamListener::BOOTSTRAP_PARAM => $zfAppConfig]:[]
diff --git a/setup/view/styles/lib/forms/_checkbox-radio.less b/setup/view/styles/lib/forms/_checkbox-radio.less
index 6155541bde86c9f9c1a7111eb63b1bc7d638b4c0..a0510ad6a7c66349c140eefe1745c4e64fcbe3de 100644
--- a/setup/view/styles/lib/forms/_checkbox-radio.less
+++ b/setup/view/styles/lib/forms/_checkbox-radio.less
@@ -9,7 +9,6 @@
 
 @checkbox__border-color: @color-gray68;
 @radio-bullet__color: @color-brownie;
-@color-required: @color-prime;
 
 //
 //  Common
@@ -23,7 +22,8 @@
 
     &[disabled],
     &.disabled {
-        + .form-label, + .form-label:before {
+        + .form-label,
+        + .form-label:before {
             cursor: default;
             opacity: @disabled__opacity;
             pointer-events: none;
@@ -31,7 +31,6 @@
     }
 
     //  Hover state
-
     &:not([disabled]),
     &:not(.disabled) {
         + .form-label {
diff --git a/setup/view/styles/lib/forms/_forms.less b/setup/view/styles/lib/forms/_forms.less
index a0e79796f56bbe243d677517531e7222caf0c7be..e0468c4a39b6c5f71bdf67988813b268bb5d1eea 100644
--- a/setup/view/styles/lib/forms/_forms.less
+++ b/setup/view/styles/lib/forms/_forms.less
@@ -12,6 +12,8 @@
 @form-el__focus__border-color: @focus__color;
 @form-el__hover__border-color: darken(@form-el__border-color, 10%);
 
+@color-required: @color-prime;
+
 //
 //  Structure
 //  _____________________________________________