diff --git a/CHANGELOG.md b/CHANGELOG.md
index 338ab6cf7da11ec471acb79edb367b2fedddf175..72d11b49ba5d716aea1f9f023b77e8192cf59065 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,152 +1,162 @@
+0.74.0-beta2
+=============
+* Fixed bugs
+    * Wrong capitalization of the label names (the sentence-style capitalization instead of the headline style)
+    * Inconsistency in the labels in the Admin panel
+    * Customer menu tabs aren't displayed as selected for the child pages
+    * An issue with the Active item in the navigation menu in the Blank and Luma themes
+    * Incorrect price alignment during checkout in the Blank and Luma themes
+    * Broken field "URL" in the Downloadable product in the Admin panel
+* GitHub issues and requests:
+    * [#1096] (https://github.com/magento/magento2/issues/1096) -- Customer model - getPrimaryAddresses without primary billing address
+    * [#1114] (https://github.com/magento/magento2/issues/1114) -- GA bug
+    * [#1116] (https://github.com/magento/magento2/issues/1116) -- Incorrect use of implode()
+    * [#1126] (https://github.com/magento/magento2/pull/1126) -- Fixed occurrences of implode with wrong argument order
+    * [#1128] (https://github.com/magento/magento2/pull/1128) -- Change wording for long operation warning
+
 0.74.0-beta1
 =============
 * Various
-    * Inline JS code is eliminated
+    * Inline JS code was eliminated
     * Fixed XSS vulnerability issues
-    * "Last login time" functionality is moved from Magento_Log module to Magento_Customer module
-    * Implemented two-strategies JS translation
+    * The "Last login time" functionality was moved from the `Magento_Log` module to the `Magento_Customer` module
+    * Implemented two-strategies JavaScript translation
     * Improved backend menu keyboard accessibility
-    * Accessibility improvements: WAI-ARIA in product item on category page and related products
-    * Checkout flow code can work with separate DB storage
-    * Unit tests moved to component directories
+    * Accessibility improvements: WAI-ARIA in a product item on a category page and related products
+    * Checkout flow code can work with a separate DB storage
+    * <a href="http://devdocs.magento.com/guides/v1.0/release-notes/changes.html#change-devrc-unit">Unit tests moved to module directories</a>
     * Addressed naming inconsistencies in REST routes
-    * Added Advanced Developer Workflow for frontend developers
+    * Added Advanced Developer workflow for frontend developers
 * Setup
-    * Utilized Magento error handler in Setup application to convert errors and warnings to exceptions
-    * Fixed error when private content handling doesn't work when HTML profiler and developer mode are on
-    * Fixed error with packages uninstall using Magento Composer Installer failed for the last package
-    * Fixed fatal error in Setup application, after ran composer install with --no-dev option
-    * Fixed JS error when expanding list of modules at "Customize Your Store" step in installation wizard
-    * Fixed JS error when going back to "Customize Your Store" step from "Create Admin Account" step in installation wizard
+    * Utilized Magento error handler in the Setup application to convert errors and warnings to exceptions
+    * Fixed an issue when private content handling did not work with enabled HTML profiler and developer mode
+    * Fixed an issue where Magento Composer Installer failed to uninstall last package
+    * Fixed an issue where a fatal error was thrown in the Setup application after running composer install with the `--no-dev` option
+    * Fixed a JavaScript issue with expanding the list of modules on the  Customize Your Store step in the Setup Wizard
+    * Fixed a JavaScript issue with returning from the Create Admin Account step to the Customize Your Store step in the Setup Wizard
 * Framework
-    * New module Magento_MediaStorage is created and holds components from Magento_Core module
-    * New module Magento_MediaStorage is created and holds components from Magento_Core module
-    * Implemented JS resources bundling (server side pre-processing)
-    * Zend_Locale replaced with Native PHP Implementation
-    * Zend_Date replaced with native PHP DateTime object/functions
-    * Magento\Framework\Exception\LocalizedException constructor is refactored
-    * Magento\Framework\Validator\ValidatorException is renamed
-    * Magento\Framework\Controller\Result\JSON is renamed to meet PSR standard
-    * Library oyejorge/less.php is updated to the latest version
-    * Refactored WebApi framework to support concrete types for custom attributes
+    * Added a new `Magento_MediaStorage` module to store components of the `Magento_Core` module
+    * Implemented JavaScript resources bundling (server side pre-processing)
+    * Replaced `Zend_Locale` with native PHP implementation
+    * Replaced `Zend_Date` with native PHP `DateTime` object/functions
+    * Refactored Magento\Framework\Exception\LocalizedException
+    * Renamed Magento\Framework\Validator\ValidatorException
+    * Renamed Magento\Framework\Controller\Result\JSON to meet PSR standard
+    * Updated the oyejorge/less.php library to the latest version
+    * Refactored WebApi framework to support particular types for custom attributes
     * Version used in SOAP declarations is now taken from routes declared in webapi.xml
     * Added ability to extend API data interfaces using extension attributes
-    * Magento_Core module is removed
+    * Removed the `Magento_Core` module
 * Web API Framework
     * Factories are used instead of builders
-    * Removed auto generation of builders
-    * Made interfaceName a required parameter in Magento\Framework\Api\DataObjectHelper::populateWithArray method
+    * Removed auto-generation of builders
+    * Made `interfaceName` a required parameter in `Magento\Framework\Api\DataObjectHelper::populateWithArray` method
 * Performance
     * Increased caching coverage of Magento storefront pages: Cart, Register, Login, My Account
-    * finished work around HHVM Compatibility
+    * Finished work around <a href="http://hhvm.com/" target="_blank">HHVM compatibility</a>
     * Fixed EAV caching on storefront
-    * Optimized DI compilation for interception
+    * Optimized dependency injection compilation for interception
 * Design
-    * New design in Backend
-    * New messages design in Installation Wizard
-    * New design for MAP on Catalog Frontend Pages
+    * New design for the Magento Admin
+    * New message design in Setup Wizard
+    * New design for Minimum Advertised Price (MAP) on storefront catalog pages
 * Fixed bugs
-    * Catch syntax error in module.xml files
+    * Catch syntax error in `module.xml` files
     * Profiling of cache operations was permanently disabled
     * Session was not cleared when layout is cached
-    * Page cache was invalidated by cron jobs after reindexing, even in case nothing is changed
-    * Typo in method name in Adminhtml/Index/Grid.php
-    * Missing validation of table prefix in 'Step 2: Add a Database' of Web Setup wizard
-    * User hint of password strength validator in Web Setup wizard to be consistent with the algorithm used
-    * New Logger cannot format exception and debug info correctly
+    * Page cache was invalidated by cron jobs after reindexing, even when nothing was changed
+    * Typo in method name in `Adminhtml/Index/Grid.php`
+    * Missing validation of table prefix in Step 2: Add a Database in the Setup wizard
+    * User hint of password strength validator in Web Setup wizard now consistent with the algorithm used
+    * New Logger did not format exception and debug info correctly
     * Wrong styles structure
-    * Customer is redirected to shopping cart by clicking on mini shopping cart after adding product
-    * Gift Message information for Order level is not presented on frontend/backend orders
-    * Wrong "customer_id" value for GiftMessages created using API service
+    * Customer is redirected to shopping cart by clicking on mini-shopping cart after adding product
+    * Gift Message information for Order level is not presented on storefront or Admin orders
+    * Wrong `customer_id` value for GiftMessages created using API service
     * No ability to place order for guest customer using API service
-    * Shopping Cart was displayed partly broken if contained a Product with an image as a custom option
-    * Impossible to add product to the shopping cart with Custom option of type="file"
-    * Adding to cart dialog widget with MSRP price on product page is broken
-    * Copy and Paste detector is run against test files that are blacklisted
-    * Displaying the wrong price on product page when selecting an option for configurable product
-    * Tax amount (tax on full shipping) is refunded, when partial shipping amount is refunded
-    * Tax Calculation Based On Shipping Address, when the discount coupon is applied
+    * Shopping Cart displayed partly broken if it contained a Product with an image as a custom option
+    * Impossible to add product to the shopping cart with Custom option of `type="file"`
+    * Adding to cart dialog widget with MSRP price on product page was broken
+    * Copy and paste detector is run against test files that are blacklisted
+    * Displayed the wrong price on product page when selecting an option for configurable product
+    * Tax amount (tax on full shipping) is refunded when partial shipping amount is refunded
     * Price (including tax) is shown on product page when configuration is set to display excluding tax
-    * FPT is not applied in shopping cart and order for registered user
+    * Fixed Product Tax (FPT) is not applied in shopping cart and orders for registered users
     * FPT not applied for registered users when FPC is disabled
     * "All categoryName" menu link is absent, subcategories are shown on hover of parent category
-    * Horizontal scrolling appears when browser width is resized to mobile size
+    * Horizontal scrolling displays when browser width is resized to mobile size
     * Broken design for "select store" element in CMS grid filter
     * Attribute value uniqueness isn't checked for custom product template
     * Category tree is not displayed in conditions for Catalog Price Rules
-    * Remove hard coded IDs from catalog API code
-    * Bottom margin for "Wishlist Search" Widget
-    * Custom option image with limits view for frontend
+    * Remove hard-coded IDs from catalog API code
+    * Bottom margin for "Wishlist Search" widget
+    * Custom option image with limits view for storefront
     * Category page displayed outdated prices after catalog price rule was deleted
-    * Cart quantity is more than in stock amount
-    * Page layout configuration: not being possible to extend/override on the theme level
+    * Cart quantity is more than in-stock amount
+    * Page layout configuration cannot be extended or overridden by the theme
     * Page layout with custom set of containers causing fatal error
     * Reset password e-mails requested from second store view has link and name of the first main store
-    * There is no ability to place order for virtual product with customer address attribute from backend
-    * Specified details for Bundle product are lost after adding to wishlist
-    * Customer address is set to non default after changing account information
-    * Unable to save newsletter subscription information of customer in backend
+    * Cannot place order for virtual product with customer address attribute from Admin
+    * Specified details for bundle product are lost after adding to wishlist
+    * Customer address is set to non-default after changing account information
+    * Unable to save newsletter subscription information of customer in Admin
     * Guest can't add product to wishlist while registering
     * Cron job for Shipping
     * Solution for issue with attributes with list of countries
-    * Unable to generate variations while creating configurable product
-    * Variations are created with Out of Stock status if configurable product has been switched from simple product
-    * Impossible search Downloadable product using file title
+    * Unable to generate variations while creating a configurable product
+    * Variations are created with out of stock status if configurable product has been switched from simple product
+    * Impossible to search Downloadable product using file title
     * Change order of loading integration tests (load config annotations before fixtures)
-    * Impossible to upload files in Configuration
-    * Creating shipment for an order
+    * Impossible to upload files in configuration
     * Price displaying on product page for bundle product
     * Display bug for tier prices
-    * Required marker is displayed on wrong line in Backend
-    * Categories' titles in Frontend navigation Menu overlap "expand" button on mobile
-    * Backend Login form alignment for ie9
-    * JS loader position for Backend
-    * Display checkboxes on Update Attributes page via Mass Action
-    * Removed Test\Unit from cached DI configuration, as it brings performance degradation
+    * Required marker is displayed on wrong line in Admin
+    * Categories' titles in storefront navigation Menu overlap "expand" button on mobile
+    * Admin Login form alignment issues with IE9
+    * Display check boxes on Update Attributes page using a mass action
+    * Removed Test\Unit from cached dependency injection configuration for performance reasons
     * Impossible to place order with DHL EU shipping method
     * Updates while tables recreation in setup process
-    * Pagination on downloadable products tab in customer account
+    * Pagination issues in the Downloadable Products tab page in a customer account
     * Adding existing attribute on New Product page
     * "Manage Stock" is not saving for bundle product
     * Filter did not work for Order Total report
     * Error on reports for Order Totals if grouped by Year
-    * Customer can't find Order on Frontend
-    * Postal code is still mandatory for Non-US addresses that don't use it
+    * Customer can't find order on storefront
+    * Postal code is still mandatory for non-US addresses that don't use it
     * Price of simple product isn't recalculated after selecting options on product page
     * Don't load bundle quantity from options on bundle page
-    * It's impossible to remove added row from "Minimum Qty Allowed in Shopping Cart" in config
-    * It's impossible to add Product with required Custom Options of "Field" and/or "Area" type to Shopping Cart
+    * Impossible to remove added row from "Minimum Qty Allowed in Shopping Cart"
+    * Impossible to add to the cart a product with required Custom Options of "Field" and/or "Area" type
     * Syntax error in New Shipment email template
-    * Removed admin only web service route for using customer user password reset tokens and setting new passwords
-    * Remove the relevant URL Rewrites configuration after removing a category
+    * Removed `adminhtml`-only web service route for using customer user password reset tokens and setting new passwords
+    * Removed the relevant URL Rewrites configuration after removing a category
     * Static obsolete code test did not recognize partial namespaces
     * Magento breaks when set specific locale
-    * An error on Shipping Method page which appeared on MultiAddress Checkout
-    * Impossible to update Gift Message from backend
+    * Impossible to update Gift Message from Admin
     * Impossible to create configurable product
-    * Impossible to create new attribute through Product Creation page
+    * Impossible to create new attribute using the Product Creation page
     * Product Template page did not work in IE9 and FF
-    * Product image could added only after double click in IE9
-    * Inconsistent timestamp return for Magento admin panel timezone
-    * Few problems with HTML minification
+    * Product image could added only after double-click in IE9
+    * Inconsistent timestamp return for Admin timezone
     * 404 page is displayed on any action with order that it viewed under guest
     * "500 Internal Server Error" in case of excess "Maximum Qty Allowed in Shopping Cart" value
     * MAP link is displayed for a product on category page after delete Catalog Price Rule
-    * Deploy script modifies LESS files with "@urls-resolved: true"
-    * Zip code field is missing in customers addresses on backend
+    * Deploy script modifies LESS files with `@urls-resolved: true`
+    * Zip code field is missing in customer addresses in the Admin
     * Impossible to add bundle product with required option to shopping cart without selecting all available options
-    * Empty email is sent when a registered user changes password in the front end
+    * Empty email is sent when a registered user changes password in the storefront
     * Tabs widget does not initialize sometimes on Product Creation page
     * Fatal error when trying to send notify customer by email about shipment
 * Tests
-    * Fixed an issue with WebDriverException for iframes in functional tests
-    * Added functional test for backend menu navigation
+    * Fixed an issue with `WebDriverException` for iframes in functional tests
+    * Added functional test for Admin menu navigation
     * Replaced end-to-end test for online one-page checkout with injectable test
-    * Replaced end-to-end test for admin user with injectable test
+    * Replaced end-to-end test for administrator user with injectable test
     * Replaced end-to-end test for catalog price rule with injectable test
     * Replaced end-to-end test for store view with injectable test
-    * Increased integration tests coverage for Magento_Indexer module
-    * Increased unit test coverage for Magento_Cms, Magento_Email and Magento_Sales module
+    * Increased integration tests coverage for `Magento_Indexer` module
+    * Increased unit test coverage for `Magento_Cms`, `Magento_Email`, and `Magento_Sales` modules
 * GitHub issues and requests:
     * [#533] (https://github.com/magento/magento2/issues/533) -- Remove Allow all access in .htaccess
     * [#850] (https://github.com/magento/magento2/issues/850) -- HTML Profiler and pub/static Resources
@@ -155,7 +165,7 @@
     * [#1004] (https://github.com/magento/magento2/issues/1004) -- Problem with template luma
     * [#1014] (https://github.com/magento/magento2/issues/1014) -- php index.php update - Class Magento\Store\Model\StoreManagerInterface does not exist
     * [#1015] (https://github.com/magento/magento2/issues/1015) -- After success setup/index.php update - "Missing required argument $engines of Magento\Framework\View\TemplateEngineFactory"
-    * [#1016] (https://github.com/magento/magento2/issues/1016) -- Backend Javascript Errors (new instalation)
+    * [#1016] (https://github.com/magento/magento2/issues/1016) -- Backend Javascript Errors (new installation)
     * [#1020] (https://github.com/magento/magento2/issues/1020) -- Bug generating Sitemap Cron expression
     * [#1029] (https://github.com/magento/magento2/issues/1029) -- Admin dashboard Most Viewed Products Tab issue (without product list)
     * [#1035] (https://github.com/magento/magento2/issues/1035) -- Bug in Magento\Framework\Simplexml\Element::appendChild
diff --git a/Gruntfile.js b/Gruntfile.js
index 4c50be920fa914c5dd2605e0724abccc62e9a885..c0da0e90cf983c21adc836c401f5ecebf408651a 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -8,18 +8,24 @@ module.exports = function (grunt) {
     'use strict';
 
     var _ = require('underscore'),
-        path = require('path');
+        path = require('path'),
+        configDir = './dev/tools/grunt/configs',
+        taskDir = './dev/tools/grunt/tasks';
 
-    require('./dev/tools/grunt/tasks/mage-minify')(grunt);
-    require('time-grunt')(grunt);
+    [
+        taskDir + '/mage-minify',
+        taskDir + '/deploy',
+        'time-grunt'
+    ].forEach(function (task) {
+        require(task)(grunt);
+    });
 
     require('load-grunt-config')(grunt, {
-        configPath: path.join(process.cwd(), 'dev/tools/grunt/configs'),
+        configPath: path.join(__dirname, configDir),
         init: true,
         loadGruntTasks: {
             pattern: [
-                'grunt-*',
-                '!grunt-template-jasmine-requirejs'
+                'grunt-*'
             ]
         }
     });
@@ -78,24 +84,6 @@ module.exports = function (grunt) {
             'clean:pub'
         ],
 
-        spec: [
-            'specRunner:lib',
-            'specRunner:backend',
-            'specRunner:frontend'
-        ],
-
-        unit: [
-            'jasmine:lib-unit',
-            'jasmine:backend-unit',
-            'jasmine:frontend-unit'
-        ],
-
-        integration: [
-            'jasmine:lib-integration',
-            'jasmine:backend-integration',
-            'jasmine:frontend-integration'
-        ],
-
         'legacy-build': [
             'mage-minify:legacy'
         ],
@@ -104,7 +92,15 @@ module.exports = function (grunt) {
             'usebanner:documentationCss',
             'usebanner:documentationLess',
             'usebanner:documentationHtml'
-        ]
+        ],
+
+        spec: function (theme) {
+            var runner = require('./dev/tests/js/jasmine/spec_runner');
+
+            runner.init(grunt, { theme: theme });
+
+            grunt.task.run(runner.getTasks());
+        }
     }, function (task, name) {
         grunt.registerTask(name, task);
     });
diff --git a/app/code/Magento/AdminNotification/composer.json b/app/code/Magento/AdminNotification/composer.json
index 26fe4843a27f037e11f00c3b6d2bbace9e0c9ba3..4bdbc07cfbd7e9bb30713dafc8291546c9b0ea60 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-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-media-storage": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-media-storage": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "lib-libxml": "*",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Authorization/composer.json b/app/code/Magento/Authorization/composer.json
index 77ff967c18683861bf28bd13b3dd7760bbc053aa..41cca87deaa066a7e119c190d49aa72f09d4d8a9 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-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Backend/Model/Auth.php b/app/code/Magento/Backend/Model/Auth.php
index 427ac932f515ff4ee9f90d0f09ef72d0b2983fc6..a15f8e1526e0708180402d9d9c9295d2b28ce890 100644
--- a/app/code/Magento/Backend/Model/Auth.php
+++ b/app/code/Magento/Backend/Model/Auth.php
@@ -93,6 +93,7 @@ class Auth
      * If auth storage was not defined outside - returns default object of auth storage
      *
      * @return \Magento\Backend\Model\Auth\StorageInterface
+     * @codeCoverageIgnore
      */
     public function getAuthStorage()
     {
@@ -126,6 +127,7 @@ class Auth
      * Return credential storage object
      *
      * @return null|\Magento\Backend\Model\Auth\Credential\StorageInterface
+     * @codeCoverageIgnore
      */
     public function getCredentialStorage()
     {
diff --git a/app/code/Magento/Backend/Model/Auth/Session.php b/app/code/Magento/Backend/Model/Auth/Session.php
index 6d0965dc1bbbefdb31093fceccc029e5c75d9d90..fec438f70c744d7b7cc9999d8574f3e4deef862c 100644
--- a/app/code/Magento/Backend/Model/Auth/Session.php
+++ b/app/code/Magento/Backend/Model/Auth/Session.php
@@ -253,6 +253,7 @@ class Session extends \Magento\Framework\Session\SessionManager implements \Mage
      * @param string $path
      * @return bool
      * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     * @codeCoverageIgnore
      */
     public function isValidForPath($path)
     {
diff --git a/app/code/Magento/Backend/Model/Search/Order.php b/app/code/Magento/Backend/Model/Search/Order.php
index f25de8f9881e108572b247ef3de2dbccaf4cd062..314b6a375ee686fcaa2a929aec29265ddafe4856 100644
--- a/app/code/Magento/Backend/Model/Search/Order.php
+++ b/app/code/Magento/Backend/Model/Search/Order.php
@@ -76,12 +76,7 @@ class Order extends \Magento\Framework\Object
                 'id' => 'order/1/' . $order->getId(),
                 'type' => __('Order'),
                 'name' => __('Order #%1', $order->getIncrementId()),
-                'description' => $order->getBillingFirstname() . ' ' . $order->getBillingLastname(),
-                'form_panel_title' => __(
-                    'Order #%1 (%2)',
-                    $order->getIncrementId(),
-                    $order->getBillingFirstname() . ' ' . $order->getBillingLastname()
-                ),
+                'description' => $order->getFirstname() . ' ' . $order->getLastname(),
                 'url' => $this->_adminhtmlData->getUrl('sales/order/view', ['order_id' => $order->getId()]),
             ];
         }
diff --git a/app/code/Magento/Backend/Test/Unit/Model/Auth/SessionTest.php b/app/code/Magento/Backend/Test/Unit/Model/Auth/SessionTest.php
index 68b5d21f85416fdd874179162000c651d3f91e5c..3e41177e72c0cae37f1f4324caa310d63e471e2c 100644
--- a/app/code/Magento/Backend/Test/Unit/Model/Auth/SessionTest.php
+++ b/app/code/Magento/Backend/Test/Unit/Model/Auth/SessionTest.php
@@ -38,6 +38,11 @@ class SessionTest extends \PHPUnit_Framework_TestCase
      */
     protected $storage;
 
+    /**
+     * @var \Magento\Framework\Acl\Builder | \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $aclBuilder;
+
     /**
      * @var Session
      */
@@ -61,7 +66,13 @@ class SessionTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
-        $this->storage = $this->getMock('Magento\Framework\Session\Storage', ['getUser'], [], '', false);
+        $this->storage = $this->getMock(
+            'Magento\Framework\Session\Storage',
+            ['getUser', 'getAcl', 'setAcl'],
+            [],
+            '',
+            false
+        );
         $this->sessionConfig = $this->getMock(
             'Magento\Framework\Session\Config',
             ['getCookiePath', 'getCookieDomain', 'getCookieSecure', 'getCookieHttpOnly'],
@@ -69,6 +80,9 @@ class SessionTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
+        $this->aclBuilder = $this->getMockBuilder('Magento\Framework\Acl\Builder')
+            ->disableOriginalConstructor()
+            ->getMock();
         $objectManager = new ObjectManager($this);
         $this->session = $objectManager->getObject(
             'Magento\Backend\Model\Auth\Session',
@@ -77,7 +91,8 @@ class SessionTest extends \PHPUnit_Framework_TestCase
                 'sessionConfig' => $this->sessionConfig,
                 'cookieManager' => $this->cookieManager,
                 'cookieMetadataFactory' => $this->cookieMetadataFactory,
-                'storage' => $this->storage
+                'storage' => $this->storage,
+                'aclBuilder' => $this->aclBuilder
             ]
         );
     }
@@ -89,6 +104,40 @@ class SessionTest extends \PHPUnit_Framework_TestCase
         $this->session = null;
     }
 
+    /**
+     * @dataProvider refreshAclDataProvider
+     * @param $isUserPassedViaParams
+     */
+    public function testRefreshAcl($isUserPassedViaParams)
+    {
+        $aclMock = $this->getMockBuilder('Magento\Framework\Acl')->disableOriginalConstructor()->getMock();
+        $this->aclBuilder->expects($this->any())->method('getAcl')->willReturn($aclMock);
+        $userMock = $this->getMockBuilder('Magento\User\Model\User')
+            ->setMethods(['getReloadAclFlag', 'setReloadAclFlag', 'unsetData', 'save'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $userMock->expects($this->any())->method('getReloadAclFlag')->willReturn(true);
+        $userMock->expects($this->once())->method('setReloadAclFlag')->with('0')->willReturnSelf();
+        $userMock->expects($this->once())->method('save');
+        $this->storage->expects($this->once())->method('setAcl')->with($aclMock);
+        $this->storage->expects($this->any())->method('getAcl')->willReturn($aclMock);
+        if ($isUserPassedViaParams) {
+            $this->session->refreshAcl($userMock);
+        } else {
+            $this->storage->expects($this->once())->method('getUser')->willReturn($userMock);
+            $this->session->refreshAcl();
+        }
+        $this->assertSame($aclMock, $this->session->getAcl());
+    }
+
+    public function refreshAclDataProvider()
+    {
+        return [
+            'User set via params' => [true],
+            'User set to session object' => [false]
+        ];
+    }
+
     public function testIsLoggedInPositive()
     {
         $lifetime = 900;
@@ -176,4 +225,58 @@ class SessionTest extends \PHPUnit_Framework_TestCase
 
         $this->assertLessThanOrEqual(time(), $this->session->getUpdatedAt());
     }
+
+    /**
+     * @dataProvider isAllowedDataProvider
+     * @param bool $isUserDefined
+     * @param bool $isAclDefined
+     * @param bool $isAllowed
+     * @param true $expectedResult
+     */
+    public function testIsAllowed($isUserDefined, $isAclDefined, $isAllowed, $expectedResult)
+    {
+        $userAclRole = 'userAclRole';
+        if ($isAclDefined) {
+            $aclMock = $this->getMockBuilder('Magento\Framework\Acl')->disableOriginalConstructor()->getMock();
+            $this->storage->expects($this->any())->method('getAcl')->willReturn($aclMock);
+        }
+        if ($isUserDefined) {
+            $userMock = $this->getMockBuilder('Magento\User\Model\User')->disableOriginalConstructor()->getMock();
+            $this->storage->expects($this->once())->method('getUser')->willReturn($userMock);
+        }
+        if ($isAclDefined && $isUserDefined) {
+            $userMock->expects($this->any())->method('getAclRole')->willReturn($userAclRole);
+            $aclMock->expects($this->once())->method('isAllowed')->with($userAclRole)->willReturn($isAllowed);
+        }
+
+        $this->assertEquals($expectedResult, $this->session->isAllowed('resource'));
+    }
+
+    public function isAllowedDataProvider()
+    {
+        return [
+            "Negative: User not defined" => [false, true, true, false],
+            "Negative: Acl not defined" => [true, false, true, false],
+            "Negative: Permission denied" => [true, true, false, false],
+            "Positive: Permission granted" => [true, true, false, false],
+        ];
+    }
+
+    /**
+     * @dataProvider firstPageAfterLoginDataProvider
+     * @param bool $isFirstPageAfterLogin
+     */
+    public function testFirstPageAfterLogin($isFirstPageAfterLogin)
+    {
+        $this->session->setIsFirstPageAfterLogin($isFirstPageAfterLogin);
+        $this->assertEquals($isFirstPageAfterLogin, $this->session->isFirstPageAfterLogin());
+    }
+
+    public function firstPageAfterLoginDataProvider()
+    {
+        return [
+            'First page after login' => [true],
+            'Not first page after login' => [false],
+        ];
+    }
 }
diff --git a/app/code/Magento/Backend/composer.json b/app/code/Magento/Backend/composer.json
index 659cf679b5a1d1a927053f423a23a8ecf8b3bed1..639122ecc702064bc2ceda23e59f32b21fd19f8f 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-beta1",
-        "magento/module-directory": "0.74.0-beta1",
-        "magento/module-developer": "0.74.0-beta1",
-        "magento/module-eav": "0.74.0-beta1",
-        "magento/module-cron": "0.74.0-beta1",
-        "magento/module-theme": "0.74.0-beta1",
-        "magento/module-reports": "0.74.0-beta1",
-        "magento/module-sales": "0.74.0-beta1",
-        "magento/module-quote": "0.74.0-beta1",
-        "magento/module-catalog": "0.74.0-beta1",
-        "magento/module-user": "0.74.0-beta1",
-        "magento/module-backup": "0.74.0-beta1",
-        "magento/module-customer": "0.74.0-beta1",
-        "magento/module-translation": "0.74.0-beta1",
-        "magento/module-require-js": "0.74.0-beta1",
-        "magento/module-config": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-directory": "0.74.0-beta2",
+        "magento/module-developer": "0.74.0-beta2",
+        "magento/module-eav": "0.74.0-beta2",
+        "magento/module-cron": "0.74.0-beta2",
+        "magento/module-theme": "0.74.0-beta2",
+        "magento/module-reports": "0.74.0-beta2",
+        "magento/module-sales": "0.74.0-beta2",
+        "magento/module-quote": "0.74.0-beta2",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/module-user": "0.74.0-beta2",
+        "magento/module-backup": "0.74.0-beta2",
+        "magento/module-customer": "0.74.0-beta2",
+        "magento/module-translation": "0.74.0-beta2",
+        "magento/module-require-js": "0.74.0-beta2",
+        "magento/module-config": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Backend/etc/config.xml b/app/code/Magento/Backend/etc/config.xml
index ea2586bae427a78a76e1fe2eb2e36077c8683824..d83c36cda31cc1936127d317ea7404fc911a6b6c 100644
--- a/app/code/Magento/Backend/etc/config.xml
+++ b/app/code/Magento/Backend/etc/config.xml
@@ -9,7 +9,7 @@
     <default>
         <dev>
             <template>
-                <minify_html>1</minify_html>
+                <minify_html>0</minify_html>
             </template>
         </dev>
         <system>
diff --git a/app/code/Magento/Backup/composer.json b/app/code/Magento/Backup/composer.json
index 714e41e7aae2b3e55c16fc813238911341d8dcc0..2c9f59ec6320c18d224d40af33aa6d20c546a5d7 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-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-cron": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-cron": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Bundle/composer.json b/app/code/Magento/Bundle/composer.json
index bd5de2331605a8ed5e2ef03bceed9054d2dd995e..172bf912af2924d869d8f763c172729ae41920a6 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-beta1",
-        "magento/module-catalog": "0.74.0-beta1",
-        "magento/module-tax": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-sales": "0.74.0-beta1",
-        "magento/module-checkout": "0.74.0-beta1",
-        "magento/module-catalog-inventory": "0.74.0-beta1",
-        "magento/module-customer": "0.74.0-beta1",
-        "magento/module-catalog-rule": "0.74.0-beta1",
-        "magento/module-eav": "0.74.0-beta1",
-        "magento/module-config": "0.74.0-beta1",
-        "magento/module-gift-message": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
-        "magento/module-quote": "0.74.0-beta1",
-        "magento/module-media-storage": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/module-tax": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-sales": "0.74.0-beta2",
+        "magento/module-checkout": "0.74.0-beta2",
+        "magento/module-catalog-inventory": "0.74.0-beta2",
+        "magento/module-customer": "0.74.0-beta2",
+        "magento/module-catalog-rule": "0.74.0-beta2",
+        "magento/module-eav": "0.74.0-beta2",
+        "magento/module-config": "0.74.0-beta2",
+        "magento/module-gift-message": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
+        "magento/module-quote": "0.74.0-beta2",
+        "magento/module-media-storage": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "suggest": {
-        "magento/module-webapi": "0.74.0-beta1"
+        "magento/module-webapi": "0.74.0-beta2"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Bundle/view/frontend/templates/email/order/items/creditmemo/default.phtml b/app/code/Magento/Bundle/view/frontend/templates/email/order/items/creditmemo/default.phtml
index fdeaac8ee26557106b9de8418a9671ae7ac5c773..0caea13b65b5a392e18217bfa682c4a46e70c0d0 100644
--- a/app/code/Magento/Bundle/view/frontend/templates/email/order/items/creditmemo/default.phtml
+++ b/app/code/Magento/Bundle/view/frontend/templates/email/order/items/creditmemo/default.phtml
@@ -17,7 +17,7 @@
 
 <?php foreach ($items as $_item): ?>
 
-<?php if ($block->getItemOptions() || $parentItem->getDescription() || $this->helper('Magento\GiftMessage\Helper\Message')->getIsMessagesAvailable('order_item', $parentItem) && $parentItem->getGiftMessageId()): ?>
+<?php if ($block->getItemOptions() || $parentItem->getDescription() || $this->helper('Magento\GiftMessage\Helper\Message')->isMessagesAllowed('order_item', $parentItem) && $parentItem->getGiftMessageId()): ?>
     <?php $_showlastRow = true ?>
 <?php else: ?>
     <?php $_showlastRow = false ?>
diff --git a/app/code/Magento/Bundle/view/frontend/templates/email/order/items/invoice/default.phtml b/app/code/Magento/Bundle/view/frontend/templates/email/order/items/invoice/default.phtml
index cf6b520bcd00f4501b049b16a7ab8d1ba1df82cd..4aec9e983e7c5e86238ee178f30a331d77e3c907 100644
--- a/app/code/Magento/Bundle/view/frontend/templates/email/order/items/invoice/default.phtml
+++ b/app/code/Magento/Bundle/view/frontend/templates/email/order/items/invoice/default.phtml
@@ -18,7 +18,7 @@
 
 <?php foreach ($items as $_item): ?>
 
-<?php if ($block->getItemOptions() || $parentItem->getDescription() || $this->helper('Magento\GiftMessage\Helper\Message')->getIsMessagesAvailable('order_item', $parentItem) && $parentItem->getGiftMessageId()): ?>
+<?php if ($block->getItemOptions() || $parentItem->getDescription() || $this->helper('Magento\GiftMessage\Helper\Message')->isMessagesAllowed('order_item', $parentItem) && $parentItem->getGiftMessageId()): ?>
     <?php $_showlastRow = true ?>
 <?php else: ?>
     <?php $_showlastRow = false ?>
diff --git a/app/code/Magento/Bundle/view/frontend/templates/email/order/items/order/default.phtml b/app/code/Magento/Bundle/view/frontend/templates/email/order/items/order/default.phtml
index 876a77f7726ca088c68b7d713c25f701784ae431..c40ac91faf20a0c999997f46c23e9cec3403874e 100644
--- a/app/code/Magento/Bundle/view/frontend/templates/email/order/items/order/default.phtml
+++ b/app/code/Magento/Bundle/view/frontend/templates/email/order/items/order/default.phtml
@@ -14,7 +14,7 @@
 <?php $parentItem = $block->getItem() ?>
 <?php $items = array_merge([$parentItem], $parentItem->getChildrenItems()); ?>
 
-<?php if ($block->getItemOptions() || $_item->getDescription() || $this->helper('Magento\GiftMessage\Helper\Message')->getIsMessagesAvailable('order_item', $_item) && $_item->getGiftMessageId()): ?>
+<?php if ($block->getItemOptions() || $_item->getDescription() || $this->helper('Magento\GiftMessage\Helper\Message')->isMessagesAllowed('order_item', $_item) && $_item->getGiftMessageId()): ?>
     <?php $_showlastRow = true ?>
 <?php else: ?>
     <?php $_showlastRow = false ?>
diff --git a/app/code/Magento/Bundle/view/frontend/templates/email/order/items/shipment/default.phtml b/app/code/Magento/Bundle/view/frontend/templates/email/order/items/shipment/default.phtml
index 8b9c86c24780d8d2cf798a5798c9bdd20d52df06..c485ea7524906bce8ab030dbf5d8ff6263875b8e 100644
--- a/app/code/Magento/Bundle/view/frontend/templates/email/order/items/shipment/default.phtml
+++ b/app/code/Magento/Bundle/view/frontend/templates/email/order/items/shipment/default.phtml
@@ -16,7 +16,7 @@
 
 <?php foreach ($items as $_item): ?>
 
-<?php if ($block->getItemOptions() || $parentItem->getDescription() || $this->helper('Magento\GiftMessage\Helper\Message')->getIsMessagesAvailable('order_item', $parentItem) && $parentItem->getGiftMessageId()): ?>
+<?php if ($block->getItemOptions() || $parentItem->getDescription() || $this->helper('Magento\GiftMessage\Helper\Message')->isMessagesAllowed('order_item', $parentItem) && $parentItem->getGiftMessageId()): ?>
     <?php $_showlastRow = true ?>
 <?php else: ?>
     <?php $_showlastRow = false ?>
diff --git a/app/code/Magento/Bundle/view/frontend/templates/sales/order/creditmemo/items/renderer.phtml b/app/code/Magento/Bundle/view/frontend/templates/sales/order/creditmemo/items/renderer.phtml
index 92d5f48d962c250205098b11690e9c9ab43825fc..3d908583e199610eb48aad5ce83126bf957a9ca8 100644
--- a/app/code/Magento/Bundle/view/frontend/templates/sales/order/creditmemo/items/renderer.phtml
+++ b/app/code/Magento/Bundle/view/frontend/templates/sales/order/creditmemo/items/renderer.phtml
@@ -19,7 +19,7 @@
 
 <?php foreach ($items as $_item): ?>
 
-    <?php if ($block->getItemOptions() || $parentItem->getDescription() || $this->helper('Magento\GiftMessage\Helper\Message')->getIsMessagesAvailable('order_item', $parentItem) && $parentItem->getGiftMessageId()): ?>
+    <?php if ($block->getItemOptions() || $parentItem->getDescription() || $this->helper('Magento\GiftMessage\Helper\Message')->isMessagesAllowed('order_item', $parentItem) && $parentItem->getGiftMessageId()): ?>
         <?php $_showlastRow = true ?>
     <?php else: ?>
         <?php $_showlastRow = false ?>
diff --git a/app/code/Magento/Bundle/view/frontend/templates/sales/order/invoice/items/renderer.phtml b/app/code/Magento/Bundle/view/frontend/templates/sales/order/invoice/items/renderer.phtml
index ce6c827ab2475925de00c0d711b814175ba93fce..c7f4dd44bc08b82634ec14cbc2753806cb1fae3b 100644
--- a/app/code/Magento/Bundle/view/frontend/templates/sales/order/invoice/items/renderer.phtml
+++ b/app/code/Magento/Bundle/view/frontend/templates/sales/order/invoice/items/renderer.phtml
@@ -18,7 +18,7 @@
 <?php $_prevOptionId = '' ?>
 <?php foreach ($items as $_item): ?>
 
-    <?php if ($block->getItemOptions() || $parentItem->getDescription() || $this->helper('Magento\GiftMessage\Helper\Message')->getIsMessagesAvailable('order_item', $parentItem) && $parentItem->getGiftMessageId()): ?>
+    <?php if ($block->getItemOptions() || $parentItem->getDescription() || $this->helper('Magento\GiftMessage\Helper\Message')->isMessagesAllowed('order_item', $parentItem) && $parentItem->getGiftMessageId()): ?>
         <?php $_showlastRow = true ?>
     <?php else: ?>
         <?php $_showlastRow = false ?>
diff --git a/app/code/Magento/Bundle/view/frontend/templates/sales/order/items/renderer.phtml b/app/code/Magento/Bundle/view/frontend/templates/sales/order/items/renderer.phtml
index b4276aeaa7ba38fc5c5fe72c6fe3622a2f243a55..c50b8cfdac980447385bf4367eb3dfddbf07c789 100644
--- a/app/code/Magento/Bundle/view/frontend/templates/sales/order/items/renderer.phtml
+++ b/app/code/Magento/Bundle/view/frontend/templates/sales/order/items/renderer.phtml
@@ -17,7 +17,7 @@
 
 <?php foreach ($items as $_item): ?>
 
-    <?php if ($block->getItemOptions() || $parentItem->getDescription() || $this->helper('Magento\GiftMessage\Helper\Message')->getIsMessagesAvailable('order_item', $parentItem) && $parentItem->getGiftMessageId()): ?>
+    <?php if ($block->getItemOptions() || $parentItem->getDescription() || $this->helper('Magento\GiftMessage\Helper\Message')->isMessagesAllowed('order_item', $parentItem) && $parentItem->getGiftMessageId()): ?>
         <?php $_showlastRow = true ?>
     <?php else: ?>
         <?php $_showlastRow = false ?>
diff --git a/app/code/Magento/Bundle/view/frontend/templates/sales/order/shipment/items/renderer.phtml b/app/code/Magento/Bundle/view/frontend/templates/sales/order/shipment/items/renderer.phtml
index 1e02e1b887ad8f29e744f362cbad49440888fe75..15406932c1c3e8706afa0c13b58c5c717ddb3dca 100644
--- a/app/code/Magento/Bundle/view/frontend/templates/sales/order/shipment/items/renderer.phtml
+++ b/app/code/Magento/Bundle/view/frontend/templates/sales/order/shipment/items/renderer.phtml
@@ -17,7 +17,7 @@
 
 <?php foreach ($items as $_item): ?>
 
-    <?php if ($block->getItemOptions() || $parentItem->getDescription() || $this->helper('Magento\GiftMessage\Helper\Message')->getIsMessagesAvailable('order_item', $parentItem) && $parentItem->getGiftMessageId()): ?>
+    <?php if ($block->getItemOptions() || $parentItem->getDescription() || $this->helper('Magento\GiftMessage\Helper\Message')->isMessagesAllowed('order_item', $parentItem) && $parentItem->getGiftMessageId()): ?>
         <?php $_showlastRow = true ?>
     <?php else: ?>
         <?php $_showlastRow = false ?>
diff --git a/app/code/Magento/Captcha/composer.json b/app/code/Magento/Captcha/composer.json
index a00471c9759f5616e89b021b324ccb5c5116bd67..ee220a5e9b3af383185d71694704c4cb25b72f53 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-beta1",
-        "magento/module-customer": "0.74.0-beta1",
-        "magento/module-checkout": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-customer": "0.74.0-beta2",
+        "magento/module-checkout": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Catalog/Model/Category/Attribute/Source/Page.php b/app/code/Magento/Catalog/Model/Category/Attribute/Source/Page.php
index a62537b88cc8707f2de132e3063d4a0bc3140b74..3cff2cc0941a3b7b0ee6febfa0c6fc4ebb3ca88b 100644
--- a/app/code/Magento/Catalog/Model/Category/Attribute/Source/Page.php
+++ b/app/code/Magento/Catalog/Model/Category/Attribute/Source/Page.php
@@ -5,7 +5,7 @@
  */
 namespace Magento\Catalog\Model\Category\Attribute\Source;
 
-use Magento\Cms\Model\Resource\Block\Grid\CollectionFactory;
+use Magento\Cms\Model\Resource\Block\CollectionFactory;
 
 /**
  * Catalog category landing page attribute source
diff --git a/app/code/Magento/Catalog/Model/Observer.php b/app/code/Magento/Catalog/Model/Observer.php
index dac92e427e266bdd07f63eb1e3ce3c5edf18c7dc..39e72883f68add9d3672497199eb7c744480a7db 100644
--- a/app/code/Magento/Catalog/Model/Observer.php
+++ b/app/code/Magento/Catalog/Model/Observer.php
@@ -5,6 +5,9 @@
  */
 namespace Magento\Catalog\Model;
 
+/**
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
 class Observer
 {
     /**
@@ -62,16 +65,23 @@ class Observer
     protected $_productResourceFactory;
 
     /**
-     * @param \Magento\Catalog\Model\Resource\Category $categoryResource
-     * @param \Magento\Catalog\Model\Resource\Product $catalogProduct
+     * @var \Magento\Framework\Registry
+     */
+    protected $_registry;
+
+    /**
+     * @param \Magento\Framework\Registry $registry
+     * @param Resource\Category $categoryResource
+     * @param Resource\Product $catalogProduct
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
-     * @param \Magento\Catalog\Model\Layer\Resolver $layerResolver
+     * @param Layer\Resolver $layerResolver
      * @param \Magento\Catalog\Helper\Category $catalogCategory
      * @param \Magento\Catalog\Helper\Data $catalogData
      * @param Indexer\Category\Flat\State $categoryFlatState
-     * @param \Magento\Catalog\Model\Resource\ProductFactory $productResourceFactory
+     * @param Resource\ProductFactory $productResourceFactory
      */
     public function __construct(
+        \Magento\Framework\Registry $registry,
         \Magento\Catalog\Model\Resource\Category $categoryResource,
         \Magento\Catalog\Model\Resource\Product $catalogProduct,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
@@ -81,6 +91,7 @@ class Observer
         \Magento\Catalog\Model\Indexer\Category\Flat\State $categoryFlatState,
         \Magento\Catalog\Model\Resource\ProductFactory $productResourceFactory
     ) {
+        $this->_registry = $registry;
         $this->_categoryResource = $categoryResource;
         $this->_catalogProduct = $catalogProduct;
         $this->_storeManager = $storeManager;
@@ -137,11 +148,20 @@ class Observer
             $block->addIdentity(\Magento\Catalog\Model\Category::CACHE_TAG . '_' . $category->getId());
 
             $tree = $parentCategoryNode->getTree();
+
+            $isActiveCategory = false;
+            /** @var \Magento\Catalog\Model\Category $currentCategory */
+            $currentCategory = $this->_registry->registry('current_category');
+            if ($currentCategory && $currentCategory->getId() == $category->getId()) {
+                $isActiveCategory = true;
+            }
+
             $categoryData = [
                 'name' => $category->getName(),
                 'id' => $nodeId,
                 'url' => $this->_catalogCategory->getCategoryUrl($category),
-                'is_active' => $this->_isActiveMenuCategory($category),
+                'has_active' => $this->hasActive($category),
+                'is_active' => $isActiveCategory
             ];
             $categoryNode = new \Magento\Framework\Data\Tree\Node($categoryData, 'id', $tree, $parentCategoryNode);
             $parentCategoryNode->addChild($categoryNode);
@@ -162,7 +182,7 @@ class Observer
      * @param \Magento\Framework\Data\Tree\Node $category
      * @return bool
      */
-    protected function _isActiveMenuCategory($category)
+    protected function hasActive($category)
     {
         if (!$this->_catalogLayer) {
             return false;
diff --git a/app/code/Magento/Catalog/Model/Resource/Category/Attribute/Source/Page.php b/app/code/Magento/Catalog/Model/Resource/Category/Attribute/Source/Page.php
index 10c44850e0f7c4e3ceda09b1fabee2f8fe564651..6e6b4406d71d4ac4d6d1fcd8f71a97bd32b8f0b7 100644
--- a/app/code/Magento/Catalog/Model/Resource/Category/Attribute/Source/Page.php
+++ b/app/code/Magento/Catalog/Model/Resource/Category/Attribute/Source/Page.php
@@ -15,16 +15,16 @@ class Page extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource
     /**
      * Block collection factory
      *
-     * @var \Magento\Cms\Model\Resource\Block\Grid\CollectionFactory
+     * @var \Magento\Cms\Model\Resource\Block\CollectionFactory
      */
     protected $_blockCollectionFactory;
 
     /**
      * Construct
      *
-     * @param \Magento\Cms\Model\Resource\Block\Grid\CollectionFactory $blockCollectionFactory
+     * @param \Magento\Cms\Model\Resource\Block\CollectionFactory $blockCollectionFactory
      */
-    public function __construct(\Magento\Cms\Model\Resource\Block\Grid\CollectionFactory $blockCollectionFactory)
+    public function __construct(\Magento\Cms\Model\Resource\Block\CollectionFactory $blockCollectionFactory)
     {
         $this->_blockCollectionFactory = $blockCollectionFactory;
     }
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Category/Attribute/Source/PageTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Category/Attribute/Source/PageTest.php
index b55a39bce8812111d551e0833f73aa4adab27485..1086b9a0c28a189006cc0f248931ffc26c45917f 100644
--- a/app/code/Magento/Catalog/Test/Unit/Model/Category/Attribute/Source/PageTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Model/Category/Attribute/Source/PageTest.php
@@ -45,7 +45,7 @@ class PageTest extends \PHPUnit_Framework_TestCase
     {
         $mockedCollection = $this->getMockedCollection();
 
-        $mockBuilder = $this->getMockBuilder('Magento\Cms\Model\Resource\Block\Grid\CollectionFactory');
+        $mockBuilder = $this->getMockBuilder('Magento\Cms\Model\Resource\Block\CollectionFactory');
         $mock = $mockBuilder->setMethods(['create'])
             ->disableOriginalConstructor()
             ->getMock();
diff --git a/app/code/Magento/Catalog/composer.json b/app/code/Magento/Catalog/composer.json
index 9a8170b92698efcd808b3e06769ad1fbf619ab8b..b0605d9539855499da59d386f5e106fa32951c96 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-beta1",
-        "magento/module-eav": "0.74.0-beta1",
-        "magento/module-cms": "0.74.0-beta1",
-        "magento/module-indexer": "0.74.0-beta1",
-        "magento/module-customer": "0.74.0-beta1",
-        "magento/module-theme": "0.74.0-beta1",
-        "magento/module-checkout": "0.74.0-beta1",
-        "magento/module-log": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-widget": "0.74.0-beta1",
-        "magento/module-wishlist": "0.74.0-beta1",
-        "magento/module-tax": "0.74.0-beta1",
-        "magento/module-msrp": "0.74.0-beta1",
-        "magento/module-catalog-inventory": "0.74.0-beta1",
-        "magento/module-directory": "0.74.0-beta1",
-        "magento/module-catalog-rule": "0.74.0-beta1",
-        "magento/module-product-alert": "0.74.0-beta1",
-        "magento/module-url-rewrite": "0.74.0-beta1",
-        "magento/module-catalog-url-rewrite": "0.74.0-beta1",
-        "magento/module-page-cache": "0.74.0-beta1",
-        "magento/module-quote": "0.74.0-beta1",
-        "magento/module-config": "0.74.0-beta1",
-        "magento/module-media-storage": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-eav": "0.74.0-beta2",
+        "magento/module-cms": "0.74.0-beta2",
+        "magento/module-indexer": "0.74.0-beta2",
+        "magento/module-customer": "0.74.0-beta2",
+        "magento/module-theme": "0.74.0-beta2",
+        "magento/module-checkout": "0.74.0-beta2",
+        "magento/module-log": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-widget": "0.74.0-beta2",
+        "magento/module-wishlist": "0.74.0-beta2",
+        "magento/module-tax": "0.74.0-beta2",
+        "magento/module-msrp": "0.74.0-beta2",
+        "magento/module-catalog-inventory": "0.74.0-beta2",
+        "magento/module-directory": "0.74.0-beta2",
+        "magento/module-catalog-rule": "0.74.0-beta2",
+        "magento/module-product-alert": "0.74.0-beta2",
+        "magento/module-url-rewrite": "0.74.0-beta2",
+        "magento/module-catalog-url-rewrite": "0.74.0-beta2",
+        "magento/module-page-cache": "0.74.0-beta2",
+        "magento/module-quote": "0.74.0-beta2",
+        "magento/module-config": "0.74.0-beta2",
+        "magento/module-media-storage": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "suggest": {
-        "magento/module-cookie": "0.74.0-beta1"
+        "magento/module-cookie": "0.74.0-beta2"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Catalog/etc/webapi.xml b/app/code/Magento/Catalog/etc/webapi.xml
index a4fb44c7eae061b3547fee1c93d61889dd923b7a..88bc0f93a6ec32002356446962220f48422f1fce 100644
--- a/app/code/Magento/Catalog/etc/webapi.xml
+++ b/app/code/Magento/Catalog/etc/webapi.xml
@@ -82,7 +82,7 @@
             <resource ref="Magento_Catalog::attributes_attributes" />
         </resources>
     </route>
-    <route url="/V1/products/attributes/:attributeId" method="PUT">
+    <route url="/V1/products/attributes/:attributeCode" method="PUT">
         <service class="Magento\Catalog\Api\ProductAttributeRepositoryInterface" method="save"/>
         <resources>
             <resource ref="Magento_Catalog::attributes_attributes" />
diff --git a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/category/edit/form.phtml b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/category/edit/form.phtml
index 71d0a48dd8fed85df0c811eae2c4ea91ff26b255..8d2f762d8160c59931897313e43bc43222ad0fe7 100644
--- a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/category/edit/form.phtml
+++ b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/category/edit/form.phtml
@@ -54,7 +54,7 @@ $categoryId = $block->getCategoryId();
 
 <div data-id="information-dialog-category" class="messages admin__scope" style="display: none;">
     <div class="message message-notice">
-        <div><?php echo __('This operation can take much time'); ?></div>
+        <div><?php echo __('This operation can take a long time'); ?></div>
     </div>
 </div>
 
diff --git a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/category/tree.phtml b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/category/tree.phtml
index 26731afb65e187e36e8220b4069611391fd39f6c..58fa76afac0d4d5a4418dc8663f43e4cfd647ab7 100644
--- a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/category/tree.phtml
+++ b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/category/tree.phtml
@@ -32,7 +32,7 @@
 
 <div data-id="information-dialog-tree" class="messages admin__scope" style="display: none;">
     <div class="message message-notice">
-       <div><?php echo __('This operation can take much time'); ?></div>
+       <div><?php echo __('This operation can take a long time'); ?></div>
     </div>
 </div>
 <!--[if IE]>
diff --git a/app/code/Magento/CatalogImportExport/composer.json b/app/code/Magento/CatalogImportExport/composer.json
index 3bb4b80527dc8989ba4ef59f37efcd9377882ab8..3d648c064b3abec3b79a9ebf0ce4675582bece41 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-beta1",
-        "magento/module-eav": "0.74.0-beta1",
-        "magento/module-import-export": "0.74.0-beta1",
-        "magento/module-indexer": "0.74.0-beta1",
-        "magento/module-store": "0.74.0-beta1",
-        "magento/module-catalog-inventory": "0.74.0-beta1",
-        "magento/module-media-storage": "0.74.0-beta1",
-        "magento/module-customer": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/module-eav": "0.74.0-beta2",
+        "magento/module-import-export": "0.74.0-beta2",
+        "magento/module-indexer": "0.74.0-beta2",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-catalog-inventory": "0.74.0-beta2",
+        "magento/module-media-storage": "0.74.0-beta2",
+        "magento/module-customer": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "ext-ctype": "*",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/CatalogInventory/composer.json b/app/code/Magento/CatalogInventory/composer.json
index a99f0c15c70591434e213c94bd370e5acc14c7b5..a08100c30935a41452a6cdcbbca3a6fba2b62d9e 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-beta1",
-        "magento/module-store": "0.74.0-beta1",
-        "magento/module-catalog": "0.74.0-beta1",
-        "magento/module-customer": "0.74.0-beta1",
-        "magento/module-indexer": "0.74.0-beta1",
-        "magento/module-eav": "0.74.0-beta1",
-        "magento/module-quote": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-config": "0.74.0-beta2",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/module-customer": "0.74.0-beta2",
+        "magento/module-indexer": "0.74.0-beta2",
+        "magento/module-eav": "0.74.0-beta2",
+        "magento/module-quote": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/CatalogRule/composer.json b/app/code/Magento/CatalogRule/composer.json
index d7523d37ba568775f8fe18fabdb4585b482856fa..527f58c05615f46d3c9348c710cb8f5ce65b8777 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-beta1",
-        "magento/module-rule": "0.74.0-beta1",
-        "magento/module-catalog": "0.74.0-beta1",
-        "magento/module-customer": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-eav": "0.74.0-beta1",
-        "magento/module-indexer": "0.74.0-beta1",
-        "magento/module-import-export": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-rule": "0.74.0-beta2",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/module-customer": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-eav": "0.74.0-beta2",
+        "magento/module-indexer": "0.74.0-beta2",
+        "magento/module-import-export": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/CatalogSearch/composer.json b/app/code/Magento/CatalogSearch/composer.json
index 9c69ab5a1b10fea15fa6fa4d44323e926a1b0c4c..d0d4169d006ce4208d00d09dc1b3dc3c87a907c5 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-beta1",
-        "magento/module-catalog": "0.74.0-beta1",
-        "magento/module-search": "0.74.0-beta1",
-        "magento/module-customer": "0.74.0-beta1",
-        "magento/module-directory": "0.74.0-beta1",
-        "magento/module-indexer": "0.74.0-beta1",
-        "magento/module-eav": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-theme": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/module-search": "0.74.0-beta2",
+        "magento/module-customer": "0.74.0-beta2",
+        "magento/module-directory": "0.74.0-beta2",
+        "magento/module-indexer": "0.74.0-beta2",
+        "magento/module-eav": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-theme": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/CatalogUrlRewrite/composer.json b/app/code/Magento/CatalogUrlRewrite/composer.json
index de90f444789d867ebda8453f31af08074193e769..730aec4c662dca3ff93602e6ecfcc12d33594130 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-beta1",
-        "magento/module-catalog": "0.74.0-beta1",
-        "magento/module-catalog-import-export": "0.74.0-beta1",
-        "magento/module-eav": "0.74.0-beta1",
-        "magento/module-import-export": "0.74.0-beta1",
-        "magento/module-store": "0.74.0-beta1",
-        "magento/module-url-rewrite": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/module-catalog-import-export": "0.74.0-beta2",
+        "magento/module-eav": "0.74.0-beta2",
+        "magento/module-import-export": "0.74.0-beta2",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-url-rewrite": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/CatalogWidget/composer.json b/app/code/Magento/CatalogWidget/composer.json
index 8b533a13e21623868e280a344d074c008b2c1098..772427302289cc7e94adf038c5620c8751c04d20 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-beta1",
-        "magento/module-widget": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-rule": "0.74.0-beta1",
-        "magento/module-eav": "0.74.0-beta1",
-        "magento/module-customer": "0.74.0-beta1",
-        "magento/module-store": "0.74.0-beta1",
-        "magento/module-wishlist": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/module-widget": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-rule": "0.74.0-beta2",
+        "magento/module-eav": "0.74.0-beta2",
+        "magento/module-customer": "0.74.0-beta2",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-wishlist": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Centinel/composer.json b/app/code/Magento/Centinel/composer.json
index 2270659643400f47167fa405dd0219815331ce13..497c1378422053931b3f7c2580aeb4f9843162c5 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-beta1",
-        "magento/module-checkout": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-sales": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-checkout": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-sales": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Checkout/Block/Cart/Sidebar.php b/app/code/Magento/Checkout/Block/Cart/Sidebar.php
index a811d6069b6ffe4a1f7469064bb79a7581fe8f87..549b8c8a54437223408fc59daebc1a78637fc0f6 100644
--- a/app/code/Magento/Checkout/Block/Cart/Sidebar.php
+++ b/app/code/Magento/Checkout/Block/Cart/Sidebar.php
@@ -9,6 +9,7 @@
 namespace Magento\Checkout\Block\Cart;
 
 use Magento\Framework\View\Block\IdentityInterface;
+use Magento\Store\Model\ScopeInterface;
 
 /**
  * Wishlist sidebar block
@@ -19,6 +20,7 @@ class Sidebar extends AbstractCart implements IdentityInterface
      * Xml pah to chackout sidebar count value
      */
     const XML_PATH_CHECKOUT_SIDEBAR_COUNT = 'checkout/sidebar/count';
+    const XML_PATH_CHECKOUT_SIDEBAR_DISPLAY = 'checkout/sidebar/display';
 
     /**
      * @var \Magento\Catalog\Model\Resource\Url
@@ -73,7 +75,7 @@ class Sidebar extends AbstractCart implements IdentityInterface
         if (is_null($count)) {
             $count = $this->_scopeConfig->getValue(
                 self::XML_PATH_CHECKOUT_SIDEBAR_COUNT,
-                \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+                ScopeInterface::SCOPE_STORE
             );
             $this->setData('item_count', $count);
         }
@@ -161,14 +163,43 @@ class Sidebar extends AbstractCart implements IdentityInterface
     /**
      * Get one page checkout page url
      *
-     * @return bool
-     * @SuppressWarnings(PHPMD.BooleanGetMethodName)
+     * @return string
      */
     public function getCheckoutUrl()
     {
         return $this->getUrl('checkout/onepage');
     }
 
+    /**
+     * Get shoppinc cart page url
+     *
+     * @return string
+     */
+    public function getShoppingCartUrl()
+    {
+        return $this->getUrl('checkout/cart');
+    }
+
+    /**
+     * Get update cart item url
+     *
+     * @return string
+     */
+    public function getUpdateItemQtyUrl()
+    {
+        return $this->getUrl('checkout/sidebar/updateItemQty');
+    }
+
+    /**
+     * Get remove cart item url
+     *
+     * @return string
+     */
+    public function getRemoveItemUrl()
+    {
+        return $this->getUrl('checkout/sidebar/removeItem');
+    }
+
     /**
      * Define if Mini Shopping Cart Pop-Up Menu enabled
      *
@@ -178,8 +209,8 @@ class Sidebar extends AbstractCart implements IdentityInterface
     public function getIsNeedToDisplaySideBar()
     {
         return (bool)$this->_scopeConfig->getValue(
-            'checkout/sidebar/display',
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+            self::XML_PATH_CHECKOUT_SIDEBAR_DISPLAY,
+            ScopeInterface::SCOPE_STORE
         );
     }
 
@@ -284,8 +315,24 @@ class Sidebar extends AbstractCart implements IdentityInterface
         return $identities;
     }
 
+    /**
+     * Retrieve subtotal block html
+     *
+     * @return string
+     */
     public function getTotalsHtml()
     {
         return $this->getLayout()->getBlock('checkout.cart.minicart.totals')->toHtml();
     }
+
+    /**
+     * Retrieve items qty text
+     *
+     * @param int $qty
+     * @return \Magento\Framework\Phrase
+     */
+    public function getSummaryText($qty)
+    {
+        return ($qty == 1) ? __(' item') : __(' items');
+    }
 }
diff --git a/app/code/Magento/Checkout/Controller/Sidebar/RemoveItem.php b/app/code/Magento/Checkout/Controller/Sidebar/RemoveItem.php
new file mode 100644
index 0000000000000000000000000000000000000000..d0ed1515f90475a09ce1034632bd4db6c656267e
--- /dev/null
+++ b/app/code/Magento/Checkout/Controller/Sidebar/RemoveItem.php
@@ -0,0 +1,98 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Checkout\Controller\Sidebar;
+
+use Magento\Checkout\Model\Sidebar;
+use Magento\Framework\App\Action\Action;
+use Magento\Framework\App\Action\Context;
+use Magento\Framework\App\Response\Http;
+use Magento\Framework\Exception\LocalizedException;
+use Magento\Framework\Json\Helper\Data;
+use Magento\Framework\View\Result\PageFactory;
+use Psr\Log\LoggerInterface;
+
+class RemoveItem extends Action
+{
+    /**
+     * @var Sidebar
+     */
+    protected $sidebar;
+
+    /**
+     * @var LoggerInterface
+     */
+    protected $logger;
+
+    /**
+     * @var Data
+     */
+    protected $jsonHelper;
+
+    /**
+     * @var PageFactory
+     */
+    protected $resultPageFactory;
+
+    /**
+     * @param Context $context
+     * @param Sidebar $sidebar
+     * @param LoggerInterface $logger
+     * @param Data $jsonHelper
+     * @param PageFactory $resultPageFactory
+     */
+    public function __construct(
+        Context $context,
+        Sidebar $sidebar,
+        LoggerInterface $logger,
+        Data $jsonHelper,
+        PageFactory $resultPageFactory
+    ) {
+        $this->sidebar = $sidebar;
+        $this->logger = $logger;
+        $this->jsonHelper = $jsonHelper;
+        $this->resultPageFactory = $resultPageFactory;
+        parent::__construct($context);
+    }
+
+    /**
+     * @return $this
+     */
+    public function execute()
+    {
+        $itemId = (int)$this->getRequest()->getParam('item_id');
+        try {
+            $this->sidebar->checkQuoteItem($itemId);
+            $this->sidebar->removeQuoteItem($itemId);
+            return $this->jsonResponse();
+        } catch (LocalizedException $e) {
+            return $this->jsonResponse($e->getMessage());
+        } catch (\Exception $e) {
+            $this->logger->critical($e);
+            return $this->jsonResponse($e->getMessage());
+        }
+    }
+
+    /**
+     * Compile JSON response
+     *
+     * @param string $error
+     * @return Http
+     */
+    protected function jsonResponse($error = '')
+    {
+        $response = $this->sidebar->getResponseData($error);
+
+        if (empty($error)) {
+            $resultPage = $this->resultPageFactory->create();
+            $block = $resultPage->getLayout()->getBlock('minicart.content')->toHtml();
+            $response['content'] = $block;
+        }
+
+        return $this->getResponse()->representJson(
+            $this->jsonHelper->jsonEncode($response)
+        );
+    }
+}
diff --git a/app/code/Magento/Checkout/Controller/Sidebar/UpdateItemQty.php b/app/code/Magento/Checkout/Controller/Sidebar/UpdateItemQty.php
new file mode 100644
index 0000000000000000000000000000000000000000..656ea11ad773b9a2141a12e4c6714ccc33a880f9
--- /dev/null
+++ b/app/code/Magento/Checkout/Controller/Sidebar/UpdateItemQty.php
@@ -0,0 +1,83 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Checkout\Controller\Sidebar;
+
+use Magento\Checkout\Model\Sidebar;
+use Magento\Framework\App\Action\Action;
+use Magento\Framework\App\Action\Context;
+use Magento\Framework\App\Response\Http;
+use Magento\Framework\Exception\LocalizedException;
+use Magento\Framework\Json\Helper\Data;
+use Psr\Log\LoggerInterface;
+
+class UpdateItemQty extends Action
+{
+    /**
+     * @var Sidebar
+     */
+    protected $sidebar;
+
+    /**
+     * @var LoggerInterface
+     */
+    protected $logger;
+
+    /**
+     * @var Data
+     */
+    protected $jsonHelper;
+
+    /**
+     * @param Context $context
+     * @param Sidebar $sidebar
+     * @param LoggerInterface $logger
+     * @param Data $jsonHelper
+     */
+    public function __construct(
+        Context $context,
+        Sidebar $sidebar,
+        LoggerInterface $logger,
+        Data $jsonHelper
+    ) {
+        $this->sidebar = $sidebar;
+        $this->logger = $logger;
+        $this->jsonHelper = $jsonHelper;
+        parent::__construct($context);
+    }
+
+    /**
+     * @return $this
+     */
+    public function execute()
+    {
+        $itemId = (int)$this->getRequest()->getParam('item_id');
+        $itemQty = (int)$this->getRequest()->getParam('item_qty');
+
+        try {
+            $this->sidebar->checkQuoteItem($itemId);
+            $this->sidebar->updateQuoteItem($itemId, $itemQty);
+            return $this->jsonResponse();
+        } catch (LocalizedException $e) {
+            return $this->jsonResponse($e->getMessage());
+        } catch (\Exception $e) {
+            $this->logger->critical($e);
+            return $this->jsonResponse($e->getMessage());
+        }
+    }
+
+    /**
+     * Compile JSON response
+     *
+     * @param string $error
+     * @return Http
+     */
+    protected function jsonResponse($error = '')
+    {
+        return $this->getResponse()->representJson(
+            $this->jsonHelper->jsonEncode($this->sidebar->getResponseData($error))
+        );
+    }
+}
diff --git a/app/code/Magento/Checkout/Model/Cart.php b/app/code/Magento/Checkout/Model/Cart.php
index 898bbefe8c47fdcefa1bbe22e8599fbc72f224df..b023e8eda142fc9c3cefededf0b1ea027a308a3c 100644
--- a/app/code/Magento/Checkout/Model/Cart.php
+++ b/app/code/Magento/Checkout/Model/Cart.php
@@ -228,8 +228,10 @@ class Cart extends Object implements CartInterface
     {
         $quote = $this->getQuote()->setCheckoutMethod('');
         $this->_checkoutSession->setCartWasUpdated(true);
+        // TODO: Move this logic to Multishipping module as plug-in.
         // reset for multiple address checkout
-        if ($this->_checkoutSession->getCheckoutState() !== Session::CHECKOUT_STATE_BEGIN) {
+        if ($this->_checkoutSession->getCheckoutState() !== Session::CHECKOUT_STATE_BEGIN
+            && $this->_checkoutSession->getCheckoutState() !== null) {
             $quote->removeAllAddresses()->removePayment();
             $this->_checkoutSession->resetCheckout();
         }
diff --git a/app/code/Magento/Checkout/Model/Sidebar.php b/app/code/Magento/Checkout/Model/Sidebar.php
new file mode 100644
index 0000000000000000000000000000000000000000..225c5c7323bc48cc3d06f970acfa59b5a99d6965
--- /dev/null
+++ b/app/code/Magento/Checkout/Model/Sidebar.php
@@ -0,0 +1,178 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Checkout\Model;
+
+use Magento\Checkout\Helper\Data as HelperData;
+use Magento\Checkout\Model\Cart;
+use Magento\Framework\Exception\LocalizedException;
+use Magento\Framework\Locale\ResolverInterface;
+use Magento\Quote\Api\Data\CartItemInterface;
+use Magento\Quote\Model\Quote\Address\Total;
+
+class Sidebar
+{
+    /**
+     * @var Cart
+     */
+    protected $cart;
+
+    /**
+     * @var HelperData
+     */
+    protected $helperData;
+
+    /**
+     * @var ResolverInterface
+     */
+    protected $resolver;
+
+    /**
+     * @var int
+     */
+    protected $summaryQty;
+
+    /**
+     * @param Cart $cart
+     * @param HelperData $helperData
+     * @param ResolverInterface $resolver
+     */
+    public function __construct(
+        Cart $cart,
+        HelperData $helperData,
+        ResolverInterface $resolver
+    ) {
+        $this->cart = $cart;
+        $this->helperData = $helperData;
+        $this->resolver = $resolver;
+    }
+
+    /**
+     * Compile response data
+     *
+     * @param string $error
+     * @return array
+     */
+    public function getResponseData($error = '')
+    {
+        if (empty($error)) {
+            $response = [
+                'success' => true,
+                'data' => [
+                    'summary_qty' => $this->getSummaryQty(),
+                    'summary_text' => $this->getSummaryText(),
+                    'subtotal' => $this->getSubtotalHtml(),
+                ],
+            ];
+            if (!$this->getSummaryQty()) {
+                $response['cleanup'] = true;
+            }
+        } else {
+            $response = [
+                'success' => false,
+                'error_message' => $error,
+            ];
+        }
+        return $response;
+    }
+
+    /**
+     * Check if required quote item exist
+     *
+     * @param int $itemId
+     * @throws LocalizedException
+     * @return $this
+     */
+    public function checkQuoteItem($itemId)
+    {
+        $item = $this->cart->getQuote()->getItemById($itemId);
+        if (!$item instanceof CartItemInterface) {
+            throw new LocalizedException(__('We can\'t find the quote item.'));
+        }
+        return $this;
+    }
+
+    /**
+     * Remove quote item
+     *
+     * @param int $itemId
+     * @return $this
+     */
+    public function removeQuoteItem($itemId)
+    {
+        $this->cart->removeItem($itemId);
+        $this->cart->save();
+        return $this;
+    }
+
+    /**
+     * Update quote item
+     *
+     * @param int $itemId
+     * @param int $itemQty
+     * @throws LocalizedException
+     * @return $this
+     */
+    public function updateQuoteItem($itemId, $itemQty)
+    {
+        $itemData = [$itemId => ['qty' => $this->normalize($itemQty)]];
+        $this->cart->updateItems($itemData)->save();
+        return $this;
+    }
+
+    /**
+     * Apply normalization filter to item qty value
+     *
+     * @param int $itemQty
+     * @return int|array
+     */
+    protected function normalize($itemQty)
+    {
+        if ($itemQty) {
+            $filter = new \Zend_Filter_LocalizedToNormalized(
+                ['locale' => $this->resolver->getLocale()]
+            );
+            return $filter->filter($itemQty);
+        }
+        return $itemQty;
+    }
+
+    /**
+     * Retrieve summary qty
+     *
+     * @return int
+     */
+    protected function getSummaryQty()
+    {
+        if (!$this->summaryQty) {
+            $this->summaryQty = $this->cart->getSummaryQty();
+        }
+        return $this->summaryQty;
+    }
+
+    /**
+     * Retrieve summary qty text
+     *
+     * @return string
+     */
+    protected function getSummaryText()
+    {
+        return ($this->getSummaryQty() == 1) ? __(' item') : __(' items');
+    }
+
+    /**
+     * Retrieve subtotal block html
+     *
+     * @return string
+     */
+    protected function getSubtotalHtml()
+    {
+        $totals = $this->cart->getQuote()->getTotals();
+        $subtotal = isset($totals['subtotal']) && $totals['subtotal'] instanceof Total
+            ? $totals['subtotal']->getValue()
+            : 0;
+        return $this->helperData->formatPrice($subtotal);
+    }
+}
diff --git a/app/code/Magento/Checkout/Test/Unit/Controller/Sidebar/RemoveItemTest.php b/app/code/Magento/Checkout/Test/Unit/Controller/Sidebar/RemoveItemTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..900693acec908f43bb86e24f10f89e0d04585bb4
--- /dev/null
+++ b/app/code/Magento/Checkout/Test/Unit/Controller/Sidebar/RemoveItemTest.php
@@ -0,0 +1,234 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Checkout\Test\Unit\Controller\Sidebar;
+
+use Magento\Framework\Exception\LocalizedException;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
+
+class RemoveItemTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\Checkout\Controller\Sidebar\RemoveItem */
+    protected $removeItem;
+
+    /** @var ObjectManagerHelper */
+    protected $objectManagerHelper;
+
+    /** @var \Magento\Checkout\Model\Sidebar|\PHPUnit_Framework_MockObject_MockObject */
+    protected $sidebarMock;
+
+    /** @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $loggerMock;
+
+    /** @var \Magento\Framework\Json\Helper\Data|\PHPUnit_Framework_MockObject_MockObject */
+    protected $jsonHelperMock;
+
+    /** @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\View\Result\PageFactory|\PHPUnit_Framework_MockObject_MockObject */
+    protected $resultPageFactoryMock;
+
+    protected function setUp()
+    {
+        $this->sidebarMock = $this->getMock('Magento\Checkout\Model\Sidebar', [], [], '', false);
+        $this->loggerMock = $this->getMock('Psr\Log\LoggerInterface');
+        $this->jsonHelperMock = $this->getMock('Magento\Framework\Json\Helper\Data', [], [], '', false);
+        $this->requestMock = $this->getMock('Magento\Framework\App\RequestInterface');
+        $this->responseMock = $this->getMockForAbstractClass(
+            'Magento\Framework\App\ResponseInterface',
+            [],
+            '',
+            false,
+            true,
+            true,
+            ['representJson']
+        );
+        $this->resultPageFactoryMock = $this->getMock('Magento\Framework\View\Result\PageFactory', [], [], '', false);
+
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+        $this->removeItem = $this->objectManagerHelper->getObject(
+            'Magento\Checkout\Controller\Sidebar\RemoveItem',
+            [
+                'sidebar' => $this->sidebarMock,
+                'logger' => $this->loggerMock,
+                'jsonHelper' => $this->jsonHelperMock,
+                'request' => $this->requestMock,
+                'response' => $this->responseMock,
+                'resultPageFactory' => $this->resultPageFactoryMock,
+            ]
+        );
+    }
+
+    public function testExecute()
+    {
+        $this->requestMock->expects($this->once())
+            ->method('getParam')
+            ->with('item_id', null)
+            ->willReturn('1');
+
+        $this->sidebarMock->expects($this->once())
+            ->method('checkQuoteItem')
+            ->with(1)
+            ->willReturnSelf();
+        $this->sidebarMock->expects($this->once())
+            ->method('removeQuoteItem')
+            ->with(1)
+            ->willReturnSelf();
+        $this->sidebarMock->expects($this->once())
+            ->method('getResponseData')
+            ->with('')
+            ->willReturn(
+                [
+                    'cleanup' => true,
+                    'data' => [
+                        'summary_qty' => 0,
+                        'summary_text' => __(' items'),
+                        'subtotal' => 0,
+                    ],
+                ]
+            );
+
+        $pageMock = $this->getMockBuilder('Magento\Framework\View\Result\Page')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->resultPageFactoryMock->expects($this->once())
+            ->method('create')
+            ->with(false, [])
+            ->willReturn($pageMock);
+
+        $layoutMock = $this->getMockBuilder('Magento\Framework\View\LayoutInterface')
+            ->getMock();
+
+        $pageMock->expects($this->once())
+            ->method('getLayout')
+            ->willReturn($layoutMock);
+
+        $blockMock = $this->getMockBuilder('Magento\Framework\View\Element\BlockInterface')
+            ->getMock();
+
+        $layoutMock->expects($this->once())
+            ->method('getBlock')
+            ->with('minicart.content')
+            ->willReturn($blockMock);
+
+        $blockMock->expects($this->once())
+            ->method('toHtml')
+            ->willReturn('block html');
+
+        $this->jsonHelperMock->expects($this->once())
+            ->method('jsonEncode')
+            ->with(
+                [
+                    'cleanup' => true,
+                    'data' => [
+                        'summary_qty' => 0,
+                        'summary_text' => __(' items'),
+                        'subtotal' => 0,
+                    ],
+                    'content' => 'block html',
+                ]
+            )
+            ->willReturn('json encoded');
+
+        $this->responseMock->expects($this->once())
+            ->method('representJson')
+            ->with('json encoded')
+            ->willReturn('json represented');
+
+        $this->assertEquals('json represented', $this->removeItem->execute());
+    }
+
+    public function testExecuteWithLocalizedException()
+    {
+        $this->requestMock->expects($this->once())
+            ->method('getParam')
+            ->with('item_id', null)
+            ->willReturn('1');
+
+        $this->sidebarMock->expects($this->once())
+            ->method('checkQuoteItem')
+            ->with(1)
+            ->willThrowException(new LocalizedException(__('Error message!')));
+
+        $this->sidebarMock->expects($this->once())
+            ->method('getResponseData')
+            ->with('Error message!')
+            ->willReturn(
+                [
+                    'success' => false,
+                    'error_message' => 'Error message!',
+                ]
+            );
+
+        $this->jsonHelperMock->expects($this->once())
+            ->method('jsonEncode')
+            ->with(
+                [
+                    'success' => false,
+                    'error_message' => 'Error message!',
+                ]
+            )
+            ->willReturn('json encoded');
+
+        $this->responseMock->expects($this->once())
+            ->method('representJson')
+            ->with('json encoded')
+            ->willReturn('json represented');
+
+        $this->assertEquals('json represented', $this->removeItem->execute());
+    }
+
+    public function testExecuteWithException()
+    {
+        $this->requestMock->expects($this->once())
+            ->method('getParam')
+            ->with('item_id', null)
+            ->willReturn('1');
+
+        $exception = new \Exception('Error message!');
+
+        $this->sidebarMock->expects($this->once())
+            ->method('checkQuoteItem')
+            ->with(1)
+            ->willThrowException($exception);
+
+        $this->loggerMock->expects($this->once())
+            ->method('critical')
+            ->with($exception)
+            ->willReturn(null);
+
+        $this->sidebarMock->expects($this->once())
+            ->method('getResponseData')
+            ->with('Error message!')
+            ->willReturn(
+                [
+                    'success' => false,
+                    'error_message' => 'Error message!',
+                ]
+            );
+
+        $this->jsonHelperMock->expects($this->once())
+            ->method('jsonEncode')
+            ->with(
+                [
+                    'success' => false,
+                    'error_message' => 'Error message!',
+                ]
+            )
+            ->willReturn('json encoded');
+
+        $this->responseMock->expects($this->once())
+            ->method('representJson')
+            ->with('json encoded')
+            ->willReturn('json represented');
+
+        $this->assertEquals('json represented', $this->removeItem->execute());
+    }
+}
diff --git a/app/code/Magento/Checkout/Test/Unit/Controller/Sidebar/UpdateItemQtyTest.php b/app/code/Magento/Checkout/Test/Unit/Controller/Sidebar/UpdateItemQtyTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..b36cbed010b0298348affe01da90822694fd8cb0
--- /dev/null
+++ b/app/code/Magento/Checkout/Test/Unit/Controller/Sidebar/UpdateItemQtyTest.php
@@ -0,0 +1,210 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Checkout\Test\Unit\Controller\Sidebar;
+
+use Magento\Framework\Exception\LocalizedException;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
+
+class UpdateItemQtyTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\Checkout\Controller\Sidebar\UpdateItemQty */
+    protected $updateItemQty;
+
+    /** @var ObjectManagerHelper */
+    protected $objectManagerHelper;
+
+    /** @var \Magento\Checkout\Model\Sidebar|\PHPUnit_Framework_MockObject_MockObject */
+    protected $sidebarMock;
+
+    /** @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $loggerMock;
+
+    /** @var \Magento\Framework\Json\Helper\Data|\PHPUnit_Framework_MockObject_MockObject */
+    protected $jsonHelperMock;
+
+    /** @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $requestMock;
+
+    /** @var \Magento\Framework\App\ResponseInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $responseMock;
+
+    protected function setUp()
+    {
+        $this->sidebarMock = $this->getMock('Magento\Checkout\Model\Sidebar', [], [], '', false);
+        $this->loggerMock = $this->getMock('Psr\Log\LoggerInterface');
+        $this->jsonHelperMock = $this->getMock('Magento\Framework\Json\Helper\Data', [], [], '', false);
+        $this->requestMock = $this->getMock('Magento\Framework\App\RequestInterface');
+        $this->responseMock = $this->getMockForAbstractClass(
+            'Magento\Framework\App\ResponseInterface',
+            [],
+            '',
+            false,
+            true,
+            true,
+            ['representJson']
+        );
+
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+        $this->updateItemQty = $this->objectManagerHelper->getObject(
+            'Magento\Checkout\Controller\Sidebar\UpdateItemQty',
+            [
+                'sidebar' => $this->sidebarMock,
+                'logger' => $this->loggerMock,
+                'jsonHelper' => $this->jsonHelperMock,
+                'request' => $this->requestMock,
+                'response' => $this->responseMock,
+            ]
+        );
+    }
+
+    public function testExecute()
+    {
+        $this->requestMock->expects($this->at(0))
+            ->method('getParam')
+            ->with('item_id', null)
+            ->willReturn('1');
+        $this->requestMock->expects($this->at(1))
+            ->method('getParam')
+            ->with('item_qty', null)
+            ->willReturn('2');
+
+        $this->sidebarMock->expects($this->once())
+            ->method('checkQuoteItem')
+            ->with(1)
+            ->willReturnSelf();
+        $this->sidebarMock->expects($this->once())
+            ->method('updateQuoteItem')
+            ->with(1, 2)
+            ->willReturnSelf();
+        $this->sidebarMock->expects($this->once())
+            ->method('getResponseData')
+            ->with('')
+            ->willReturn(
+                [
+                    'data' => [
+                        'summary_qty' => 2,
+                        'summary_text' => __(' items'),
+                        'subtotal' => 12.34,
+                    ],
+                ]
+            );
+
+        $this->jsonHelperMock->expects($this->once())
+            ->method('jsonEncode')
+            ->with(
+                [
+                    'data' => [
+                        'summary_qty' => 2,
+                        'summary_text' => __(' items'),
+                        'subtotal' => 12.34,
+                    ],
+                ]
+            )
+            ->willReturn('json encoded');
+
+        $this->responseMock->expects($this->once())
+            ->method('representJson')
+            ->with('json encoded')
+            ->willReturn('json represented');
+
+        $this->assertEquals('json represented', $this->updateItemQty->execute());
+    }
+
+    public function testExecuteWithLocalizedException()
+    {
+        $this->requestMock->expects($this->at(0))
+            ->method('getParam')
+            ->with('item_id', null)
+            ->willReturn('1');
+        $this->requestMock->expects($this->at(1))
+            ->method('getParam')
+            ->with('item_qty', null)
+            ->willReturn('2');
+
+        $this->sidebarMock->expects($this->once())
+            ->method('checkQuoteItem')
+            ->with(1)
+            ->willThrowException(new LocalizedException(__('Error!')));
+
+        $this->sidebarMock->expects($this->once())
+            ->method('getResponseData')
+            ->with('Error!')
+            ->willReturn(
+                [
+                    'success' => false,
+                    'error_message' => 'Error!',
+                ]
+            );
+
+        $this->jsonHelperMock->expects($this->once())
+            ->method('jsonEncode')
+            ->with(
+                [
+                    'success' => false,
+                    'error_message' => 'Error!',
+                ]
+            )
+            ->willReturn('json encoded');
+
+        $this->responseMock->expects($this->once())
+            ->method('representJson')
+            ->with('json encoded')
+            ->willReturn('json represented');
+
+        $this->assertEquals('json represented', $this->updateItemQty->execute());
+    }
+
+    public function testExecuteWithException()
+    {
+        $this->requestMock->expects($this->at(0))
+            ->method('getParam')
+            ->with('item_id', null)
+            ->willReturn('1');
+        $this->requestMock->expects($this->at(1))
+            ->method('getParam')
+            ->with('item_qty', null)
+            ->willReturn('2');
+
+        $exception = new \Exception('Error!');
+
+        $this->sidebarMock->expects($this->once())
+            ->method('checkQuoteItem')
+            ->with(1)
+            ->willThrowException($exception);
+
+        $this->loggerMock->expects($this->once())
+            ->method('critical')
+            ->with($exception)
+            ->willReturn(null);
+
+        $this->sidebarMock->expects($this->once())
+            ->method('getResponseData')
+            ->with('Error!')
+            ->willReturn(
+                [
+                    'success' => false,
+                    'error_message' => 'Error!',
+                ]
+            );
+
+        $this->jsonHelperMock->expects($this->once())
+            ->method('jsonEncode')
+            ->with(
+                [
+                    'success' => false,
+                    'error_message' => 'Error!',
+                ]
+            )
+            ->willReturn('json encoded');
+
+        $this->responseMock->expects($this->once())
+            ->method('representJson')
+            ->with('json encoded')
+            ->willReturn('json represented');
+
+        $this->assertEquals('json represented', $this->updateItemQty->execute());
+    }
+}
diff --git a/app/code/Magento/Checkout/Test/Unit/Model/SidebarTest.php b/app/code/Magento/Checkout/Test/Unit/Model/SidebarTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..c928db0923da844cdecd741b08269824d726a6f5
--- /dev/null
+++ b/app/code/Magento/Checkout/Test/Unit/Model/SidebarTest.php
@@ -0,0 +1,233 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Checkout\Test\Unit\Model;
+
+use Magento\Checkout\Model\Sidebar;
+
+class SidebarTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var Sidebar */
+    protected $sidebar;
+
+    /** @var \Magento\Checkout\Model\Cart|\PHPUnit_Framework_MockObject_MockObject */
+    protected $cartMock;
+
+    /** @var \Magento\Checkout\Helper\Data|\PHPUnit_Framework_MockObject_MockObject */
+    protected $checkoutHelperMock;
+
+    /** @var \Magento\Framework\Locale\ResolverInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $resolverMock;
+
+    protected function setUp()
+    {
+        $this->cartMock = $this->getMock('Magento\Checkout\Model\Cart', [], [], '', false);
+        $this->checkoutHelperMock = $this->getMock('Magento\Checkout\Helper\Data', [], [], '', false);
+        $this->resolverMock = $this->getMock('Magento\Framework\Locale\ResolverInterface');
+
+        $this->sidebar = new Sidebar(
+            $this->cartMock,
+            $this->checkoutHelperMock,
+            $this->resolverMock
+        );
+    }
+
+    /**
+     * @param string $error
+     * @param float $summaryQty
+     * @param array $totals
+     * @param array $result
+     *
+     * @dataProvider dataProviderGetResponseData
+     */
+    public function testGetResponseData($error, $summaryQty, $totals, $result)
+    {
+        $quoteMock = $this->getMockBuilder('Magento\Quote\Model\Quote')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $quoteMock->expects($this->any())
+            ->method('getTotals')
+            ->willReturn($totals);
+
+        $this->cartMock->expects($this->any())
+            ->method('getSummaryQty')
+            ->willReturn($summaryQty);
+        $this->cartMock->expects($this->any())
+            ->method('getQuote')
+            ->willReturn($quoteMock);
+
+        $this->checkoutHelperMock->expects($this->any())
+            ->method('formatPrice')
+            ->willReturnArgument(0);
+
+        $this->assertEquals($result, $this->sidebar->getResponseData($error));
+    }
+
+    public function dataProviderGetResponseData()
+    {
+        $totalMock = $this->getMockBuilder('Magento\Quote\Model\Quote\Address\Total')
+            ->disableOriginalConstructor()
+            ->setMethods(['getValue'])
+            ->getMock();
+        $totalMock->expects($this->any())
+            ->method('getValue')
+            ->willReturn(12.34);
+
+        return [
+            [
+                '',
+                0,
+                [],
+                [
+                    'success' => true,
+                    'data' => [
+                        'summary_qty' => 0,
+                        'summary_text' => __(' items'),
+                        'subtotal' => 0,
+                    ],
+                    'cleanup' => true,
+                ],
+            ],
+            [
+                '',
+                1,
+                [
+                    'subtotal' => $this->getMock('NonexistentClass'),
+                ],
+                [
+                    'success' => true,
+                    'data' => [
+                        'summary_qty' => 1,
+                        'summary_text' => __(' item'),
+                        'subtotal' => 0,
+                    ],
+                ],
+            ],
+            [
+                '',
+                2,
+                [
+                    'subtotal' => $totalMock,
+                ],
+                [
+                    'success' => true,
+                    'data' => [
+                        'summary_qty' => 2,
+                        'summary_text' => __(' items'),
+                        'subtotal' => 12.34,
+                    ],
+                ],
+            ],
+            [
+                'Error',
+                0,
+                [],
+                [
+                    'success' => false,
+                    'error_message' => 'Error',
+                ],
+            ],
+        ];
+    }
+
+    public function testCheckQuoteItem()
+    {
+        $itemId = 1;
+
+        $itemMock = $this->getMockBuilder('Magento\Quote\Api\Data\CartItemInterface')
+            ->getMock();
+
+        $quoteMock = $this->getMockBuilder('Magento\Quote\Model\Quote')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $quoteMock->expects($this->once())
+            ->method('getItemById')
+            ->with($itemId)
+            ->willReturn($itemMock);
+
+        $this->cartMock->expects($this->any())
+            ->method('getQuote')
+            ->willReturn($quoteMock);
+
+        $this->assertEquals($this->sidebar, $this->sidebar->checkQuoteItem($itemId));
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\LocalizedException
+     * @exceptedExceptionMessage We can't find the quote item.
+     */
+    public function testCheckQuoteItemWithException()
+    {
+        $itemId = 2;
+
+        $quoteMock = $this->getMockBuilder('Magento\Quote\Model\Quote')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $quoteMock->expects($this->once())
+            ->method('getItemById')
+            ->with($itemId)
+            ->willReturn(null);
+
+        $this->cartMock->expects($this->any())
+            ->method('getQuote')
+            ->willReturn($quoteMock);
+
+        $this->sidebar->checkQuoteItem($itemId);
+    }
+
+    public function testRemoveQuoteItem()
+    {
+        $itemId = 1;
+
+        $this->cartMock->expects($this->once())
+            ->method('removeItem')
+            ->with($itemId)
+            ->willReturnSelf();
+        $this->cartMock->expects($this->once())
+            ->method('save')
+            ->willReturnSelf();
+
+        $this->assertEquals($this->sidebar, $this->sidebar->removeQuoteItem($itemId));
+    }
+
+    public function testUpdateQuoteItem()
+    {
+        $itemId = 1;
+        $itemQty = 2;
+
+        $this->resolverMock->expects($this->once())
+            ->method('getLocale')
+            ->willReturn('en');
+
+        $this->cartMock->expects($this->once())
+            ->method('updateItems')
+            ->with([$itemId => ['qty' => $itemQty]])
+            ->willReturnSelf();
+        $this->cartMock->expects($this->once())
+            ->method('save')
+            ->willReturnSelf();
+
+        $this->assertEquals($this->sidebar, $this->sidebar->updateQuoteItem($itemId, $itemQty));
+    }
+
+    public function testUpdateQuoteItemWithZeroQty()
+    {
+        $itemId = 1;
+        $itemQty = 0;
+
+        $this->resolverMock->expects($this->never())
+            ->method('getLocale');
+
+        $this->cartMock->expects($this->once())
+            ->method('updateItems')
+            ->with([$itemId => ['qty' => $itemQty]])
+            ->willReturnSelf();
+        $this->cartMock->expects($this->once())
+            ->method('save')
+            ->willReturnSelf();
+
+        $this->assertEquals($this->sidebar, $this->sidebar->updateQuoteItem($itemId, $itemQty));
+    }
+}
diff --git a/app/code/Magento/Checkout/composer.json b/app/code/Magento/Checkout/composer.json
index 6c15c5a46c36fabb60a805f4c8a2a8ca3bf0b75c..a92572b3680b6c80688bc383ec8b5f72ea1a0cde 100644
--- a/app/code/Magento/Checkout/composer.json
+++ b/app/code/Magento/Checkout/composer.json
@@ -3,31 +3,31 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta1",
-        "magento/module-sales": "0.74.0-beta1",
-        "magento/module-catalog-inventory": "0.74.0-beta1",
-        "magento/module-config": "0.74.0-beta1",
-        "magento/module-customer": "0.74.0-beta1",
-        "magento/module-catalog": "0.74.0-beta1",
-        "magento/module-payment": "0.74.0-beta1",
-        "magento/module-tax": "0.74.0-beta1",
-        "magento/module-directory": "0.74.0-beta1",
-        "magento/module-eav": "0.74.0-beta1",
-        "magento/module-gift-message": "0.74.0-beta1",
-        "magento/module-wishlist": "0.74.0-beta1",
-        "magento/module-page-cache": "0.74.0-beta1",
-        "magento/module-theme": "0.74.0-beta1",
-        "magento/module-msrp": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
-        "magento/module-ui": "0.74.0-beta1",
-        "magento/module-quote": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-sales": "0.74.0-beta2",
+        "magento/module-catalog-inventory": "0.74.0-beta2",
+        "magento/module-config": "0.74.0-beta2",
+        "magento/module-customer": "0.74.0-beta2",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/module-payment": "0.74.0-beta2",
+        "magento/module-tax": "0.74.0-beta2",
+        "magento/module-directory": "0.74.0-beta2",
+        "magento/module-eav": "0.74.0-beta2",
+        "magento/module-gift-message": "0.74.0-beta2",
+        "magento/module-wishlist": "0.74.0-beta2",
+        "magento/module-page-cache": "0.74.0-beta2",
+        "magento/module-theme": "0.74.0-beta2",
+        "magento/module-msrp": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
+        "magento/module-ui": "0.74.0-beta2",
+        "magento/module-quote": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "suggest": {
-        "magento/module-cookie": "0.74.0-beta1"
+        "magento/module-cookie": "0.74.0-beta2"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Checkout/etc/config.xml b/app/code/Magento/Checkout/etc/config.xml
index 31f59f6d891c5af880e55ec5d2dda30c5d26ab28..060d51932d09facdc524faa5e64d3a4032df9d90 100644
--- a/app/code/Magento/Checkout/etc/config.xml
+++ b/app/code/Magento/Checkout/etc/config.xml
@@ -21,7 +21,7 @@
             </cart_link>
             <sidebar>
                 <display>1</display>
-                <count>3</count>
+                <count>5</count>
             </sidebar>
             <payment_failed>
                 <identity>general</identity>
diff --git a/app/code/Magento/Checkout/view/frontend/layout/default.xml b/app/code/Magento/Checkout/view/frontend/layout/default.xml
index e563c4b56bf96830d92fcfd9f85dbcfe36143630..8fff222718790f074ae8935ce68923e51010f134 100644
--- a/app/code/Magento/Checkout/view/frontend/layout/default.xml
+++ b/app/code/Magento/Checkout/view/frontend/layout/default.xml
@@ -15,14 +15,17 @@
         </referenceBlock>
         <referenceContainer name="header-wrapper">
             <block class="Magento\Checkout\Block\Cart\Sidebar" name="minicart" as="minicart" after="logo" template="cart/minicart.phtml">
-                <block class="Magento\Framework\View\Element\RendererList" name="checkout.cart.sidebar.item.renderers" as="renderer.list"/>
-                <container name="minicart.subtotal.container" as="subtotal" label="My Cart Subtotal">
-                    <block name="minicart.subtotal" class="Magento\Checkout\Block\Cart\Sidebar" template="cart/subtotal.phtml"/>
-                </container>
-                <container name="minicart.extra.info" as="minicart_info" label="My Cart Extra info"/>
-                <container name="topCart.extra_actions" as="extra_actions" label="My Cart Extra Actions">
-                    <block class="Magento\Catalog\Block\ShortcutButtons" name="topCart.shortcut.buttons"/>
-                </container>
+                <block class="Magento\Checkout\Block\Cart\Sidebar" name="minicart.content" as="minicart_content" template="cart/minicart/content.phtml">
+                    <block class="Magento\Framework\View\Element\RendererList" name="checkout.cart.sidebar.item.renderers" as="renderer.list"/>
+                    <container name="minicart.subtotal.container" as="subtotal" label="My Cart Subtotal">
+                        <block name="minicart.subtotal" class="Magento\Checkout\Block\Cart\Sidebar" template="cart/subtotal.phtml"/>
+                    </container>
+                    <container name="minicart.promotion" as="cart_promotion" label="Mini-cart promotion block"/>
+                    <container name="minicart.extra.info" as="minicart_info" label="My Cart Extra info"/>
+                    <container name="topCart.extra_actions" as="extra_actions" label="My Cart Extra Actions">
+                        <block class="Magento\Catalog\Block\ShortcutButtons" name="topCart.shortcut.buttons"/>
+                    </container>
+                </block>
             </block>
         </referenceContainer>
     </body>
diff --git a/app/code/Magento/Checkout/view/frontend/templates/cart/minicart.phtml b/app/code/Magento/Checkout/view/frontend/templates/cart/minicart.phtml
index 355971348cbe9b8516d2f007cbda6da38b360d61..9082c7696e4e1217e5c38514bcf50f154bb7f8d4 100644
--- a/app/code/Magento/Checkout/view/frontend/templates/cart/minicart.phtml
+++ b/app/code/Magento/Checkout/view/frontend/templates/cart/minicart.phtml
@@ -8,104 +8,71 @@
 
 /** @var $block \Magento\Checkout\Block\Cart\Sidebar */
 ?>
-<?php if ($block->getInList()): ?>
-    <li data-block="minicart" class="minicart-wrapper">
-<?php else:  ?>
-    <div data-block="minicart" class="minicart-wrapper">
-<?php endif; ?>
+
 <?php $_cartQty = (float) $block->getSummaryCount() ?>
-<?php if (!$block->getIsLinkMode() || !$block->getIsNeedToDisplaySideBar()): ?>
-    <a class="action showcart" href="<?php echo $block->getUrl('checkout/cart'); ?>">
+<div data-block="minicart" class="minicart-wrapper">
+    <a class="action showcart" href="<?php echo $block->getShoppingCartUrl(); ?>">
         <span class="text"><?php echo __('My Cart'); ?></span>
         <span class="counter qty<?php echo($_cartQty > 0) ? '' : ' empty'; ?>">
             <span class="counter-number">
                 <?php echo $_cartQty;?>
             </span>
             <span class="counter-label">
-                <?php if ($_cartQty == 1):?>
-                    <?php echo __('item');?>
-                <?php else:?>
-                    <?php echo __('items');?>
-                <?php endif;?>
+                <?php echo $block->getSummaryText($_cartQty); ?>
             </span>
         </span>
     </a>
     <?php if ($block->getIsNeedToDisplaySideBar()): ?>
-        <div class="block block-minicart<?php echo($_cartQty > 0) ? '' : ' empty'; ?>" <?php if ($block->getIsNeedToDisplaySideBar()): ?> data-mage-init='{"dropdownDialog":{"appendTo":"[data-block=minicart]", "triggerTarget":".showcart", "timeout": "2000", "triggerClass":"active", "parentClass":"active"}}'<?php endif ?>>
-            <div class="title">
-                <strong>
-                    <span class="text"><?php echo __('My Cart'); ?></span>
-                    <span title="<?php echo __('Items in Cart'); ?>"
-                          class="qty<?php echo($_cartQty > 0) ? '' : ' empty'; ?>"
-                        ><?php echo $_cartQty ?></span>
-                </strong>
-            </div>
-            <div class="content">
-                <?php if ($_cartQty || $block->getAllowCartLink()): ?>
-                    <div class="items-total">
-                        <?php echo($_cartQty == 1) ? __('1 item ') : __('%1 items ', $_cartQty) ?>
-                    </div>
-                    <?php $isPossibleOnepageCheckout = $_cartQty && $block->isPossibleOnepageCheckout() ?>
-                    <?php if ($isPossibleOnepageCheckout): ?>
-                        <?php echo $block->getChildHtml('subtotal'); ?>
-                    <?php endif; ?>
-                    <?php echo $block->getChildHtml('minicart_info') ?>
-                    <div class="actions">
-                        <div class="primary">
-                            <?php if ($isPossibleOnepageCheckout): ?>
-                                <button
-                                    id="top-cart-btn-checkout"
-                                    type="button"
-                                    class="action checkout primary"
-                                    title="<?php echo __('Go to Checkout') ?>">
-                                    <span><?php echo __('Go to Checkout') ?></span>
-                                </button>
-                                <?php echo $block->getChildHtml('extra_actions') ?>
-                            <?php endif; ?>
-                        </div>
-                        <div class="secondary">
-                            <a class="action viewcart" href="<?php echo $block->getUrl('checkout/cart'); ?>">
-                                <span><?php echo __('Go to Shopping Cart') ?></span>
-                            </a>
-                        </div>
-                    </div>
-                <?php endif ?>
-                <?php $_items = $block->getRecentItems() ?>
-                <?php if (count($_items)): ?>
-                    <strong class="subtitle"><?php echo __('Recently added item(s)') ?></strong>
-                    <div data-action="scroll" class="products minilist">
-                        <ol id="mini-cart" class="minilist items">
-                            <?php foreach ($_items as $_item): ?>
-                            <?php echo $block->getItemHtml($_item) ?>
-                            <?php endforeach; ?>
-                        </ol>
-                    </div>
-                <?php else: ?>
-                    <strong class="subtitle empty">
-                        <?php echo __('You have no items in your shopping cart.') ?>
-                    </strong>
-                    <?php if ($block->getCartEmptyMessage()): ?>
-                        <p class="minicart empty text"><?php echo $block->getCartEmptyMessage(); ?></p>
-                    <?php endif; ?>
-                <?php endif ?>
+        <div class="block block-minicart<?php echo($_cartQty > 0) ? '' : ' empty'; ?>"
+             data-mage-init='{"dropdownDialog":{
+                "appendTo":"[data-block=minicart]",
+                "triggerTarget":".showcart",
+                "timeout": "2000",
+                "closeOnMouseLeave": false,
+                "closeOnEscape": true,
+                "triggerClass":"active",
+                "parentClass":"active",
+                "buttons":[]}}'>
+            <div id="minicart-content-wrapper">
+                <?php echo $block->getChildHtml('minicart_content') ?>
             </div>
         </div>
     <?php endif ?>
-<?php endif; ?>
-<script type="text/x-magento-init">
+    <script type="text/x-magento-init">
     {
         "[data-block='minicart']": {
             "sidebar": {
-                "checkoutUrl": "<?php echo $block->getCheckoutUrl();?>",
-                "checkoutButton": "#top-cart-btn-checkout",
-                "removeButton": "#mini-cart a.action.delete",
+                "targetElement": "div.block.block-minicart",
+                "url": {
+                    "checkout": "<?php echo $block->getCheckoutUrl();?>",
+                    "update": "<?php echo $block->getUpdateItemQtyUrl(); ?>",
+                    "remove": "<?php echo $block->getRemoveItemUrl(); ?>"
+                },
+                "button": {
+                    "checkout": "#top-cart-btn-checkout",
+                    "remove": "#mini-cart a.action.delete",
+                    "close": "#btn-minicart-close"
+                },
+                "showcart": {
+                    "parent": "span.counter",
+                    "qty": "span.counter-number",
+                    "label": "span.counter-label"
+                },
+                "minicart": {
+                    "list": "#mini-cart",
+                    "content": "#minicart-content-wrapper",
+                    "qty": "div.items-total",
+                    "subtotal": "div.subtotal span.price"
+                },
+                "item": {
+                    "qty": ":input.cart-item-qty",
+                    "button": ":button.update-cart-item"
+                },
                 "confirmMessage": "<?php echo __('Are you sure you would like to remove this item from the shopping cart?') ?>"
             }
         }
     }
-</script>
-<?php if ($block->getInList()): ?>
-    </li>
-<?php else:  ?>
-    </div>
-<?php endif; ?>
+    </script>
+</div>
+
+
diff --git a/app/code/Magento/Checkout/view/frontend/templates/cart/minicart/content.phtml b/app/code/Magento/Checkout/view/frontend/templates/cart/minicart/content.phtml
new file mode 100644
index 0000000000000000000000000000000000000000..ac59b9dce84a0ff7b5584db0b7a99e7d6fed28c3
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/templates/cart/minicart/content.phtml
@@ -0,0 +1,87 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+// @codingStandardsIgnoreFile
+
+/** @var $block \Magento\Checkout\Block\Cart\Sidebar */
+?>
+
+<?php $_cartQty = (float) $block->getSummaryCount() ?>
+<div class="block-title">
+    <strong>
+        <span class="text"><?php echo __('My Cart'); ?></span>
+                    <span title="<?php echo $block->escapeHtml(__('Items in Cart')); ?>"
+                          class="qty<?php echo($_cartQty > 0) ? '' : ' empty'; ?>"
+                        ><?php echo $_cartQty ?></span>
+    </strong>
+</div>
+<div class="block-content">
+    <button type="button"
+            id="btn-minicart-close"
+            title="<?php echo $block->escapeHtml(__('Close')); ?>"
+            class="action close">
+        <span><?php echo __('Close') ?></span>
+    </button>
+
+    <?php if ($_cartQty || $block->getAllowCartLink()): ?>
+        <div class="items-total">
+            <span class="count"><?php echo $_cartQty; ?></span>
+            <?php echo $block->getSummaryText($_cartQty); ?>
+        </div>
+        <?php $isPossibleOnepageCheckout = $_cartQty && $block->isPossibleOnepageCheckout() ?>
+        <?php if ($isPossibleOnepageCheckout): ?>
+            <?php echo $block->getChildHtml('subtotal'); ?>
+        <?php endif; ?>
+        <?php echo $block->getChildHtml('minicart_info') ?>
+        <div class="actions">
+            <div class="primary">
+                <?php if ($isPossibleOnepageCheckout): ?>
+                    <button
+                        id="top-cart-btn-checkout"
+                        type="button"
+                        class="action primary checkout"
+                        title="<?php echo $block->escapeHtml(__('Go to Checkout')); ?>">
+                        <span><?php echo __('Go to Checkout') ?></span>
+                    </button>
+                    <?php echo $block->getChildHtml('extra_actions') ?>
+                <?php endif; ?>
+            </div>
+        </div>
+    <?php endif ?>
+
+    <?php $_items = $block->getRecentItems() ?>
+    <?php if (count($_items)): ?>
+        <strong class="subtitle"><?php echo __('Recently added item(s)') ?></strong>
+        <div data-action="scroll" class="minicart-items-wrapper">
+            <ol id="mini-cart" class="minicart-items">
+                <?php foreach ($_items as $_item): ?>
+                    <?php echo $block->getItemHtml($_item) ?>
+                <?php endforeach; ?>
+            </ol>
+        </div>
+    <?php else: ?>
+        <strong class="subtitle empty">
+            <?php echo __('You have no items in your shopping cart.') ?>
+        </strong>
+        <?php if ($block->getCartEmptyMessage()): ?>
+            <p class="minicart empty text"><?php echo $block->getCartEmptyMessage(); ?></p>
+        <?php endif; ?>
+    <?php endif ?>
+
+    <?php if ($_cartQty || $block->getAllowCartLink()): ?>
+        <div class="actions">
+            <div class="secondary">
+                <a class="action viewcart" href="<?php echo $block->getUrl('checkout/cart'); ?>">
+                    <span><?php echo __('View and edit cart') ?></span>
+                </a>
+            </div>
+        </div>
+    <?php endif ?>
+
+    <div id="minicart-widgets" class="minicart-widgets">
+        <?php echo $block->getChildHtml('cart_promotion') ?>
+    </div>
+</div>
diff --git a/app/code/Magento/Checkout/view/frontend/templates/cart/sidebar/default.phtml b/app/code/Magento/Checkout/view/frontend/templates/cart/sidebar/default.phtml
index 826cc8efac19b814a976cca84a512d30b3c1a454..5a5d1cba87399286e052eab523e4c514cfc76ec7 100644
--- a/app/code/Magento/Checkout/view/frontend/templates/cart/sidebar/default.phtml
+++ b/app/code/Magento/Checkout/view/frontend/templates/cart/sidebar/default.phtml
@@ -75,9 +75,23 @@ $imageBlock = $block->getLayout()->createBlock('Magento\Catalog\Block\Product\Im
                     <?php echo $block->getSidebarItemPriceHtml($_item); ?>
                 <?php endif; //Can apply MSRP ?>
 
-                <div class="details-qty">
+                <div class="details-qty qty">
                     <span class="label"><?php echo __('Qty'); ?></span>
-                    <span class="value qty"><?php echo $block->getQty() ?></span>
+                    <input id="cart-item-<?php echo $_item->getId() ?>-qty"
+                           value="<?php echo $block->getQty() ?>"
+                           type="number"
+                           size="4"
+                           class="item-qty cart-item-qty"
+                           data-cart-item="<?php echo $_item->getId() ?>"
+                           data-item-qty="<?php echo $block->getQty() ?>"
+                           maxlength="12"/>
+                    <button id="update-cart-item-<?php echo $_item->getId() ?>"
+                            class="update-cart-item"
+                            data-cart-item="<?php echo $_item->getId() ?>"
+                            title="<?php echo $block->escapeHtml(__('Update')); ?>"
+                            style="display: none">
+                        <span><?php echo __('Update'); ?></span>
+                    </button>
                 </div>
             </div>
 
@@ -85,12 +99,17 @@ $imageBlock = $block->getLayout()->createBlock('Magento\Catalog\Block\Product\Im
                 <?php if ($product->isVisibleInSiteVisibility()):?>
                 <div class="primary">
                     <a href="<?php echo $block->getConfigureUrl() ?>"
-                       title="<?php echo __('Edit item') ?>"
-                       class="action edit"><span><?php echo __('Edit')?></span></a>
+                       title="<?php echo $block->escapeHtml(__('Edit item')); ?>"
+                       class="action edit">
+                       <span><?php echo __('Edit')?></span>
+                   </a>
                 </div>
                 <?php endif ?>
                 <div class="secondary">
-                    <a href="#" data-post='<?php echo $this->helper('Magento\Checkout\Helper\Cart')->getDeletePostJson($_item); ?>' title="<?php echo __('Remove item') ?>" class="action delete">
+                    <a href="#"
+                       data-cart-item="<?php echo $_item->getId() ?>"
+                       title="<?php echo $block->escapeHtml(__('Remove item')); ?>"
+                       class="action delete">
                         <span><?php echo __('Remove')?></span>
                     </a>
                 </div>
diff --git a/app/code/Magento/Checkout/view/frontend/templates/cart/subtotal.phtml b/app/code/Magento/Checkout/view/frontend/templates/cart/subtotal.phtml
index 34e8b3922671cebd25915227a7e2459532045246..291a8a762fe899ffeb9726aa6d2ab8043fad0339 100644
--- a/app/code/Magento/Checkout/view/frontend/templates/cart/subtotal.phtml
+++ b/app/code/Magento/Checkout/view/frontend/templates/cart/subtotal.phtml
@@ -6,7 +6,7 @@
 /** @var $block \Magento\Checkout\Block\Cart\Sidebar */
 ?>
 <div class="subtotal">
-    <span class="mark">
+    <span class="label">
         <?php echo __('Cart Subtotal') ?>
     </span>
     <?php echo $block->getTotalsHtml() ?>
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 59e5f2e35d81022aa4bef3e624713d5d8ff91396..d3c3a264b88d814fd8123aa84bc1df10d3828aa6 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js
@@ -12,18 +12,242 @@ define([
 
     $.widget('mage.sidebar', {
         options: {
-            isRecursive: true
+            isRecursive: true,
+            maxItemsVisible: 3
         },
+        scrollHeight: 0,
+
         _create: function() {
+            this._initContent();
+        },
+
+        _initContent: function() {
+            var self = this;
+
             this.element.decorate('list', this.options.isRecursive);
-            $(this.options.checkoutButton).on('click', $.proxy(function() {
-                location.href = this.options.checkoutUrl;
-            }, this));
-            $(this.options.removeButton).on('click', $.proxy(function() {
-                return confirm(this.options.confirmMessage);
+
+            $(this.options.button.close).click(function(event) {
+                event.stopPropagation();
+                $(self.options.targetElement).dropdownDialog("close");
+            });
+
+            $(this.options.button.checkout).on('click', $.proxy(function() {
+                location.href = this.options.url.checkout;
             }, this));
+
+            $(this.options.button.remove).click(function(event) {
+                event.stopPropagation();
+                if (confirm(self.options.confirmMessage)) {
+                    self._removeItem($(this));
+                }
+            });
+
+            $(this.options.item.qty).keyup(function() {
+                self._showItemButton($(this));
+            });
+            $(this.options.item.button).click(function(event) {
+                event.stopPropagation();
+                self._updateItemQty($(this))
+            });
+
+            this._calcHeight();
+            this._isOverflowed();
+        },
+
+        /**
+         * Add 'overflowed' class to minicart items wrapper element
+         *
+         * @private
+         */
+        _isOverflowed: function() {
+            var list = $(this.options.minicart.list);
+            if (this.scrollHeight > list.innerHeight()) {
+                list.parent().addClass('overflowed');
+            } else {
+                list.parent().removeClass('overflowed');
+            }
+        },
+
+        _showItemButton: function(elem) {
+            var itemId = elem.data('cart-item');
+            var itemQty = elem.data('item-qty');
+            if (this._isValidQty(itemQty, elem.val())) {
+                $('#update-cart-item-' + itemId).show('fade', 300);
+            } else if (elem.val() == 0) {
+                elem.val(itemQty);
+                this._hideItemButton(elem);
+            } else {
+                this._hideItemButton(elem);
+            }
+        },
+
+        /**
+         * @param origin - origin qty. 'data-item-qty' attribute.
+         * @param changed - new qty.
+         * @returns {boolean}
+         * @private
+         */
+        _isValidQty: function(origin, changed) {
+            return (origin != changed)
+                && (changed.length > 0)
+                && (changed - 0 == changed)
+                && (changed - 0 > 0);
+        },
+
+        _hideItemButton: function(elem) {
+            var itemId = elem.data('cart-item');
+            $('#update-cart-item-' + itemId).hide('fade', 300);
+        },
+
+        _updateItemQty: function(elem) {
+            var itemId = elem.data('cart-item');
+            this._ajax(this.options.url.update, {
+                item_id: itemId,
+                item_qty: $('#cart-item-' + itemId + '-qty').val()
+            }, elem, this._updateItemQtyAfter);
+        },
+
+        /**
+         * Update content after update qty
+         *
+         * @param elem
+         * @param response
+         * @private
+         */
+        _updateItemQtyAfter: function(elem, response) {
+            if ($.type(response.data) === 'object') {
+                this._refreshQty(response.data.summary_qty, response.data.summary_text);
+                this._refreshSubtotal(response.data.subtotal);
+                this._refreshShowcart(response.data.summary_qty, response.data.summary_text);
+                this._refreshItemQty(elem, response.data.summary_qty);
+            }
+            this._hideItemButton(elem);
+        },
+
+        _removeItem: function(elem) {
+            var itemId = elem.data('cart-item');
+            this._ajax(this.options.url.remove, {
+                item_id: itemId
+            }, elem, this._removeItemAfter);
+        },
+
+        /**
+         * Update content after item remove
+         *
+         * @param elem
+         * @param response
+         * @private
+         */
+        _removeItemAfter: function(elem, response) {
+            if ($.type(response.data) === 'object') {
+                this._refreshShowcart(response.data.summary_qty, response.data.summary_text);
+            }
+            $(this.options.minicart.content).html($.trim(response.content));
+            if (response.cleanup === true) {
+                $(this.options.showcart.parent).addClass('empty');
+            }
+            this._initContent();
+        },
+
+        /**
+         * @param url - ajax url
+         * @param data - post data for ajax call
+         * @param elem - element that initiated the event
+         * @param callback - callback method to execute after AJAX success
+         */
+        _ajax: function(url, data, elem, callback) {
+            $.ajax({
+                url: url,
+                data: data,
+                type: 'post',
+                dataType: 'json',
+                context: this,
+                beforeSend: function() {
+                    elem.attr('disabled', 'disabled');
+                },
+                complete: function() {
+                    elem.attr('disabled', null);
+                }
+            })
+                .done(function(response) {
+                    if (response.success) {
+                        callback.call(this, elem, response);
+                    } else {
+                        var msg = response.error_message;
+                        if (msg) {
+                            window.alert($.mage.__(msg));
+                        }
+                    }
+                })
+                .fail(function(error) {
+                    console.log(JSON.stringify(error));
+                });
+        },
+
+        _refreshItemQty: function(elem, qty) {
+            if (qty != undefined) {
+                var itemId = elem.data('cart-item');
+                $('#cart-item-' + itemId + '-qty').data('item-qty', qty);
+            }
+        },
+
+        _refreshQty: function(qty, text) {
+            if (qty != undefined && text != undefined) {
+                var self = this;
+                $(this.options.minicart.qty).fadeOut('slow', function() {
+                    $(self.options.minicart.qty).html('<span class="count">' + qty + '</span>' + text);
+                }).fadeIn();
+            }
+        },
+
+        _refreshSubtotal: function(val) {
+            if (val != undefined) {
+                var self = this;
+                $(this.options.minicart.subtotal).fadeOut('slow', function() {
+                    $(self.options.minicart.subtotal).replaceWith(val);
+                }).fadeIn();
+            }
+        },
+
+        _refreshShowcart: function(qty, text) {
+            if (qty != undefined && text != undefined) {
+                var self = this;
+                $(this.options.showcart.qty).fadeOut('slow', function() {
+                    $(self.options.showcart.qty).text(qty);
+                }).fadeIn();
+                $(this.options.showcart.label).fadeOut('slow', function() {
+                    $(self.options.showcart.label).text(text);
+                }).fadeIn();
+            }
+        },
+
+        /**
+         * Calculate height of minicart list
+         *
+         * @private
+         */
+        _calcHeight: function() {
+            var self = this,
+                height = 0,
+                counter = this.options.maxItemsVisible,
+                target = $(this.options.minicart.list)
+                    .clone()
+                    .attr('style', 'position: absolute !important; top: -10000 !important;')
+                    .appendTo('body');
+
+            this.scrollHeight = 0;
+            target.children().each(function() {
+                if (counter-- > 0) {
+                    height += $(this).height() - 15;
+                }
+                self.scrollHeight += $(this).height() - 15;
+            });
+
+            target.remove();
+
+            $(this.options.minicart.list).css('height', height);
         }
     });
 
     return $.mage.sidebar;
-});
\ No newline at end of file
+});
diff --git a/app/code/Magento/CheckoutAgreements/composer.json b/app/code/Magento/CheckoutAgreements/composer.json
index 1597afb38007873a927009646947de57b7408854..564eb787401ac173b467a9dc1a741c80188af697 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-beta1",
-        "magento/module-store": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-checkout": "0.74.0-beta2",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Cms/Api/BlockRepositoryInterface.php b/app/code/Magento/Cms/Api/BlockRepositoryInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..e9834b821a66be6531ecfcce99fe1800a38f62f7
--- /dev/null
+++ b/app/code/Magento/Cms/Api/BlockRepositoryInterface.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Cms\Api;
+
+use Magento\Framework\Api\SearchCriteriaInterface;
+
+/**
+ * CMS block CRUD interface.
+ */
+interface BlockRepositoryInterface
+{
+    /**
+     * Save block.
+     *
+     * @param Data\BlockInterface $block
+     * @return Data\BlockInterface
+     * @throws \Magento\Framework\Exception\LocalizedException
+     */
+    public function save(Data\BlockInterface $block);
+
+    /**
+     * Retrieve block.
+     *
+     * @param int $blockId
+     * @return Data\BlockInterface
+     * @throws \Magento\Framework\Exception\LocalizedException
+     */
+    public function getById($blockId);
+
+    /**
+     * Retrieve blocks matching the specified criteria.
+     *
+     * @param SearchCriteriaInterface $searchCriteria
+     * @return \Magento\Framework\Api\SearchResultsInterface
+     * @throws \Magento\Framework\Exception\LocalizedException
+     */
+    public function getList(SearchCriteriaInterface $searchCriteria);
+
+    /**
+     * Delete block.
+     *
+     * @param Data\BlockInterface $block
+     * @return bool true on success
+     * @throws \Magento\Framework\Exception\LocalizedException
+     */
+    public function delete(Data\BlockInterface $block);
+
+    /**
+     * Delete block by ID.
+     *
+     * @param int $blockId
+     * @return bool true on success
+     * @throws \Magento\Framework\Exception\NoSuchEntityException
+     * @throws \Magento\Framework\Exception\LocalizedException
+     */
+    public function deleteById($blockId);
+}
diff --git a/app/code/Magento/Cms/Api/Data/BlockInterface.php b/app/code/Magento/Cms/Api/Data/BlockInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..d26f46cda2fb2cfe337413133be03785dfbbbbfa
--- /dev/null
+++ b/app/code/Magento/Cms/Api/Data/BlockInterface.php
@@ -0,0 +1,129 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Cms\Api\Data;
+
+/**
+ * CMS block interface.
+ */
+interface BlockInterface
+{
+    /**#@+
+     * Constants for keys of data array. Identical to the name of the getter in snake case
+     */
+    const BLOCK_ID      = 'block_id';
+    const IDENTIFIER    = 'identifier';
+    const TITLE         = 'title';
+    const CONTENT       = 'content';
+    const CREATION_TIME = 'creation_time';
+    const UPDATE_TIME   = 'update_time';
+    const IS_ACTIVE     = 'is_active';
+    /**#@-*/
+
+    /**
+     * Get ID
+     *
+     * @return int
+     */
+    public function getId();
+
+    /**
+     * Get identifier
+     *
+     * @return string
+     */
+    public function getIdentifier();
+
+    /**
+     * Get title
+     *
+     * @return string
+     */
+    public function getTitle();
+
+    /**
+     * Get content
+     *
+     * @return string
+     */
+    public function getContent();
+
+    /**
+     * Get creation time
+     *
+     * @return string
+     */
+    public function getCreationTime();
+
+    /**
+     * Get update time
+     *
+     * @return string
+     */
+    public function getUpdateTime();
+
+    /**
+     * Is active
+     *
+     * @return bool
+     */
+    public function isActive();
+
+    /**
+     * Set ID
+     *
+     * @param int $id
+     * @return BlockInterface
+     */
+    public function setId($id);
+
+    /**
+     * Set identifier
+     *
+     * @param string $identifier
+     * @return BlockInterface
+     */
+    public function setIdentifier($identifier);
+
+    /**
+     * Set title
+     *
+     * @param string $title
+     * @return BlockInterface
+     */
+    public function setTitle($title);
+
+    /**
+     * Set content
+     *
+     * @param string $content
+     * @return BlockInterface
+     */
+    public function setContent($content);
+
+    /**
+     * Set creation time
+     *
+     * @param string $creationTime
+     * @return BlockInterface
+     */
+    public function setCreationTime($creationTime);
+
+    /**
+     * Set update time
+     *
+     * @param string $updateTime
+     * @return BlockInterface
+     */
+    public function setUpdateTime($updateTime);
+
+    /**
+     * Set is active
+     *
+     * @param bool|int $isActive
+     * @return BlockInterface
+     */
+    public function setIsActive($isActive);
+}
diff --git a/app/code/Magento/Cms/Api/Data/BlockSearchResultsInterface.php b/app/code/Magento/Cms/Api/Data/BlockSearchResultsInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..715790c17343691226d8020f45ae896aee4eb5df
--- /dev/null
+++ b/app/code/Magento/Cms/Api/Data/BlockSearchResultsInterface.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Cms\Api\Data;
+
+use Magento\Framework\Api\SearchResultsInterface;
+
+/**
+ * Interface for cms block search results.
+ */
+interface BlockSearchResultsInterface extends SearchResultsInterface
+{
+    /**
+     * Get blocks list.
+     *
+     * @return \Magento\Cms\Api\Data\BlockInterface[]
+     */
+    public function getItems();
+
+    /**
+     * Set blocks list.
+     *
+     * @param \Magento\Cms\Api\Data\BlockInterface[] $items
+     * @return $this
+     */
+    public function setItems(array $items = null);
+}
diff --git a/app/code/Magento/Cms/Api/Data/PageInterface.php b/app/code/Magento/Cms/Api/Data/PageInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..8e03d0ed1ffde5e14a18ae2effb77062b508ffcf
--- /dev/null
+++ b/app/code/Magento/Cms/Api/Data/PageInterface.php
@@ -0,0 +1,305 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Cms\Api\Data;
+
+/**
+ * CMS page interface.
+ */
+interface PageInterface
+{
+    /**#@+
+     * Constants for keys of data array. Identical to the name of the getter in snake case
+     */
+    const PAGE_ID                  = 'page_id';
+    const IDENTIFIER               = 'identifier';
+    const TITLE                    = 'title';
+    const PAGE_LAYOUT              = 'page_layout';
+    const META_KEYWORDS            = 'meta_keywords';
+    const META_DESCRIPTION         = 'meta_description';
+    const CONTENT_HEADING          = 'content_heading';
+    const CONTENT                  = 'content';
+    const CREATION_TIME            = 'creation_time';
+    const UPDATE_TIME              = 'update_time';
+    const SORT_ORDER               = 'sort_order';
+    const LAYOUT_UPDATE_XML        = 'layout_update_xml';
+    const CUSTOM_THEME             = 'custom_theme';
+    const CUSTOM_ROOT_TEMPLATE     = 'custom_root_template';
+    const CUSTOM_LAYOUT_UPDATE_XML = 'custom_layout_update_xml';
+    const CUSTOM_THEME_FROM        = 'custom_theme_from';
+    const CUSTOM_THEME_TO          = 'custom_theme_to';
+    const IS_ACTIVE                = 'is_active';
+    /**#@-*/
+
+    /**
+     * Get ID
+     *
+     * @return int
+     */
+    public function getId();
+
+    /**
+     * Get identifier
+     *
+     * @return string
+     */
+    public function getIdentifier();
+
+    /**
+     * Get title
+     *
+     * @return string
+     */
+    public function getTitle();
+
+    /**
+     * Get page layout
+     *
+     * @return string
+     */
+    public function getPageLayout();
+
+    /**
+     * Get meta keywords
+     *
+     * @return string
+     */
+    public function getMetaKeywords();
+
+    /**
+     * Get meta description
+     *
+     * @return string
+     */
+    public function getMetaDescription();
+
+    /**
+     * Get content heading
+     *
+     * @return string
+     */
+    public function getContentHeading();
+
+    /**
+     * Get content
+     *
+     * @return string
+     */
+    public function getContent();
+
+    /**
+     * Get creation time
+     *
+     * @return string
+     */
+    public function getCreationTime();
+
+    /**
+     * Get update time
+     *
+     * @return string
+     */
+    public function getUpdateTime();
+
+    /**
+     * Get sort order
+     *
+     * @return string
+     */
+    public function getSortOrder();
+
+    /**
+     * Get layout update xml
+     *
+     * @return string
+     */
+    public function getLayoutUpdateXml();
+
+    /**
+     * Get custom theme
+     *
+     * @return string
+     */
+    public function getCustomTheme();
+
+    /**
+     * Get custom root template
+     *
+     * @return string
+     */
+    public function getCustomRootTemplate();
+
+    /**
+     * Get custom layout update xml
+     *
+     * @return string
+     */
+    public function getCustomLayoutUpdateXml();
+
+    /**
+     * Get custom theme from
+     *
+     * @return string
+     */
+    public function getCustomThemeFrom();
+
+    /**
+     * Get custom theme to
+     *
+     * @return string
+     */
+    public function getCustomThemeTo();
+
+    /**
+     * Is active
+     *
+     * @return bool
+     */
+    public function isActive();
+
+    /**
+     * Set ID
+     *
+     * @param int $id
+     * @return \Magento\Cms\Api\Data\PageInterface
+     */
+    public function setId($id);
+
+    /**
+     * Set identifier
+     *
+     * @param string $identifier
+     * @return \Magento\Cms\Api\Data\PageInterface
+     */
+    public function setIdentifier($identifier);
+
+    /**
+     * Set title
+     *
+     * @param string $title
+     * @return \Magento\Cms\Api\Data\PageInterface
+     */
+    public function setTitle($title);
+
+    /**
+     * Set page layout
+     *
+     * @param string $pageLayout
+     * @return \Magento\Cms\Api\Data\PageInterface
+     */
+    public function setPageLayout($pageLayout);
+
+    /**
+     * Set meta keywords
+     *
+     * @param string $metaKeywords
+     * @return \Magento\Cms\Api\Data\PageInterface
+     */
+    public function setMetaKeywords($metaKeywords);
+
+    /**
+     * Set meta description
+     *
+     * @param string $metaDescription
+     * @return \Magento\Cms\Api\Data\PageInterface
+     */
+    public function setMetaDescription($metaDescription);
+
+    /**
+     * Set content heading
+     *
+     * @param string $contentHeading
+     * @return \Magento\Cms\Api\Data\PageInterface
+     */
+    public function setContentHeading($contentHeading);
+
+    /**
+     * Set content
+     *
+     * @param string $content
+     * @return \Magento\Cms\Api\Data\PageInterface
+     */
+    public function setContent($content);
+
+    /**
+     * Set creation time
+     *
+     * @param string $creationTime
+     * @return \Magento\Cms\Api\Data\PageInterface
+     */
+    public function setCreationTime($creationTime);
+
+    /**
+     * Set update time
+     *
+     * @param string $updateTime
+     * @return \Magento\Cms\Api\Data\PageInterface
+     */
+    public function setUpdateTime($updateTime);
+
+    /**
+     * Set sort order
+     *
+     * @param string $sortOrder
+     * @return \Magento\Cms\Api\Data\PageInterface
+     */
+    public function setSortOrder($sortOrder);
+
+    /**
+     * Set layout update xml
+     *
+     * @param string $layoutUpdateXml
+     * @return \Magento\Cms\Api\Data\PageInterface
+     */
+    public function setLayoutUpdateXml($layoutUpdateXml);
+
+    /**
+     * Set custom theme
+     *
+     * @param string $customTheme
+     * @return \Magento\Cms\Api\Data\PageInterface
+     */
+    public function setCustomTheme($customTheme);
+
+    /**
+     * Set custom root template
+     *
+     * @param string $customRootTemplate
+     * @return \Magento\Cms\Api\Data\PageInterface
+     */
+    public function setCustomRootTemplate($customRootTemplate);
+
+    /**
+     * Set custom layout update xml
+     *
+     * @param string $customLayoutUpdateXml
+     * @return \Magento\Cms\Api\Data\PageInterface
+     */
+    public function setCustomLayoutUpdateXml($customLayoutUpdateXml);
+
+    /**
+     * Set custom theme from
+     *
+     * @param string $customThemeFrom
+     * @return \Magento\Cms\Api\Data\PageInterface
+     */
+    public function setCustomThemeFrom($customThemeFrom);
+
+    /**
+     * Set custom theme to
+     *
+     * @param string $customThemeTo
+     * @return \Magento\Cms\Api\Data\PageInterface
+     */
+    public function setCustomThemeTo($customThemeTo);
+
+    /**
+     * Set is active
+     *
+     * @param int|bool $isActive
+     * @return \Magento\Cms\Api\Data\PageInterface
+     */
+    public function setIsActive($isActive);
+}
diff --git a/app/code/Magento/Cms/Api/Data/PageSearchResultsInterface.php b/app/code/Magento/Cms/Api/Data/PageSearchResultsInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..160d93d172c214ecba5dd13e4e482cc4754772c6
--- /dev/null
+++ b/app/code/Magento/Cms/Api/Data/PageSearchResultsInterface.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Cms\Api\Data;
+
+use Magento\Framework\Api\SearchResultsInterface;
+
+/**
+ * Interface for cms page search results.
+ */
+interface PageSearchResultsInterface extends SearchResultsInterface
+{
+    /**
+     * Get pages list.
+     *
+     * @return \Magento\Cms\Api\Data\PageInterface[]
+     */
+    public function getItems();
+
+    /**
+     * Set pages list.
+     *
+     * @param \Magento\Cms\Api\Data\PageInterface[] $items
+     * @return $this
+     */
+    public function setItems(array $items = null);
+}
diff --git a/app/code/Magento/Cms/Api/PageRepositoryInterface.php b/app/code/Magento/Cms/Api/PageRepositoryInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..9dcf95d572fd533036999b4863bd1240ed7ad30e
--- /dev/null
+++ b/app/code/Magento/Cms/Api/PageRepositoryInterface.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Cms\Api;
+
+use Magento\Framework\Api\SearchCriteriaInterface;
+
+/**
+ * CMS page CRUD interface.
+ */
+interface PageRepositoryInterface
+{
+    /**
+     * Save page.
+     *
+     * @param Data\PageInterface $page
+     * @return Data\PageInterface
+     * @throws \Magento\Framework\Exception\LocalizedException
+     */
+    public function save(Data\PageInterface $page);
+
+    /**
+     * Retrieve page.
+     *
+     * @param int $pageId
+     * @return Data\PageInterface
+     * @throws \Magento\Framework\Exception\LocalizedException
+     */
+    public function getById($pageId);
+
+    /**
+     * Retrieve pages matching the specified criteria.
+     *
+     * @param SearchCriteriaInterface $searchCriteria
+     * @return \Magento\Framework\Api\SearchResultsInterface
+     * @throws \Magento\Framework\Exception\LocalizedException
+     */
+    public function getList(SearchCriteriaInterface $searchCriteria);
+
+    /**
+     * Delete page.
+     *
+     * @param Data\PageInterface $page
+     * @return bool true on success
+     * @throws \Magento\Framework\Exception\LocalizedException
+     */
+    public function delete(Data\PageInterface $page);
+
+    /**
+     * Delete page by ID.
+     *
+     * @param int $pageId
+     * @return bool true on success
+     * @throws \Magento\Framework\Exception\NoSuchEntityException
+     * @throws \Magento\Framework\Exception\LocalizedException
+     */
+    public function deleteById($pageId);
+}
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 93f8f338149a480ebb4502291daaa7a538263099..fed2f67da6f177806559e463deb8fda56a2fbb3f 100644
--- a/app/code/Magento/Cms/Block/Adminhtml/Block/Widget/Chooser.php
+++ b/app/code/Magento/Cms/Block/Adminhtml/Block/Widget/Chooser.php
@@ -16,7 +16,7 @@ class Chooser extends \Magento\Backend\Block\Widget\Grid\Extended
     protected $_blockFactory;
 
     /**
-     * @var \Magento\Cms\Model\Resource\Block\Grid\CollectionFactory
+     * @var \Magento\Cms\Model\Resource\Block\CollectionFactory
      */
     protected $_collectionFactory;
 
@@ -24,14 +24,14 @@ class Chooser extends \Magento\Backend\Block\Widget\Grid\Extended
      * @param \Magento\Backend\Block\Template\Context $context
      * @param \Magento\Backend\Helper\Data $backendHelper
      * @param \Magento\Cms\Model\BlockFactory $blockFactory
-     * @param \Magento\Cms\Model\Resource\Block\Grid\CollectionFactory $collectionFactory
+     * @param \Magento\Cms\Model\Resource\Block\CollectionFactory $collectionFactory
      * @param array $data
      */
     public function __construct(
         \Magento\Backend\Block\Template\Context $context,
         \Magento\Backend\Helper\Data $backendHelper,
         \Magento\Cms\Model\BlockFactory $blockFactory,
-        \Magento\Cms\Model\Resource\Block\Grid\CollectionFactory $collectionFactory,
+        \Magento\Cms\Model\Resource\Block\CollectionFactory $collectionFactory,
         array $data = []
     ) {
         $this->_blockFactory = $blockFactory;
diff --git a/app/code/Magento/Cms/Block/Adminhtml/Page/Grid.php b/app/code/Magento/Cms/Block/Adminhtml/Page/Grid.php
index 0580ceeaeb0d16706547ec6831b197c142e1cd27..af9f8d533c2d87e95e8fbcbd8a205f2dcec7e873 100644
--- a/app/code/Magento/Cms/Block/Adminhtml/Page/Grid.php
+++ b/app/code/Magento/Cms/Block/Adminhtml/Page/Grid.php
@@ -11,7 +11,7 @@ namespace Magento\Cms\Block\Adminhtml\Page;
 class Grid extends \Magento\Backend\Block\Widget\Grid\Extended
 {
     /**
-     * @var \Magento\Cms\Model\Resource\Page\Grid\CollectionFactory
+     * @var \Magento\Cms\Model\Resource\Page\CollectionFactory
      */
     protected $_collectionFactory;
 
@@ -29,7 +29,7 @@ class Grid extends \Magento\Backend\Block\Widget\Grid\Extended
      * @param \Magento\Backend\Block\Template\Context $context
      * @param \Magento\Backend\Helper\Data $backendHelper
      * @param \Magento\Cms\Model\Page $cmsPage
-     * @param \Magento\Cms\Model\Resource\Page\Grid\CollectionFactory $collectionFactory
+     * @param \Magento\Cms\Model\Resource\Page\CollectionFactory $collectionFactory
      * @param \Magento\Framework\View\Model\PageLayout\Config\BuilderInterface $pageLayoutBuilder
      * @param array $data
      */
@@ -37,7 +37,7 @@ class Grid extends \Magento\Backend\Block\Widget\Grid\Extended
         \Magento\Backend\Block\Template\Context $context,
         \Magento\Backend\Helper\Data $backendHelper,
         \Magento\Cms\Model\Page $cmsPage,
-        \Magento\Cms\Model\Resource\Page\Grid\CollectionFactory $collectionFactory,
+        \Magento\Cms\Model\Resource\Page\CollectionFactory $collectionFactory,
         \Magento\Framework\View\Model\PageLayout\Config\BuilderInterface $pageLayoutBuilder,
         array $data = []
     ) {
@@ -66,7 +66,7 @@ class Grid extends \Magento\Backend\Block\Widget\Grid\Extended
     protected function _prepareCollection()
     {
         $collection = $this->_collectionFactory->create();
-        /* @var $collection \Magento\Cms\Model\Resource\Page\Grid\Collection */
+        /* @var $collection \Magento\Cms\Model\Resource\Page\Collection */
         $collection->setFirstStoreFlag(true);
         $this->setCollection($collection);
 
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 f6efab805aa28ef9fd36d9bf5eca387adf8914df..addaf3f4926b8e05f48833b16e540eb73ad295ef 100644
--- a/app/code/Magento/Cms/Block/Adminhtml/Page/Widget/Chooser.php
+++ b/app/code/Magento/Cms/Block/Adminhtml/Page/Widget/Chooser.php
@@ -23,7 +23,7 @@ class Chooser extends \Magento\Backend\Block\Widget\Grid\Extended
     protected $_pageFactory;
 
     /**
-     * @var \Magento\Cms\Model\Resource\Page\Grid\CollectionFactory
+     * @var \Magento\Cms\Model\Resource\Page\CollectionFactory
      */
     protected $_collectionFactory;
 
@@ -37,7 +37,7 @@ class Chooser extends \Magento\Backend\Block\Widget\Grid\Extended
      * @param \Magento\Backend\Helper\Data $backendHelper
      * @param \Magento\Cms\Model\Page $cmsPage
      * @param \Magento\Cms\Model\PageFactory $pageFactory
-     * @param \Magento\Cms\Model\Resource\Page\Grid\CollectionFactory $collectionFactory
+     * @param \Magento\Cms\Model\Resource\Page\CollectionFactory $collectionFactory
      * @param \Magento\Framework\View\Model\PageLayout\Config\BuilderInterface $pageLayoutBuilder
      * @param array $data
      */
@@ -46,7 +46,7 @@ class Chooser extends \Magento\Backend\Block\Widget\Grid\Extended
         \Magento\Backend\Helper\Data $backendHelper,
         \Magento\Cms\Model\Page $cmsPage,
         \Magento\Cms\Model\PageFactory $pageFactory,
-        \Magento\Cms\Model\Resource\Page\Grid\CollectionFactory $collectionFactory,
+        \Magento\Cms\Model\Resource\Page\CollectionFactory $collectionFactory,
         \Magento\Framework\View\Model\PageLayout\Config\BuilderInterface $pageLayoutBuilder,
         array $data = []
     ) {
@@ -141,7 +141,7 @@ class Chooser extends \Magento\Backend\Block\Widget\Grid\Extended
     protected function _prepareCollection()
     {
         $collection = $this->_collectionFactory->create();
-        /* @var $collection \Magento\Cms\Model\Resource\Page\Grid\CollectionFactory */
+        /* @var $collection \Magento\Cms\Model\Resource\Page\CollectionFactory */
         $collection->setFirstStoreFlag(true);
         $this->setCollection($collection);
 
diff --git a/app/code/Magento/Cms/Block/Block.php b/app/code/Magento/Cms/Block/Block.php
index 2f8f28e4334fc17c2f112217efbb9aad8c4f3cf0..707dbbe40d754d3708cd3c13a284e13fe5720a58 100644
--- a/app/code/Magento/Cms/Block/Block.php
+++ b/app/code/Magento/Cms/Block/Block.php
@@ -68,7 +68,7 @@ class Block extends \Magento\Framework\View\Element\AbstractBlock implements \Ma
             /** @var \Magento\Cms\Model\Block $block */
             $block = $this->_blockFactory->create();
             $block->setStoreId($storeId)->load($blockId);
-            if ($block->getIsActive()) {
+            if ($block->isActive()) {
                 $html = $this->_filterProvider->getBlockFilter()->setStoreId($storeId)->filter($block->getContent());
             }
         }
diff --git a/app/code/Magento/Cms/Block/Widget/Block.php b/app/code/Magento/Cms/Block/Widget/Block.php
index 66f31639c36f1bb13a97f460f89a324f28895eac..7c83169d945f128d2d10380664f80a7f82123a7a 100644
--- a/app/code/Magento/Cms/Block/Widget/Block.php
+++ b/app/code/Magento/Cms/Block/Widget/Block.php
@@ -70,7 +70,7 @@ class Block extends \Magento\Framework\View\Element\Template implements \Magento
             /** @var \Magento\Cms\Model\Block $block */
             $block = $this->_blockFactory->create();
             $block->setStoreId($storeId)->load($blockId);
-            if ($block->getIsActive()) {
+            if ($block->isActive()) {
                 $this->setText(
                     $this->_filterProvider->getBlockFilter()->setStoreId($storeId)->filter($block->getContent())
                 );
diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Page/MassDelete.php b/app/code/Magento/Cms/Controller/Adminhtml/Page/MassDelete.php
index 95ec6e5169e34519a92e893e5f3bc26e76a99e95..a87024f3ea1e622f46e7f1d540e5f9081932bcaf 100644
--- a/app/code/Magento/Cms/Controller/Adminhtml/Page/MassDelete.php
+++ b/app/code/Magento/Cms/Controller/Adminhtml/Page/MassDelete.php
@@ -23,7 +23,7 @@ class MassDelete extends AbstractMassDelete
      *
      * @var string
      */
-    protected $collection = 'Magento\Cms\Model\Resource\Page\Grid\Collection';
+    protected $collection = 'Magento\Cms\Model\Resource\Page\Collection';
 
     /**
      * Page model
diff --git a/app/code/Magento/Cms/Model/Block.php b/app/code/Magento/Cms/Model/Block.php
index 14227352f81bb7575785bfb46af36585111ed1ab..8fd712570825f235b4959b353906974eefb69a46 100644
--- a/app/code/Magento/Cms/Model/Block.php
+++ b/app/code/Magento/Cms/Model/Block.php
@@ -5,6 +5,7 @@
  */
 namespace Magento\Cms\Model;
 
+use Magento\Cms\Api\Data\BlockInterface;
 use Magento\Framework\Object\IdentityInterface;
 
 /**
@@ -12,28 +13,14 @@ use Magento\Framework\Object\IdentityInterface;
  *
  * @method \Magento\Cms\Model\Resource\Block _getResource()
  * @method \Magento\Cms\Model\Resource\Block getResource()
- * @method \Magento\Cms\Model\Block setTitle(string $value)
- * @method \Magento\Cms\Model\Block setIdentifier(string $value)
- * @method \Magento\Cms\Model\Block setContent(string $value)
- * @method \Magento\Cms\Model\Block setCreationTime(string $value)
- * @method \Magento\Cms\Model\Block setUpdateTime(string $value)
- * @method \Magento\Cms\Model\Block setIsActive(int $value)
  */
-class Block extends \Magento\Framework\Model\AbstractModel implements IdentityInterface
+class Block extends \Magento\Framework\Model\AbstractModel implements BlockInterface, IdentityInterface
 {
     /**
      * CMS block cache tag
      */
     const CACHE_TAG = 'cms_block';
 
-    const ID = 'block_id';
-    const IDENTIFIER = 'identifier';
-    const TITLE = 'title';
-    const CONTENT = 'content';
-    const CREATION_TIME = 'creation_time';
-    const UPDATE_TIME ='update_time';
-    const IS_ACTIVE ='is_active';
-
     /**
      * @var string
      */
@@ -88,7 +75,7 @@ class Block extends \Magento\Framework\Model\AbstractModel implements IdentityIn
      */
     public function getId()
     {
-        return $this->_getData(self::ID);
+        return $this->getData(self::BLOCK_ID);
     }
 
     /**
@@ -98,7 +85,7 @@ class Block extends \Magento\Framework\Model\AbstractModel implements IdentityIn
      */
     public function getIdentifier()
     {
-        return (string) $this->_getData(self::IDENTIFIER);
+        return (string)$this->getData(self::IDENTIFIER);
     }
 
     /**
@@ -108,7 +95,7 @@ class Block extends \Magento\Framework\Model\AbstractModel implements IdentityIn
      */
     public function getTitle()
     {
-        return $this->_getData(self::TITLE);
+        return $this->getData(self::TITLE);
     }
 
     /**
@@ -118,7 +105,7 @@ class Block extends \Magento\Framework\Model\AbstractModel implements IdentityIn
      */
     public function getContent()
     {
-        return $this->_getData(self::CONTENT);
+        return $this->getData(self::CONTENT);
     }
 
     /**
@@ -128,7 +115,7 @@ class Block extends \Magento\Framework\Model\AbstractModel implements IdentityIn
      */
     public function getCreationTime()
     {
-        return $this->_getData(self::CREATION_TIME);
+        return $this->getData(self::CREATION_TIME);
     }
 
     /**
@@ -138,16 +125,93 @@ class Block extends \Magento\Framework\Model\AbstractModel implements IdentityIn
      */
     public function getUpdateTime()
     {
-        return $this->_getData(self::UPDATE_TIME);
+        return $this->getData(self::UPDATE_TIME);
     }
 
     /**
-     * Retrieve block status
+     * Is active
      *
-     * @return int
+     * @return bool
+     */
+    public function isActive()
+    {
+        return (bool)$this->getData(self::IS_ACTIVE);
+    }
+
+    /**
+     * Set ID
+     *
+     * @param int $id
+     * @return BlockInterface
+     */
+    public function setId($id)
+    {
+        return $this->setData(self::BLOCK_ID, $id);
+    }
+
+    /**
+     * Set identifier
+     *
+     * @param string $identifier
+     * @return BlockInterface
+     */
+    public function setIdentifier($identifier)
+    {
+        return $this->setData(self::IDENTIFIER, $identifier);
+    }
+
+    /**
+     * Set title
+     *
+     * @param string $title
+     * @return BlockInterface
+     */
+    public function setTitle($title)
+    {
+        return $this->setData(self::TITLE, $title);
+    }
+
+    /**
+     * Set content
+     *
+     * @param string $content
+     * @return BlockInterface
+     */
+    public function setContent($content)
+    {
+        return $this->setData(self::CONTENT, $content);
+    }
+
+    /**
+     * Set creation time
+     *
+     * @param string $creationTime
+     * @return BlockInterface
+     */
+    public function setCreationTime($creationTime)
+    {
+        return $this->setData(self::CREATION_TIME, $creationTime);
+    }
+
+    /**
+     * Set update time
+     *
+     * @param string $updateTime
+     * @return BlockInterface
+     */
+    public function setUpdateTime($updateTime)
+    {
+        return $this->setData(self::UPDATE_TIME, $updateTime);
+    }
+
+    /**
+     * Set is active
+     *
+     * @param bool|int $isActive
+     * @return BlockInterface
      */
-    public function getIsActive()
+    public function setIsActive($isActive)
     {
-        return $this->_getData(self::IS_ACTIVE);
+        return $this->setData(self::IS_ACTIVE, $isActive);
     }
 }
diff --git a/app/code/Magento/Cms/Model/BlockCriteriaInterface.php b/app/code/Magento/Cms/Model/BlockCriteriaInterface.php
deleted file mode 100644
index 358551b163cdcfa6be96d49b4c2c007c31525f1a..0000000000000000000000000000000000000000
--- a/app/code/Magento/Cms/Model/BlockCriteriaInterface.php
+++ /dev/null
@@ -1,29 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Cms\Model;
-
-/**
- * Interface BlockCriteriaInterface
- */
-interface BlockCriteriaInterface extends \Magento\Framework\Api\CriteriaInterface
-{
-    /**
-     * Set first store flag
-     *
-     * @param bool $flag
-     * @return void
-     */
-    public function setFirstStoreFlag($flag = false);
-
-    /**
-     * Add filter by store
-     *
-     * @param int $storeId
-     * @param bool $withAdmin
-     * @return void
-     */
-    public function addStoreFilter($storeId, $withAdmin = true);
-}
diff --git a/app/code/Magento/Cms/Model/BlockRepository.php b/app/code/Magento/Cms/Model/BlockRepository.php
index 520add71eb28b864280d9cc2979859400fb04c6f..be1498fc8667553ba1f4ad4f8ccd93ac61d57b97 100644
--- a/app/code/Magento/Cms/Model/BlockRepository.php
+++ b/app/code/Magento/Cms/Model/BlockRepository.php
@@ -5,70 +5,82 @@
  */
 namespace Magento\Cms\Model;
 
+use Magento\Cms\Api\Data;
+use Magento\Cms\Api\BlockRepositoryInterface;
+use Magento\Framework\Api\DataObjectHelper;
+use Magento\Framework\Api\SearchCriteriaInterface;
 use Magento\Framework\Exception\CouldNotDeleteException;
 use Magento\Framework\Exception\CouldNotSaveException;
 use Magento\Framework\Exception\NoSuchEntityException;
 
 /**
  * Class BlockRepository
- * @api
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
-class BlockRepository
+class BlockRepository implements BlockRepositoryInterface
 {
     /**
-     * @var \Magento\Cms\Model\Resource\Block
+     * @var Resource\Block
      */
     protected $resource;
 
     /**
-     * @var \Magento\Cms\Model\BlockFactory
+     * @var BlockFactory
      */
     protected $blockFactory;
 
     /**
-     * @var \Magento\Cms\Model\Resource\Block\CollectionFactory
+     * @var Resource\Block\CollectionFactory
      */
     protected $blockCollectionFactory;
 
     /**
-     * @var \Magento\Framework\DB\QueryBuilderFactory
+     * @var Data\BlockSearchResultsInterfaceFactory
      */
-    protected $queryBuilderFactory;
+    protected $searchResultsFactory;
 
     /**
-     * @var \Magento\Framework\DB\MapperFactory
+     * @var DataObjectHelper
      */
-    protected $mapperFactory;
+    protected $dataObjectHelper;
 
     /**
-     * @param \Magento\Cms\Model\Resource\Block $resource
-     * @param \Magento\Cms\Model\BlockFactory $blockFactory
-     * @param \Magento\Cms\Model\Resource\Block\CollectionFactory $blockCollectionFactory
-     * @param \Magento\Framework\DB\QueryBuilderFactory $queryBuilderFactory
-     * @param \Magento\Framework\DB\MapperFactory $mapperFactory
+     * @var Data\BlockInterfaceFactory
+     */
+    protected $dataBlockFactory;
+
+    /**
+     * @param Resource\Block $resource
+     * @param BlockFactory $blockFactory
+     * @param Data\BlockInterfaceFactory $dataBlockFactory
+     * @param Resource\Block\CollectionFactory $blockCollectionFactory
+     * @param Data\BlockSearchResultsInterfaceFactory $searchResultsFactory
+     * @param DataObjectHelper $dataObjectHelper
      */
     public function __construct(
-        \Magento\Cms\Model\Resource\Block $resource,
-        \Magento\Cms\Model\BlockFactory $blockFactory,
-        \Magento\Cms\Model\Resource\Block\CollectionFactory $blockCollectionFactory,
-        \Magento\Framework\DB\QueryBuilderFactory $queryBuilderFactory,
-        \Magento\Framework\DB\MapperFactory $mapperFactory
+        Resource\Block $resource,
+        BlockFactory $blockFactory,
+        Data\BlockInterfaceFactory $dataBlockFactory,
+        Resource\Block\CollectionFactory $blockCollectionFactory,
+        Data\BlockSearchResultsInterfaceFactory $searchResultsFactory,
+        DataObjectHelper $dataObjectHelper
     ) {
         $this->resource = $resource;
         $this->blockFactory = $blockFactory;
         $this->blockCollectionFactory = $blockCollectionFactory;
-        $this->queryBuilderFactory = $queryBuilderFactory;
-        $this->mapperFactory = $mapperFactory;
+        $this->searchResultsFactory = $searchResultsFactory;
+        $this->dataObjectHelper = $dataObjectHelper;
+        $this->dataBlockFactory = $dataBlockFactory;
     }
 
     /**
      * Save Block data
      *
-     * @param \Magento\Cms\Model\Block $block
-     * @return \Magento\Cms\Model\Block
+     * @param Data\BlockInterface $block
+     * @return Block
      * @throws CouldNotSaveException
      */
-    public function save(\Magento\Cms\Model\Block $block)
+    public function save(Data\BlockInterface $block)
     {
         try {
             $this->resource->save($block);
@@ -82,10 +94,10 @@ class BlockRepository
      * Load Block data by given Block Identity
      *
      * @param string $blockId
-     * @return \Magento\Cms\Model\Block
+     * @return Block
      * @throws \Magento\Framework\Exception\NoSuchEntityException
      */
-    public function get($blockId)
+    public function getById($blockId)
     {
         $block = $this->blockFactory->create();
         $this->resource->load($block, $blockId);
@@ -98,27 +110,65 @@ class BlockRepository
     /**
      * Load Block data collection by given search criteria
      *
-     * @param \Magento\Cms\Model\BlockCriteriaInterface $criteria
-     * @return \Magento\Cms\Model\Resource\Block\Collection
+     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+     * @SuppressWarnings(PHPMD.NPathComplexity)
+     * @param SearchCriteriaInterface $criteria
+     * @return Resource\Block\Collection
      */
-    public function getList(\Magento\Cms\Model\BlockCriteriaInterface $criteria)
+    public function getList(SearchCriteriaInterface $criteria)
     {
-        $queryBuilder = $this->queryBuilderFactory->create();
-        $queryBuilder->setCriteria($criteria);
-        $queryBuilder->setResource($this->resource);
-        $query = $queryBuilder->create();
-        $collection = $this->blockCollectionFactory->create(['query' => $query]);
-        return $collection;
+        $searchResults = $this->searchResultsFactory->create();
+        $searchResults->setSearchCriteria($criteria);
+
+        $collection = $this->blockCollectionFactory->create();
+        foreach ($criteria->getFilterGroups() as $filterGroup) {
+            $fields = [];
+            $conditions = [];
+            foreach ($filterGroup->getFilters() as $filter) {
+                if ($filter->getField() === 'store_id') {
+                    $collection->addStoreFilter($filter->getValue(), false);
+                    continue;
+                }
+                $condition = $filter->getConditionType() ?: 'eq';
+                $fields[] = ['attribute' => $filter->getField(), $condition => $filter->getValue()];
+            }
+            if ($fields) {
+                $collection->addFieldToFilter($fields, $conditions);
+            }
+        }
+        $searchResults->setTotalCount($collection->getSize());
+        $sortOrders = $criteria->getSortOrders();
+        if ($sortOrders) {
+            foreach ($sortOrders as $sortOrder) {
+                $collection->addOrder(
+                    $sortOrder->getField(),
+                    ($sortOrder->getDirection() == SearchCriteriaInterface::SORT_ASC) ? 'ASC' : 'DESC'
+                );
+            }
+        }
+        $collection->setCurPage($criteria->getCurrentPage());
+        $collection->setPageSize($criteria->getPageSize());
+        $blocks = [];
+        /** @var Block $blockModel */
+        foreach ($collection as $blockModel) {
+            $blocks[] = $this->dataObjectHelper->populateWithArray(
+                $this->dataBlockFactory->create(),
+                $blockModel->getData(),
+                'Magento\Cms\Api\Data\BlockInterface'
+            );
+        }
+        $searchResults->setItems($blocks);
+        return $searchResults;
     }
 
     /**
      * Delete Block
      *
-     * @param \Magento\Cms\Model\Block $block
+     * @param Data\BlockInterface $block
      * @return bool
-     * @throws \Magento\Framework\Exception\CouldNotDeleteException
+     * @throws CouldNotDeleteException
      */
-    public function delete(\Magento\Cms\Model\Block $block)
+    public function delete(Data\BlockInterface $block)
     {
         try {
             $this->resource->delete($block);
@@ -133,11 +183,11 @@ class BlockRepository
      *
      * @param string $blockId
      * @return bool
-     * @throws \Magento\Framework\Exception\CouldNotDeleteException
-     * @throws \Magento\Framework\Exception\NoSuchEntityException
+     * @throws CouldNotDeleteException
+     * @throws NoSuchEntityException
      */
     public function deleteById($blockId)
     {
-        return $this->delete($this->get($blockId));
+        return $this->delete($this->getById($blockId));
     }
 }
diff --git a/app/code/Magento/Cms/Model/Config/Source/Page.php b/app/code/Magento/Cms/Model/Config/Source/Page.php
index 4ed69001f1f9e0d0a747bcb7962f0a33b9c87a4a..6d0d87680ef5a386c7fde21be6a542beb1335793 100644
--- a/app/code/Magento/Cms/Model/Config/Source/Page.php
+++ b/app/code/Magento/Cms/Model/Config/Source/Page.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\Cms\Model\Config\Source;
 
+use Magento\Cms\Model\Resource\Page\CollectionFactory;
+
 /**
  * Class Page
  */
@@ -16,25 +18,17 @@ class Page implements \Magento\Framework\Option\ArrayInterface
     protected $options;
 
     /**
-     * @var \Magento\Cms\Model\PageRepository
-     */
-    protected $pageRepository;
-
-    /**
-     * @var \Magento\Cms\Model\Resource\PageCriteria
+     * @var CollectionFactory
      */
-    protected $pageCriteriaFactory;
+    protected $collectionFactory;
 
     /**
-     * @param \Magento\Cms\Model\PageRepository $pageRepository
-     * @param \Magento\Cms\Model\Resource\PageCriteriaFactory $pageCriteriaFactory
+     * @param CollectionFactory $collectionFactory
      */
     public function __construct(
-        \Magento\Cms\Model\PageRepository $pageRepository,
-        \Magento\Cms\Model\Resource\PageCriteriaFactory $pageCriteriaFactory
+        CollectionFactory $collectionFactory
     ) {
-        $this->pageRepository = $pageRepository;
-        $this->pageCriteriaFactory = $pageCriteriaFactory;
+        $this->collectionFactory = $collectionFactory;
     }
 
     /**
@@ -45,7 +39,7 @@ class Page implements \Magento\Framework\Option\ArrayInterface
     public function toOptionArray()
     {
         if (!$this->options) {
-            $this->options = $this->pageRepository->getList($this->pageCriteriaFactory->create())->toOptionIdArray();
+            $this->options = $this->collectionFactory->create()->toOptionIdArray();
         }
         return $this->options;
     }
diff --git a/app/code/Magento/Cms/Model/DataSource/BlockCollection.php b/app/code/Magento/Cms/Model/DataSource/BlockCollection.php
deleted file mode 100644
index b63c604fcd6865a88fcb7d0fadc1a578ce59e163..0000000000000000000000000000000000000000
--- a/app/code/Magento/Cms/Model/DataSource/BlockCollection.php
+++ /dev/null
@@ -1,54 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Cms\Model\DataSource;
-
-use Magento\Framework\Data\CollectionDataSourceInterface;
-use Magento\Cms\Model\Resource\BlockCriteria;
-use Magento\Cms\Model\BlockRepository;
-
-/**
- * CMS block collection data source
- *
- * Class BlockCollection
- */
-class BlockCollection extends BlockCriteria implements CollectionDataSourceInterface
-{
-    /**
-     * @var BlockRepository
-     */
-    protected $repository;
-
-    /**
-     * @param BlockRepository $repository
-     * @param string $mapper
-     */
-    public function __construct(BlockRepository $repository, $mapper = '')
-    {
-        $this->repository = $repository;
-        $this->setFirstStoreFlag(true);
-        parent::__construct($mapper);
-    }
-
-    /**
-     * @inheritdoc
-     */
-    public function addFilter($name, $field, $condition = null, $type = 'public')
-    {
-        if ($field === 'store_id') {
-            $this->addStoreFilter($condition, false);
-        } else {
-            parent::addFilter($name, $field, $condition, $type);
-        }
-    }
-
-    /**
-     * @return \Magento\Cms\Model\Resource\Block\Collection
-     */
-    public function getResultCollection()
-    {
-        return $this->repository->getList($this);
-    }
-}
diff --git a/app/code/Magento/Cms/Model/DataSource/PageCollection.php b/app/code/Magento/Cms/Model/DataSource/PageCollection.php
deleted file mode 100644
index 74491d38aea4c6a72e70e6bba56596dba579103b..0000000000000000000000000000000000000000
--- a/app/code/Magento/Cms/Model/DataSource/PageCollection.php
+++ /dev/null
@@ -1,64 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Cms\Model\DataSource;
-
-use Magento\Cms\Model\Resource\PageCriteria;
-use Magento\Framework\Data\CollectionDataSourceInterface;
-
-/**
- * CMS page collection data source
- *
- * Class PageCollection
- */
-class PageCollection extends PageCriteria implements CollectionDataSourceInterface
-{
-    /**
-     * @var \Magento\Cms\Model\PageRepository
-     */
-    protected $repository;
-
-    /**
-     * @param \Magento\Cms\Model\PageRepository $repository
-     * @param string $mapper
-     */
-    public function __construct(\Magento\Cms\Model\PageRepository $repository, $mapper = '')
-    {
-        $this->repository = $repository;
-        $this->setFirstStoreFlag(true);
-        parent::__construct($mapper);
-    }
-
-    /**
-     * @inheritdoc
-     */
-    public function addFilter($name, $field, $condition = null, $type = 'public')
-    {
-        if ($field === 'store_id') {
-            $this->addStoreFilter($condition, false);
-        } else {
-            parent::addFilter($name, $field, $condition, $type);
-        }
-    }
-
-    /**
-     * @return \Magento\Cms\Model\Resource\Page\Collection
-     */
-    public function getResultCollection()
-    {
-        return $this->repository->getList($this);
-    }
-
-    /**
-     * Add Criteria object
-     *
-     * @param \Magento\Cms\Model\Resource\PageCriteria $criteria
-     * @return void
-     */
-    public function addCriteria(\Magento\Cms\Model\Resource\PageCriteria $criteria)
-    {
-        $this->data[self::PART_CRITERIA_LIST]['list'][] = $criteria;
-    }
-}
diff --git a/app/code/Magento/Cms/Model/Page.php b/app/code/Magento/Cms/Model/Page.php
index d1693facd3e2180a190c88961455eb3dbe4f8ff8..fca4ecc84aa66052fc48af15edf6d9fac83aeb41 100644
--- a/app/code/Magento/Cms/Model/Page.php
+++ b/app/code/Magento/Cms/Model/Page.php
@@ -5,6 +5,7 @@
  */
 namespace Magento\Cms\Model;
 
+use Magento\Cms\Api\Data\PageInterface;
 use Magento\Framework\Object\IdentityInterface;
 
 /**
@@ -12,41 +13,9 @@ use Magento\Framework\Object\IdentityInterface;
  *
  * @method \Magento\Cms\Model\Resource\Page _getResource()
  * @method \Magento\Cms\Model\Resource\Page getResource()
- * @method \Magento\Cms\Model\Page setTitle(string $value)
- * @method string getPageLayout()
- * @method \Magento\Cms\Model\Page setPageLayout(string $value)
- * @method string getMetaKeywords()
- * @method \Magento\Cms\Model\Page setMetaKeywords(string $value)
- * @method string getMetaDescription()
- * @method \Magento\Cms\Model\Page setMetaDescription(string $value)
- * @method \Magento\Cms\Model\Page setIdentifier(string $value)
- * @method string getContentHeading()
- * @method \Magento\Cms\Model\Page setContentHeading(string $value)
- * @method string getContent()
- * @method \Magento\Cms\Model\Page setContent(string $value)
- * @method string getCreationTime()
- * @method \Magento\Cms\Model\Page setCreationTime(string $value)
- * @method string getUpdateTime()
- * @method \Magento\Cms\Model\Page setUpdateTime(string $value)
- * @method int getIsActive()
- * @method \Magento\Cms\Model\Page setIsActive(int $value)
- * @method int getSortOrder()
- * @method \Magento\Cms\Model\Page setSortOrder(int $value)
- * @method string getLayoutUpdateXml()
- * @method \Magento\Cms\Model\Page setLayoutUpdateXml(string $value)
- * @method string getCustomTheme()
- * @method \Magento\Cms\Model\Page setCustomTheme(string $value)
- * @method string getCustomPageLayout()
- * @method \Magento\Cms\Model\Page setCustomPageLayout(string $value)
- * @method string getCustomLayoutUpdateXml()
- * @method \Magento\Cms\Model\Page setCustomLayoutUpdateXml(string $value)
- * @method string getCustomThemeFrom()
- * @method \Magento\Cms\Model\Page setCustomThemeFrom(string $value)
- * @method string getCustomThemeTo()
- * @method \Magento\Cms\Model\Page setCustomThemeTo(string $value)
  * @method int[] getStores()
  */
-class Page extends \Magento\Framework\Model\AbstractModel implements IdentityInterface
+class Page extends \Magento\Framework\Model\AbstractModel implements PageInterface, IdentityInterface
 {
     /**
      * No route page id
@@ -60,14 +29,6 @@ class Page extends \Magento\Framework\Model\AbstractModel implements IdentityInt
     const STATUS_DISABLED = 0;
     /**#@-*/
 
-    /**#@+
-     * Data object constants
-     */
-    const PAGE_ID = 'page_id';
-    const IDENTIFIER = 'identifier';
-    const TITLE = 'title';
-    /**#@-*/
-
     /**
      * CMS page cache tag
      */
@@ -95,30 +56,6 @@ class Page extends \Magento\Framework\Model\AbstractModel implements IdentityInt
         $this->_init('Magento\Cms\Model\Resource\Page');
     }
 
-    /**
-     * @return int
-     */
-    public function getId()
-    {
-        return $this->_getData(self::PAGE_ID);
-    }
-
-    /**
-     * @return string
-     */
-    public function getIdentifier()
-    {
-        return (string) $this->_getData(self::IDENTIFIER);
-    }
-
-    /**
-     * @return string
-     */
-    public function getTitle()
-    {
-        return $this->_getData(self::TITLE);
-    }
-
     /**
      * Load object data
      *
@@ -177,4 +114,382 @@ class Page extends \Magento\Framework\Model\AbstractModel implements IdentityInt
     {
         return [self::CACHE_TAG . '_' . $this->getId()];
     }
+
+    /**
+     * Get ID
+     *
+     * @return int
+     */
+    public function getId()
+    {
+        return parent::getData(self::PAGE_ID);
+    }
+
+    /**
+     * Get identifier
+     *
+     * @return string
+     */
+    public function getIdentifier()
+    {
+        return $this->getData(self::IDENTIFIER);
+    }
+
+    /**
+     * Get title
+     *
+     * @return string
+     */
+    public function getTitle()
+    {
+        return $this->getData(self::TITLE);
+    }
+
+    /**
+     * Get page layout
+     *
+     * @return string
+     */
+    public function getPageLayout()
+    {
+        return $this->getData(self::PAGE_LAYOUT);
+    }
+
+    /**
+     * Get meta keywords
+     *
+     * @return string
+     */
+    public function getMetaKeywords()
+    {
+        return $this->getData(self::META_KEYWORDS);
+    }
+
+    /**
+     * Get meta description
+     *
+     * @return string
+     */
+    public function getMetaDescription()
+    {
+        return $this->getData(self::META_DESCRIPTION);
+    }
+
+    /**
+     * Get content heading
+     *
+     * @return string
+     */
+    public function getContentHeading()
+    {
+        return $this->getData(self::CONTENT_HEADING);
+    }
+
+    /**
+     * Get content
+     *
+     * @return string
+     */
+    public function getContent()
+    {
+        return $this->getData(self::CONTENT);
+    }
+
+    /**
+     * Get creation time
+     *
+     * @return string
+     */
+    public function getCreationTime()
+    {
+        return $this->getData(self::CREATION_TIME);
+    }
+
+    /**
+     * Get update time
+     *
+     * @return string
+     */
+    public function getUpdateTime()
+    {
+        return $this->getData(self::UPDATE_TIME);
+    }
+
+    /**
+     * Get sort order
+     *
+     * @return string
+     */
+    public function getSortOrder()
+    {
+        return $this->getData(self::SORT_ORDER);
+    }
+
+    /**
+     * Get layout update xml
+     *
+     * @return string
+     */
+    public function getLayoutUpdateXml()
+    {
+        return $this->getData(self::LAYOUT_UPDATE_XML);
+    }
+
+    /**
+     * Get custom theme
+     *
+     * @return string
+     */
+    public function getCustomTheme()
+    {
+        return $this->getData(self::CUSTOM_THEME);
+    }
+
+    /**
+     * Get custom root template
+     *
+     * @return string
+     */
+    public function getCustomRootTemplate()
+    {
+        return $this->getData(self::CUSTOM_ROOT_TEMPLATE);
+    }
+
+    /**
+     * Get custom layout update xml
+     *
+     * @return string
+     */
+    public function getCustomLayoutUpdateXml()
+    {
+        return $this->getData(self::CUSTOM_LAYOUT_UPDATE_XML);
+    }
+
+    /**
+     * Get custom theme from
+     *
+     * @return string
+     */
+    public function getCustomThemeFrom()
+    {
+        return $this->getData(self::CUSTOM_THEME_FROM);
+    }
+
+    /**
+     * Get custom theme to
+     *
+     * @return string
+     */
+    public function getCustomThemeTo()
+    {
+        return $this->getData(self::CUSTOM_THEME_TO);
+    }
+
+    /**
+     * Is active
+     *
+     * @return bool
+     */
+    public function isActive()
+    {
+        return (bool)$this->getData(self::IS_ACTIVE);
+    }
+
+    /**
+     * Set ID
+     *
+     * @param int $id
+     * @return \Magento\Cms\Api\Data\PageInterface
+     */
+    public function setId($id)
+    {
+        return $this->setData(self::PAGE_ID, $id);
+    }
+
+    /**
+     * Set identifier
+     *
+     * @param string $identifier
+     * @return \Magento\Cms\Api\Data\PageInterface
+     */
+    public function setIdentifier($identifier)
+    {
+        return $this->setData(self::IDENTIFIER, $identifier);
+    }
+
+    /**
+     * Set title
+     *
+     * @param string $title
+     * @return \Magento\Cms\Api\Data\PageInterface
+     */
+    public function setTitle($title)
+    {
+        return $this->setData(self::TITLE, $title);
+    }
+
+    /**
+     * Set page layout
+     *
+     * @param string $pageLayout
+     * @return \Magento\Cms\Api\Data\PageInterface
+     */
+    public function setPageLayout($pageLayout)
+    {
+        return $this->setData(self::PAGE_LAYOUT, $pageLayout);
+    }
+
+    /**
+     * Set meta keywords
+     *
+     * @param string $metaKeywords
+     * @return \Magento\Cms\Api\Data\PageInterface
+     */
+    public function setMetaKeywords($metaKeywords)
+    {
+        return $this->setData(self::META_KEYWORDS, $metaKeywords);
+    }
+
+    /**
+     * Set meta description
+     *
+     * @param string $metaDescription
+     * @return \Magento\Cms\Api\Data\PageInterface
+     */
+    public function setMetaDescription($metaDescription)
+    {
+        return $this->setData(self::META_DESCRIPTION, $metaDescription);
+    }
+
+    /**
+     * Set content heading
+     *
+     * @param string $contentHeading
+     * @return \Magento\Cms\Api\Data\PageInterface
+     */
+    public function setContentHeading($contentHeading)
+    {
+        return $this->setData(self::CONTENT_HEADING, $contentHeading);
+    }
+
+    /**
+     * Set content
+     *
+     * @param string $content
+     * @return \Magento\Cms\Api\Data\PageInterface
+     */
+    public function setContent($content)
+    {
+        return $this->setData(self::CONTENT, $content);
+    }
+
+    /**
+     * Set creation time
+     *
+     * @param string $creationTime
+     * @return \Magento\Cms\Api\Data\PageInterface
+     */
+    public function setCreationTime($creationTime)
+    {
+        return $this->setData(self::CREATION_TIME, $creationTime);
+    }
+
+    /**
+     * Set update time
+     *
+     * @param string $updateTime
+     * @return \Magento\Cms\Api\Data\PageInterface
+     */
+    public function setUpdateTime($updateTime)
+    {
+        return $this->setData(self::UPDATE_TIME, $updateTime);
+    }
+
+    /**
+     * Set sort order
+     *
+     * @param string $sortOrder
+     * @return \Magento\Cms\Api\Data\PageInterface
+     */
+    public function setSortOrder($sortOrder)
+    {
+        return $this->setData(self::SORT_ORDER, $sortOrder);
+    }
+
+    /**
+     * Set layout update xml
+     *
+     * @param string $layoutUpdateXml
+     * @return \Magento\Cms\Api\Data\PageInterface
+     */
+    public function setLayoutUpdateXml($layoutUpdateXml)
+    {
+        return $this->setData(self::LAYOUT_UPDATE_XML, $layoutUpdateXml);
+    }
+
+    /**
+     * Set custom theme
+     *
+     * @param string $customTheme
+     * @return \Magento\Cms\Api\Data\PageInterface
+     */
+    public function setCustomTheme($customTheme)
+    {
+        return $this->setData(self::CUSTOM_THEME, $customTheme);
+    }
+
+    /**
+     * Set custom root template
+     *
+     * @param string $customRootTemplate
+     * @return \Magento\Cms\Api\Data\PageInterface
+     */
+    public function setCustomRootTemplate($customRootTemplate)
+    {
+        return $this->setData(self::CUSTOM_ROOT_TEMPLATE, $customRootTemplate);
+    }
+
+    /**
+     * Set custom layout update xml
+     *
+     * @param string $customLayoutUpdateXml
+     * @return \Magento\Cms\Api\Data\PageInterface
+     */
+    public function setCustomLayoutUpdateXml($customLayoutUpdateXml)
+    {
+        return $this->setData(self::CUSTOM_LAYOUT_UPDATE_XML, $customLayoutUpdateXml);
+    }
+
+    /**
+     * Set custom theme from
+     *
+     * @param string $customThemeFrom
+     * @return \Magento\Cms\Api\Data\PageInterface
+     */
+    public function setCustomThemeFrom($customThemeFrom)
+    {
+        return $this->setData(self::CUSTOM_THEME_FROM, $customThemeFrom);
+    }
+
+    /**
+     * Set custom theme to
+     *
+     * @param string $customThemeTo
+     * @return \Magento\Cms\Api\Data\PageInterface
+     */
+    public function setCustomThemeTo($customThemeTo)
+    {
+        return $this->setData(self::CUSTOM_THEME_TO, $customThemeTo);
+    }
+
+    /**
+     * Set is active
+     *
+     * @param int|bool $isActive
+     * @return \Magento\Cms\Api\Data\PageInterface
+     */
+    public function setIsActive($isActive)
+    {
+        return $this->setData(self::IS_ACTIVE, $isActive);
+    }
 }
diff --git a/app/code/Magento/Cms/Model/PageCriteriaInterface.php b/app/code/Magento/Cms/Model/PageCriteriaInterface.php
deleted file mode 100644
index 692fb97988f222d119b02fcf536bc01b656b3e21..0000000000000000000000000000000000000000
--- a/app/code/Magento/Cms/Model/PageCriteriaInterface.php
+++ /dev/null
@@ -1,29 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Cms\Model;
-
-/**
- * Interface PageCriteriaInterface
- */
-interface PageCriteriaInterface extends \Magento\Framework\Api\CriteriaInterface
-{
-    /**
-     * Set first store flag
-     *
-     * @param bool $flag
-     * @return void
-     */
-    public function setFirstStoreFlag($flag = false);
-
-    /**
-     * Add filter by store
-     *
-     * @param int|\Magento\Store\Model\Store $store
-     * @param bool $withAdmin
-     * @return void
-     */
-    public function addStoreFilter($store, $withAdmin = true);
-}
diff --git a/app/code/Magento/Cms/Model/PageRepository.php b/app/code/Magento/Cms/Model/PageRepository.php
index 67815ec24adb01de14531640a2cdbeec49f2a471..82fbba3748d12cdb9dd26ec4dd0d62c9f6c50455 100644
--- a/app/code/Magento/Cms/Model/PageRepository.php
+++ b/app/code/Magento/Cms/Model/PageRepository.php
@@ -5,69 +5,82 @@
  */
 namespace Magento\Cms\Model;
 
+use Magento\Cms\Api\Data;
+use Magento\Cms\Api\PageRepositoryInterface;
+use Magento\Framework\Api\DataObjectHelper;
+use Magento\Framework\Api\SearchCriteriaInterface;
 use Magento\Framework\Exception\CouldNotDeleteException;
 use Magento\Framework\Exception\CouldNotSaveException;
 use Magento\Framework\Exception\NoSuchEntityException;
 
 /**
  * Class PageRepository
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
-class PageRepository
+class PageRepository implements PageRepositoryInterface
 {
     /**
-     * @var \Magento\Cms\Model\Resource\Page
+     * @var Resource\Page
      */
     protected $resource;
 
     /**
-     * @var \Magento\Cms\Model\PageFactory
+     * @var PageFactory
      */
     protected $pageFactory;
 
     /**
-     * @var \Magento\Cms\Model\Resource\Page\CollectionFactory
+     * @var Resource\Page\CollectionFactory
      */
     protected $pageCollectionFactory;
 
     /**
-     * @var \Magento\Framework\DB\QueryBuilderFactory
+     * @var Data\PageSearchResultsInterfaceFactory
      */
-    protected $queryBuilderFactory;
+    protected $searchResultsFactory;
 
     /**
-     * @var \Magento\Framework\DB\MapperFactory
+     * @var DataObjectHelper
      */
-    protected $mapperFactory;
+    protected $dataObjectHelper;
+
+    /**
+     * @var Data\PageInterfaceFactory
+     */
+    protected $dataPageFactory;
 
     /**
      * @param Resource\Page $resource
-     * @param \Magento\Cms\Model\PageFactory $pageFactory
-     * @param \Magento\Cms\Model\Resource\Page\CollectionFactory $pageCollectionFactory
-     * @param \Magento\Framework\DB\QueryBuilderFactory $queryBuilderFactory
-     * @param \Magento\Framework\DB\MapperFactory $mapperFactory
+     * @param PageFactory $pageFactory
+     * @param Data\PageInterfaceFactory $dataPageFactory
+     * @param Resource\Page\CollectionFactory $pageCollectionFactory
+     * @param Data\PageSearchResultsInterfaceFactory $searchResultsFactory
+     * @param DataObjectHelper $dataObjectHelper
      */
     public function __construct(
-        \Magento\Cms\Model\Resource\Page $resource,
-        \Magento\Cms\Model\PageFactory $pageFactory,
-        \Magento\Cms\Model\Resource\Page\CollectionFactory $pageCollectionFactory,
-        \Magento\Framework\DB\QueryBuilderFactory $queryBuilderFactory,
-        \Magento\Framework\DB\MapperFactory $mapperFactory
+        Resource\Page $resource,
+        PageFactory $pageFactory,
+        Data\PageInterfaceFactory $dataPageFactory,
+        Resource\Page\CollectionFactory $pageCollectionFactory,
+        Data\PageSearchResultsInterfaceFactory $searchResultsFactory,
+        DataObjectHelper $dataObjectHelper
     ) {
         $this->resource = $resource;
         $this->pageFactory = $pageFactory;
         $this->pageCollectionFactory = $pageCollectionFactory;
-        $this->queryBuilderFactory = $queryBuilderFactory;
-        $this->mapperFactory = $mapperFactory;
+        $this->searchResultsFactory = $searchResultsFactory;
+        $this->dataObjectHelper = $dataObjectHelper;
+        $this->dataPageFactory = $dataPageFactory;
     }
 
     /**
      * Save Page data
      *
-     * @param \Magento\Cms\Model\Page $page
-     * @return \Magento\Cms\Model\Page
+     * @param Data\PageInterface $page
+     * @return Page
      * @throws CouldNotSaveException
      */
-    public function save(\Magento\Cms\Model\Page $page)
+    public function save(Data\PageInterface $page)
     {
         try {
             $this->resource->save($page);
@@ -81,10 +94,10 @@ class PageRepository
      * Load Page data by given Page Identity
      *
      * @param string $pageId
-     * @return \Magento\Cms\Model\Page
+     * @return Page
      * @throws \Magento\Framework\Exception\NoSuchEntityException
      */
-    public function get($pageId)
+    public function getById($pageId)
     {
         $page = $this->pageFactory->create();
         $this->resource->load($page, $pageId);
@@ -97,27 +110,65 @@ class PageRepository
     /**
      * Load Page data collection by given search criteria
      *
-     * @param \Magento\Cms\Model\PageCriteriaInterface $criteria
-     * @return \Magento\Cms\Model\Resource\Page\Collection
+     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+     * @SuppressWarnings(PHPMD.NPathComplexity)
+     * @param SearchCriteriaInterface $criteria
+     * @return Resource\Page\Collection
      */
-    public function getList(\Magento\Cms\Model\PageCriteriaInterface $criteria)
+    public function getList(SearchCriteriaInterface $criteria)
     {
-        $queryBuilder = $this->queryBuilderFactory->create();
-        $queryBuilder->setCriteria($criteria);
-        $queryBuilder->setResource($this->resource);
-        $query = $queryBuilder->create();
-        $collection = $this->pageCollectionFactory->create(['query' => $query]);
-        return $collection;
+        $searchResults = $this->searchResultsFactory->create();
+        $searchResults->setSearchCriteria($criteria);
+
+        $collection = $this->pageCollectionFactory->create();
+        foreach ($criteria->getFilterGroups() as $filterGroup) {
+            $fields = [];
+            $conditions = [];
+            foreach ($filterGroup->getFilters() as $filter) {
+                if ($filter->getField() === 'store_id') {
+                    $collection->addStoreFilter($filter->getValue(), false);
+                    continue;
+                }
+                $condition = $filter->getConditionType() ?: 'eq';
+                $fields[] = ['attribute' => $filter->getField(), $condition => $filter->getValue()];
+            }
+            if ($fields) {
+                $collection->addFieldToFilter($fields, $conditions);
+            }
+        }
+        $searchResults->setTotalCount($collection->getSize());
+        $sortOrders = $criteria->getSortOrders();
+        if ($sortOrders) {
+            foreach ($sortOrders as $sortOrder) {
+                $collection->addOrder(
+                    $sortOrder->getField(),
+                    ($sortOrder->getDirection() == SearchCriteriaInterface::SORT_ASC) ? 'ASC' : 'DESC'
+                );
+            }
+        }
+        $collection->setCurPage($criteria->getCurrentPage());
+        $collection->setPageSize($criteria->getPageSize());
+        $pages = [];
+        /** @var Page $pageModel */
+        foreach ($collection as $pageModel) {
+            $pages[] = $this->dataObjectHelper->populateWithArray(
+                $this->dataPageFactory->create(),
+                $pageModel->getData(),
+                'Magento\Cms\Api\Data\PageInterface'
+            );
+        }
+        $searchResults->setItems($pages);
+        return $searchResults;
     }
 
     /**
      * Delete Page
      *
-     * @param \Magento\Cms\Model\Page $page
+     * @param Data\PageInterface $page
      * @return bool
-     * @throws \Magento\Framework\Exception\CouldNotDeleteException
+     * @throws CouldNotDeleteException
      */
-    public function delete(\Magento\Cms\Model\Page $page)
+    public function delete(Data\PageInterface $page)
     {
         try {
             $this->resource->delete($page);
@@ -132,11 +183,11 @@ class PageRepository
      *
      * @param string $pageId
      * @return bool
-     * @throws \Magento\Framework\Exception\CouldNotDeleteException
-     * @throws \Magento\Framework\Exception\NoSuchEntityException
+     * @throws CouldNotDeleteException
+     * @throws NoSuchEntityException
      */
     public function deleteById($pageId)
     {
-        return $this->delete($this->get($pageId));
+        return $this->delete($this->getById($pageId));
     }
 }
diff --git a/app/code/Magento/Cms/Model/Resource/Block/Collection.php b/app/code/Magento/Cms/Model/Resource/Block/Collection.php
index b6e0b2db406ee0cfd33a7fffe3b5494c21f4d508..3898607f31ed81b2ebe958e33eb56eeb243660df 100644
--- a/app/code/Magento/Cms/Model/Resource/Block/Collection.php
+++ b/app/code/Magento/Cms/Model/Resource/Block/Collection.php
@@ -1,27 +1,117 @@
 <?php
 /**
+ * Cms block grid collection
+ *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
 namespace Magento\Cms\Model\Resource\Block;
 
-use Magento\Cms\Model\Resource\AbstractCollection;
-
 /**
- * CMS block collection
- *
  * Class Collection
  */
-class Collection extends AbstractCollection
+class Collection extends \Magento\Framework\Model\Resource\Db\Collection\AbstractCollection
 {
     /**
+     * @return \Magento\Cms\Model\Resource\Block\Collection
+     */
+    protected function _afterLoad()
+    {
+        $this->walk('afterLoad');
+        parent::_afterLoad();
+    }
+
+    /**
+     * @param string|array $field
+     * @param string|int|array|null $condition
+     * @return \Magento\Cms\Model\Resource\Block\Collection
+     */
+    public function addFieldToFilter($field, $condition = null)
+    {
+        if ($field == 'store_id') {
+            return $this->addStoreFilter($condition, false);
+        }
+        return parent::addFieldToFilter($field, $condition);
+    }
+
+    /**
+     * Define resource model
+     *
+     * @return void
+     */
+    protected function _construct()
+    {
+        $this->_init('Magento\Cms\Model\Block', 'Magento\Cms\Model\Resource\Block');
+        $this->_map['fields']['store'] = 'store_table.store_id';
+    }
+
+    /**
+     * Returns pairs block_id - title
+     *
+     * @return array
+     */
+    public function toOptionArray()
+    {
+        return $this->_toOptionArray('block_id', 'title');
+    }
+
+    /**
+     * Add filter by store
+     *
+     * @param int|\Magento\Store\Model\Store $store
+     * @param bool $withAdmin
+     * @return $this
+     */
+    public function addStoreFilter($store, $withAdmin = true)
+    {
+        if ($store instanceof \Magento\Store\Model\Store) {
+            $store = [$store->getId()];
+        }
+
+        if (!is_array($store)) {
+            $store = [$store];
+        }
+
+        if ($withAdmin) {
+            $store[] = \Magento\Store\Model\Store::DEFAULT_STORE_ID;
+        }
+
+        $this->addFilter('store', ['in' => $store], 'public');
+
+        return $this;
+    }
+
+    /**
+     * Get SQL for get record count.
+     * Extra GROUP BY strip added.
+     *
+     * @return \Magento\Framework\DB\Select
+     */
+    public function getSelectCountSql()
+    {
+        $countSelect = parent::getSelectCountSql();
+
+        $countSelect->reset(\Zend_Db_Select::GROUP);
+
+        return $countSelect;
+    }
+
+    /**
+     * Join store relation table if there is store filter
+     *
      * @return void
      */
-    protected function init()
+    protected function _renderFiltersBefore()
     {
-        $this->setDataInterfaceName('Magento\Cms\Model\Block');
-        $this->storeTableName = 'cms_block_store';
-        $this->linkFieldName = 'block_id';
-        parent::init();
+        if ($this->getFilter('store')) {
+            $this->getSelect()->join(
+                ['store_table' => $this->getTable('cms_block_store')],
+                'main_table.block_id = store_table.block_id',
+                []
+            )->group(
+                'main_table.block_id'
+            );
+        }
+        parent::_renderFiltersBefore();
     }
 }
diff --git a/app/code/Magento/Cms/Model/Resource/Block/Grid/Collection.php b/app/code/Magento/Cms/Model/Resource/Block/Grid/Collection.php
deleted file mode 100644
index 50b5433e4fc9dc0a2b83e4cbd93ce89b3ab450e7..0000000000000000000000000000000000000000
--- a/app/code/Magento/Cms/Model/Resource/Block/Grid/Collection.php
+++ /dev/null
@@ -1,117 +0,0 @@
-<?php
-/**
- * Cms block grid collection
- *
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Cms\Model\Resource\Block\Grid;
-
-/**
- * Class Collection
- */
-class Collection extends \Magento\Framework\Model\Resource\Db\Collection\AbstractCollection
-{
-    /**
-     * @return \Magento\Cms\Model\Resource\Block\Grid\Collection
-     */
-    protected function _afterLoad()
-    {
-        $this->walk('afterLoad');
-        parent::_afterLoad();
-    }
-
-    /**
-     * @param string|array $field
-     * @param string|int|array|null $condition
-     * @return \Magento\Cms\Model\Resource\Block\Grid\Collection
-     */
-    public function addFieldToFilter($field, $condition = null)
-    {
-        if ($field == 'store_id') {
-            return $this->addStoreFilter($condition, false);
-        }
-        return parent::addFieldToFilter($field, $condition);
-    }
-
-    /**
-     * Define resource model
-     *
-     * @return void
-     */
-    protected function _construct()
-    {
-        $this->_init('Magento\Cms\Model\Block', 'Magento\Cms\Model\Resource\Block');
-        $this->_map['fields']['store'] = 'store_table.store_id';
-    }
-
-    /**
-     * Returns pairs block_id - title
-     *
-     * @return array
-     */
-    public function toOptionArray()
-    {
-        return $this->_toOptionArray('block_id', 'title');
-    }
-
-    /**
-     * Add filter by store
-     *
-     * @param int|\Magento\Store\Model\Store $store
-     * @param bool $withAdmin
-     * @return $this
-     */
-    public function addStoreFilter($store, $withAdmin = true)
-    {
-        if ($store instanceof \Magento\Store\Model\Store) {
-            $store = [$store->getId()];
-        }
-
-        if (!is_array($store)) {
-            $store = [$store];
-        }
-
-        if ($withAdmin) {
-            $store[] = \Magento\Store\Model\Store::DEFAULT_STORE_ID;
-        }
-
-        $this->addFilter('store', ['in' => $store], 'public');
-
-        return $this;
-    }
-
-    /**
-     * Get SQL for get record count.
-     * Extra GROUP BY strip added.
-     *
-     * @return \Magento\Framework\DB\Select
-     */
-    public function getSelectCountSql()
-    {
-        $countSelect = parent::getSelectCountSql();
-
-        $countSelect->reset(\Zend_Db_Select::GROUP);
-
-        return $countSelect;
-    }
-
-    /**
-     * Join store relation table if there is store filter
-     *
-     * @return void
-     */
-    protected function _renderFiltersBefore()
-    {
-        if ($this->getFilter('store')) {
-            $this->getSelect()->join(
-                ['store_table' => $this->getTable('cms_block_store')],
-                'main_table.block_id = store_table.block_id',
-                []
-            )->group(
-                'main_table.block_id'
-            );
-        }
-        parent::_renderFiltersBefore();
-    }
-}
diff --git a/app/code/Magento/Cms/Model/Resource/BlockCriteria.php b/app/code/Magento/Cms/Model/Resource/BlockCriteria.php
deleted file mode 100644
index e10c0c0c15d612b6b15e20e6ddc7a194e3b9bbfa..0000000000000000000000000000000000000000
--- a/app/code/Magento/Cms/Model/Resource/BlockCriteria.php
+++ /dev/null
@@ -1,22 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Cms\Model\Resource;
-
-use Magento\Cms\Model\BlockCriteriaInterface;
-
-/**
- * Class BlockCriteria
- */
-class BlockCriteria extends CmsAbstractCriteria implements BlockCriteriaInterface
-{
-    /**
-     * @param string $mapper
-     */
-    public function __construct($mapper = '')
-    {
-        $this->mapperInterfaceName = $mapper ?: 'Magento\Cms\Model\Resource\BlockCriteriaMapper';
-    }
-}
diff --git a/app/code/Magento/Cms/Model/Resource/BlockCriteriaMapper.php b/app/code/Magento/Cms/Model/Resource/BlockCriteriaMapper.php
deleted file mode 100644
index cfa339ad26232172404adb67094aa1ba90010b58..0000000000000000000000000000000000000000
--- a/app/code/Magento/Cms/Model/Resource/BlockCriteriaMapper.php
+++ /dev/null
@@ -1,23 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Cms\Model\Resource;
-
-/**
- * Class BlockCriteriaMapper
- */
-class BlockCriteriaMapper extends CmsCriteriaMapper
-{
-    /**
-     * @inheritdoc
-     */
-    protected function init()
-    {
-        $this->storeTableName = 'cms_block_store';
-        $this->linkFieldName = 'block_id';
-        $this->initResource('Magento\Cms\Model\Resource\Block');
-        parent::init();
-    }
-}
diff --git a/app/code/Magento/Cms/Model/Resource/CmsAbstractCriteria.php b/app/code/Magento/Cms/Model/Resource/CmsAbstractCriteria.php
deleted file mode 100644
index 88068299f8b9b9b68db949d2de672268827f35b6..0000000000000000000000000000000000000000
--- a/app/code/Magento/Cms/Model/Resource/CmsAbstractCriteria.php
+++ /dev/null
@@ -1,30 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Cms\Model\Resource;
-
-use Magento\Framework\Data\AbstractCriteria;
-
-/**
- * Class CmsAbstractCriteria
- */
-class CmsAbstractCriteria extends AbstractCriteria
-{
-    /**
-     * @inheritdoc
-     */
-    public function setFirstStoreFlag($flag = false)
-    {
-        $this->data['first_store_flag'] = $flag;
-    }
-
-    /**
-     * @inheritdoc
-     */
-    public function addStoreFilter($store, $withAdmin = true)
-    {
-        $this->data['store_filter'] = [$store, $withAdmin];
-    }
-}
diff --git a/app/code/Magento/Cms/Model/Resource/CmsCriteriaMapper.php b/app/code/Magento/Cms/Model/Resource/CmsCriteriaMapper.php
deleted file mode 100644
index ffac24c942d62253aed5c41b61564ef26d0fdc3e..0000000000000000000000000000000000000000
--- a/app/code/Magento/Cms/Model/Resource/CmsCriteriaMapper.php
+++ /dev/null
@@ -1,79 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Cms\Model\Resource;
-
-use Magento\Framework\DB\GenericMapper;
-
-/**
- * Class CmsCriteriaMapper
- */
-class CmsCriteriaMapper extends GenericMapper
-{
-    /**
-     * Table which links CMS entity to stores
-     *
-     * @var string
-     */
-    protected $storeTableName;
-
-    /**
-     * @var string
-     */
-    protected $linkFieldName;
-
-    /**
-     * @inheritdoc
-     */
-    protected function init()
-    {
-        $this->map['fields']['store'] = 'store_table.store_id';
-        $this->map['fields']['store_id'] = 'store_table.store_id';
-    }
-
-    /**
-     * Set first store flag
-     *
-     * @param bool $flag
-     * @return void
-     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
-     */
-    public function mapFirstStoreFlag($flag)
-    {
-        // do nothing since handled in collection afterLoad
-    }
-
-    /**
-     * Add filter by store
-     *
-     * @param int|\Magento\Store\Model\Store $store
-     * @param bool $withAdmin
-     * @return void
-     */
-    public function mapStoreFilter($store, $withAdmin)
-    {
-        $this->getSelect()->join(
-            ['store_table' => $this->getTable($this->storeTableName)],
-            "main_table.{$this->linkFieldName} = store_table.{$this->linkFieldName}",
-            []
-        )->group("main_table.{$this->linkFieldName}");
-        if (!is_array($store)) {
-            if ($store instanceof \Magento\Store\Model\Store) {
-                $store = [$store->getId()];
-            } else {
-                $store = [$store];
-            }
-        }
-        if ($withAdmin) {
-            $store[] = \Magento\Store\Model\Store::DEFAULT_STORE_ID;
-        }
-        $field = $this->getMappedField('store');
-        $this->select->where(
-            $this->getConditionSql($field, ['in' => $store]),
-            null,
-            \Magento\Framework\DB\Select::TYPE_CONDITION
-        );
-    }
-}
diff --git a/app/code/Magento/Cms/Model/Resource/Page/Collection.php b/app/code/Magento/Cms/Model/Resource/Page/Collection.php
index 69dc4cfd7558d53b761aa54b03781bac30a3a666..2b8943acb57a50f1e1dba0c87c6f44649d71ebca 100644
--- a/app/code/Magento/Cms/Model/Resource/Page/Collection.php
+++ b/app/code/Magento/Cms/Model/Resource/Page/Collection.php
@@ -5,131 +5,212 @@
  */
 namespace Magento\Cms\Model\Resource\Page;
 
-use Magento\Framework\Data\AbstractSearchResult;
-use Magento\Framework\Data\Collection\EntityFactoryInterface;
-use Magento\Framework\Data\SearchResultIteratorFactory;
-use Magento\Framework\DB\QueryInterface;
-use Magento\Framework\Event\ManagerInterface;
-use Magento\Store\Model\StoreManagerInterface;
-use Magento\Framework\Data\SearchResultProcessorFactory;
-use Magento\Framework\Data\SearchResultProcessor;
-
 /**
  * CMS page collection
+ *
+ * Class Collection
  */
-class Collection extends AbstractSearchResult
+class Collection extends \Magento\Framework\Model\Resource\Db\Collection\AbstractCollection
 {
     /**
-     * @var StoreManagerInterface
+     * Load data for preview flag
+     *
+     * @var bool
      */
-    protected $storeManager;
+    protected $_previewFlag;
 
     /**
-     * @var SearchResultProcessor
+     * Store manager
+     *
+     * @var \Magento\Store\Model\StoreManagerInterface
      */
-    protected $searchResultProcessor;
+    protected $_storeManager;
 
     /**
-     * @param QueryInterface $query
-     * @param EntityFactoryInterface $entityFactory
-     * @param ManagerInterface $eventManager
-     * @param SearchResultIteratorFactory $resultIteratorFactory
+     * @param \Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory
+     * @param \Psr\Log\LoggerInterface $logger
+     * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
+     * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
-     * @param SearchResultProcessorFactory $searchResultProcessorFactory
+     * @param mixed $connection
+     * @param \Magento\Framework\Model\Resource\Db\AbstractDb $resource
      */
     public function __construct(
-        QueryInterface $query,
-        EntityFactoryInterface $entityFactory,
-        ManagerInterface $eventManager,
-        SearchResultIteratorFactory $resultIteratorFactory,
-        StoreManagerInterface $storeManager,
-        SearchResultProcessorFactory $searchResultProcessorFactory
+        \Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory,
+        \Psr\Log\LoggerInterface $logger,
+        \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
+        \Magento\Framework\Event\ManagerInterface $eventManager,
+        \Magento\Store\Model\StoreManagerInterface $storeManager,
+        $connection = null,
+        \Magento\Framework\Model\Resource\Db\AbstractDb $resource = null
     ) {
-        $this->storeManager = $storeManager;
-        $this->searchResultProcessor = $searchResultProcessorFactory->create($this);
-        parent::__construct($query, $entityFactory, $eventManager, $resultIteratorFactory);
+        parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $connection, $resource);
+        $this->_storeManager = $storeManager;
     }
 
     /**
+     * Define resource model
+     *
      * @return void
      */
-    protected function init()
+    protected function _construct()
     {
-        $this->setDataInterfaceName('Magento\Cms\Model\Page');
-        $this->query->addCountSqlSkipPart(\Zend_Db_Select::GROUP, true);
-        $this->storeTableName = 'cms_page_store';
-        $this->linkFieldName = 'page_id';
+        $this->_init('Magento\Cms\Model\Page', 'Magento\Cms\Model\Resource\Page');
+        $this->_map['fields']['page_id'] = 'main_table.page_id';
+        $this->_map['fields']['store'] = 'store_table.store_id';
     }
 
     /**
+     * Returns pairs identifier - title for unique identifiers
+     * and pairs identifier|page_id - title for non-unique after first
+     *
      * @return array
      */
     public function toOptionIdArray()
     {
         $res = [];
         $existingIdentifiers = [];
-        foreach ($this->getItems() as $item) {
-            /** @var PageInterface $item */
-            $identifier = $item->getIdentifier();
+        foreach ($this as $item) {
+            $identifier = $item->getData('identifier');
 
             $data['value'] = $identifier;
-            $data['label'] = $item->getTitle();
+            $data['label'] = $item->getData('title');
 
             if (in_array($identifier, $existingIdentifiers)) {
-                $data['value'] .= '|' . $item->getPageId();
+                $data['value'] .= '|' . $item->getData('page_id');
             } else {
                 $existingIdentifiers[] = $identifier;
             }
+
             $res[] = $data;
         }
+
         return $res;
     }
 
     /**
-     * @deprecated
-     * @return void
+     * Set first store flag
+     *
+     * @param bool $flag
+     * @return $this
+     */
+    public function setFirstStoreFlag($flag = false)
+    {
+        $this->_previewFlag = $flag;
+        return $this;
+    }
+
+    /**
+     * Add field filter to collection
+     *
+     * @param string|array $field
+     * @param string|int|array|null $condition
+     * @return \Magento\Cms\Model\Resource\Block\Collection
+     */
+    public function addFieldToFilter($field, $condition = null)
+    {
+        if ($field === 'store_id') {
+            return $this->addStoreFilter($condition, false);
+        }
+
+        return parent::addFieldToFilter($field, $condition);
+    }
+
+    /**
+     * Add filter by store
+     *
+     * @param int|\Magento\Store\Model\Store $store
+     * @param bool $withAdmin
+     * @return $this
      */
-    public function addStoreFilter()
+    public function addStoreFilter($store, $withAdmin = true)
     {
-        //
+        if (!$this->getFlag('store_filter_added')) {
+            if ($store instanceof \Magento\Store\Model\Store) {
+                $store = [$store->getId()];
+            }
+
+            if (!is_array($store)) {
+                $store = [$store];
+            }
+
+            if ($withAdmin) {
+                $store[] = \Magento\Store\Model\Store::DEFAULT_STORE_ID;
+            }
+
+            $this->addFilter('store', ['in' => $store], 'public');
+        }
+        return $this;
     }
 
     /**
      * Perform operations after collection load
      *
-     * @return void
+     * @return $this
      */
-    protected function afterLoad()
+    protected function _afterLoad()
     {
-        if ($this->getSearchCriteria()->getPart('first_store_flag')) {
-            $items = $this->searchResultProcessor->getColumnValues('page_id');
-
-            $connection = $this->getQuery()->getConnection();
-            $resource = $this->getQuery()->getResource();
-            if (count($items)) {
-                $select = $connection->select()->from(['cps' => $resource->getTable('cms_page_store')])
-                    ->where('cps.page_id IN (?)', $items);
-                if ($result = $connection->fetchPairs($select)) {
-                    foreach ($this->getItems() as $item) {
-                        /** @var PageInterface $item */
-                        if (!isset($result[$item->getPageId()])) {
-                            continue;
-                        }
-                        if ($result[$item->getPageId()] == 0) {
-                            $stores = $this->storeManager->getStores(false, true);
-                            $storeId = current($stores)->getId();
-                            $storeCode = key($stores);
-                        } else {
-                            $storeId = $result[$item->getPageId()];
-                            $storeCode = $this->storeManager->getStore($storeId)->getCode();
-                        }
-                        $item->setData('_first_store_id', $storeId);
-                        $item->setData('store_code', $storeCode);
-                        $item->setData('store_id', [$result[$item->getPageId()]]);
+        $items = $this->getColumnValues('page_id');
+        if (count($items)) {
+            $connection = $this->getConnection();
+            $select = $connection->select()->from(['cps' => $this->getTable('cms_page_store')])
+                ->where('cps.page_id IN (?)', $items);
+            $result = $connection->fetchPairs($select);
+            if ($result) {
+                foreach ($this as $item) {
+                    $pageId = $item->getData('page_id');
+                    if (!isset($result[$pageId])) {
+                        continue;
+                    }
+                    if ($result[$pageId] == 0) {
+                        $stores = $this->_storeManager->getStores(false, true);
+                        $storeId = current($stores)->getId();
+                        $storeCode = key($stores);
+                    } else {
+                        $storeId = $result[$item->getData('page_id')];
+                        $storeCode = $this->_storeManager->getStore($storeId)->getCode();
                     }
+                    $item->setData('_first_store_id', $storeId);
+                    $item->setData('store_code', $storeCode);
+                    $item->setData('store_id', [$result[$pageId]]);
                 }
             }
         }
-        parent::afterLoad();
+
+        $this->_previewFlag = false;
+        return parent::_afterLoad();
+    }
+
+    /**
+     * Join store relation table if there is store filter
+     *
+     * @return void
+     */
+    protected function _renderFiltersBefore()
+    {
+        if ($this->getFilter('store')) {
+            $this->getSelect()->join(
+                ['store_table' => $this->getTable('cms_page_store')],
+                'main_table.page_id = store_table.page_id',
+                []
+            )->group(
+                'main_table.page_id'
+            );
+        }
+        parent::_renderFiltersBefore();
+    }
+
+    /**
+     * Get SQL for get record count.
+     * Extra GROUP BY strip added.
+     *
+     * @return \Magento\Framework\DB\Select
+     */
+    public function getSelectCountSql()
+    {
+        $countSelect = parent::getSelectCountSql();
+        $countSelect->reset(\Zend_Db_Select::GROUP);
+
+        return $countSelect;
     }
 }
diff --git a/app/code/Magento/Cms/Model/Resource/Page/Grid/Collection.php b/app/code/Magento/Cms/Model/Resource/Page/Grid/Collection.php
deleted file mode 100644
index 41402e0ed343f197fa58b3f10d6bf55bf302fcdc..0000000000000000000000000000000000000000
--- a/app/code/Magento/Cms/Model/Resource/Page/Grid/Collection.php
+++ /dev/null
@@ -1,216 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Cms\Model\Resource\Page\Grid;
-
-/**
- * CMS page collection
- *
- * Class Collection
- */
-class Collection extends \Magento\Framework\Model\Resource\Db\Collection\AbstractCollection
-{
-    /**
-     * Load data for preview flag
-     *
-     * @var bool
-     */
-    protected $_previewFlag;
-
-    /**
-     * Store manager
-     *
-     * @var \Magento\Store\Model\StoreManagerInterface
-     */
-    protected $_storeManager;
-
-    /**
-     * @param \Magento\Framework\Data\Collection\EntityFactory $entityFactory
-     * @param \Psr\Log\LoggerInterface $logger
-     * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
-     * @param \Magento\Framework\Event\ManagerInterface $eventManager
-     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
-     * @param mixed $connection
-     * @param \Magento\Framework\Model\Resource\Db\AbstractDb $resource
-     */
-    public function __construct(
-        \Magento\Framework\Data\Collection\EntityFactory $entityFactory,
-        \Psr\Log\LoggerInterface $logger,
-        \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
-        \Magento\Framework\Event\ManagerInterface $eventManager,
-        \Magento\Store\Model\StoreManagerInterface $storeManager,
-        $connection = null,
-        \Magento\Framework\Model\Resource\Db\AbstractDb $resource = null
-    ) {
-        parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $connection, $resource);
-        $this->_storeManager = $storeManager;
-    }
-
-    /**
-     * Define resource model
-     *
-     * @return void
-     */
-    protected function _construct()
-    {
-        $this->_init('Magento\Cms\Model\Page', 'Magento\Cms\Model\Resource\Page');
-        $this->_map['fields']['page_id'] = 'main_table.page_id';
-        $this->_map['fields']['store'] = 'store_table.store_id';
-    }
-
-    /**
-     * Returns pairs identifier - title for unique identifiers
-     * and pairs identifier|page_id - title for non-unique after first
-     *
-     * @return array
-     */
-    public function toOptionIdArray()
-    {
-        $res = [];
-        $existingIdentifiers = [];
-        foreach ($this as $item) {
-            $identifier = $item->getData('identifier');
-
-            $data['value'] = $identifier;
-            $data['label'] = $item->getData('title');
-
-            if (in_array($identifier, $existingIdentifiers)) {
-                $data['value'] .= '|' . $item->getData('page_id');
-            } else {
-                $existingIdentifiers[] = $identifier;
-            }
-
-            $res[] = $data;
-        }
-
-        return $res;
-    }
-
-    /**
-     * Set first store flag
-     *
-     * @param bool $flag
-     * @return $this
-     */
-    public function setFirstStoreFlag($flag = false)
-    {
-        $this->_previewFlag = $flag;
-        return $this;
-    }
-
-    /**
-     * Add field filter to collection
-     *
-     * @param string|array $field
-     * @param string|int|array|null $condition
-     * @return \Magento\Cms\Model\Resource\Block\Grid\Collection
-     */
-    public function addFieldToFilter($field, $condition = null)
-    {
-        if ($field === 'store_id') {
-            return $this->addStoreFilter($condition, false);
-        }
-
-        return parent::addFieldToFilter($field, $condition);
-    }
-
-    /**
-     * Add filter by store
-     *
-     * @param int|\Magento\Store\Model\Store $store
-     * @param bool $withAdmin
-     * @return $this
-     */
-    public function addStoreFilter($store, $withAdmin = true)
-    {
-        if (!$this->getFlag('store_filter_added')) {
-            if ($store instanceof \Magento\Store\Model\Store) {
-                $store = [$store->getId()];
-            }
-
-            if (!is_array($store)) {
-                $store = [$store];
-            }
-
-            if ($withAdmin) {
-                $store[] = \Magento\Store\Model\Store::DEFAULT_STORE_ID;
-            }
-
-            $this->addFilter('store', ['in' => $store], 'public');
-        }
-        return $this;
-    }
-
-    /**
-     * Perform operations after collection load
-     *
-     * @return $this
-     */
-    protected function _afterLoad()
-    {
-        $items = $this->getColumnValues('page_id');
-        if (count($items)) {
-            $connection = $this->getConnection();
-            $select = $connection->select()->from(['cps' => $this->getTable('cms_page_store')])
-                ->where('cps.page_id IN (?)', $items);
-            $result = $connection->fetchPairs($select);
-            if ($result) {
-                foreach ($this as $item) {
-                    $pageId = $item->getData('page_id');
-                    if (!isset($result[$pageId])) {
-                        continue;
-                    }
-                    if ($result[$pageId] == 0) {
-                        $stores = $this->_storeManager->getStores(false, true);
-                        $storeId = current($stores)->getId();
-                        $storeCode = key($stores);
-                    } else {
-                        $storeId = $result[$item->getData('page_id')];
-                        $storeCode = $this->_storeManager->getStore($storeId)->getCode();
-                    }
-                    $item->setData('_first_store_id', $storeId);
-                    $item->setData('store_code', $storeCode);
-                    $item->setData('store_id', [$result[$pageId]]);
-                }
-            }
-        }
-
-        $this->_previewFlag = false;
-        return parent::_afterLoad();
-    }
-
-    /**
-     * Join store relation table if there is store filter
-     *
-     * @return void
-     */
-    protected function _renderFiltersBefore()
-    {
-        if ($this->getFilter('store')) {
-            $this->getSelect()->join(
-                ['store_table' => $this->getTable('cms_page_store')],
-                'main_table.page_id = store_table.page_id',
-                []
-            )->group(
-                'main_table.page_id'
-            );
-        }
-        parent::_renderFiltersBefore();
-    }
-
-    /**
-     * Get SQL for get record count.
-     * Extra GROUP BY strip added.
-     *
-     * @return \Magento\Framework\DB\Select
-     */
-    public function getSelectCountSql()
-    {
-        $countSelect = parent::getSelectCountSql();
-        $countSelect->reset(\Zend_Db_Select::GROUP);
-
-        return $countSelect;
-    }
-}
diff --git a/app/code/Magento/Cms/Model/Resource/PageCriteria.php b/app/code/Magento/Cms/Model/Resource/PageCriteria.php
deleted file mode 100644
index 87cf04da8372198db34367c3f06424ac7b045efc..0000000000000000000000000000000000000000
--- a/app/code/Magento/Cms/Model/Resource/PageCriteria.php
+++ /dev/null
@@ -1,52 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Cms\Model\Resource;
-
-use Magento\Cms\Model\PageCriteriaInterface;
-
-/**
- * Class PageCriteria
- */
-class PageCriteria extends CmsAbstractCriteria implements PageCriteriaInterface
-{
-    /**
-     * @param string $mapper
-     */
-    public function __construct($mapper = '')
-    {
-        $this->mapperInterfaceName = $mapper ?: 'Magento\Cms\Model\Resource\PageCriteriaMapper';
-    }
-
-    /**
-     * @inheritdoc
-     */
-    public function setFirstStoreFlag($flag = false)
-    {
-        $this->data['first_store_flag'] = $flag;
-        return true;
-    }
-
-    /**
-     * @inheritdoc
-     */
-    public function addStoreFilter($store, $withAdmin = true)
-    {
-        $this->data['store_filter'] = [$store, $withAdmin];
-        return true;
-    }
-
-    /**
-     * Add Criteria object
-     *
-     * @param \Magento\Cms\Model\Resource\PageCriteria $criteria
-     * @return bool
-     */
-    public function addCriteria(\Magento\Cms\Model\Resource\PageCriteria $criteria)
-    {
-        $this->data[self::PART_CRITERIA_LIST]['list'][] = $criteria;
-        return true;
-    }
-}
diff --git a/app/code/Magento/Cms/Model/Resource/PageCriteriaMapper.php b/app/code/Magento/Cms/Model/Resource/PageCriteriaMapper.php
deleted file mode 100644
index 2c1aa20b396eacf22c2fdc10224e1e97ccccd8a6..0000000000000000000000000000000000000000
--- a/app/code/Magento/Cms/Model/Resource/PageCriteriaMapper.php
+++ /dev/null
@@ -1,23 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Cms\Model\Resource;
-
-/**
- * Class PageCriteriaMapper
- */
-class PageCriteriaMapper extends CmsCriteriaMapper
-{
-    /**
-     * @inheritdoc
-     */
-    protected function init()
-    {
-        $this->storeTableName = 'cms_page_store';
-        $this->linkFieldName = 'page_id';
-        $this->initResource('Magento\Cms\Model\Resource\Page');
-        parent::init();
-    }
-}
diff --git a/app/code/Magento/Cms/Test/Unit/Model/BlockRepositoryTest.php b/app/code/Magento/Cms/Test/Unit/Model/BlockRepositoryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..e5c3c9dd155437c9ff54c4a7e3e3312096bfea88
--- /dev/null
+++ b/app/code/Magento/Cms/Test/Unit/Model/BlockRepositoryTest.php
@@ -0,0 +1,300 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Cms\Test\Unit\Model;
+
+use Magento\Cms\Model\BlockRepository;
+use Magento\Framework\Api\SearchCriteriaInterface;
+
+/**
+ * Test for Magento\Cms\Model\BlockRepository
+ */
+class BlockRepositoryTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var BlockRepository
+     */
+    protected $repository;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Cms\Model\Resource\Block
+     */
+    protected $blockResource;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Cms\Model\Block
+     */
+    protected $block;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Cms\Api\Data\BlockInterface
+     */
+    protected $blockData;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Cms\Api\Data\BlockSearchResultsInterface
+     */
+    protected $blockSearchResult;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Api\DataObjectHelper
+     */
+    protected $dataHelper;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Cms\Model\Resource\Block\Collection
+     */
+    protected $collection;
+
+    /**
+     * Initialize repository
+     */
+    public function setUp()
+    {
+        $this->blockResource = $this->getMockBuilder('Magento\Cms\Model\Resource\Block')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $blockFactory = $this->getMockBuilder('Magento\Cms\Model\BlockFactory')
+            ->disableOriginalConstructor()
+            ->setMethods(['create'])
+            ->getMock();
+        $blockDataFactory = $this->getMockBuilder('Magento\Cms\Api\Data\BlockInterfaceFactory')
+            ->disableOriginalConstructor()
+            ->setMethods(['create'])
+            ->getMock();
+        $blockSearchResultFactory = $this->getMockBuilder('Magento\Cms\Api\Data\BlockSearchResultsInterfaceFactory')
+            ->disableOriginalConstructor()
+            ->setMethods(['create'])
+            ->getMock();
+        $collectionFactory = $this->getMockBuilder('Magento\Cms\Model\Resource\Block\CollectionFactory')
+            ->disableOriginalConstructor()
+            ->setMethods(['create'])
+            ->getMock();
+
+        $this->block = $this->getMockBuilder('Magento\Cms\Model\Block')->disableOriginalConstructor()->getMock();
+        $this->blockData = $this->getMockBuilder('Magento\Cms\Api\Data\BlockInterface')
+            ->getMock();
+        $this->blockSearchResult = $this->getMockBuilder('Magento\Cms\Api\Data\BlockSearchResultsInterface')
+            ->getMock();
+        $this->collection = $this->getMockBuilder('Magento\Cms\Model\Resource\Block\Collection')
+            ->disableOriginalConstructor()
+            ->setMethods(['addFieldToFilter', 'getSize', 'setCurPage', 'setPageSize', 'load', 'addOrder'])
+            ->getMock();
+
+        $blockFactory->expects($this->any())
+            ->method('create')
+            ->willReturn($this->block);
+        $blockDataFactory->expects($this->any())
+            ->method('create')
+            ->willReturn($this->blockData);
+        $blockSearchResultFactory->expects($this->any())
+            ->method('create')
+            ->willReturn($this->blockSearchResult);
+        $collectionFactory->expects($this->any())
+            ->method('create')
+            ->willReturn($this->collection);
+        /**
+         * @var \Magento\Cms\Model\BlockFactory $blockFactory
+         * @var \Magento\Cms\Api\Data\BlockInterfaceFactory $blockDataFactory
+         * @var \Magento\Cms\Api\Data\BlockSearchResultsInterfaceFactory $blockSearchResultFactory
+         * @var \Magento\Cms\Model\Resource\Block\CollectionFactory $collectionFactory
+         */
+
+        $this->dataHelper = $this->getMockBuilder('Magento\Framework\Api\DataObjectHelper')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->repository = new BlockRepository(
+            $this->blockResource,
+            $blockFactory,
+            $blockDataFactory,
+            $collectionFactory,
+            $blockSearchResultFactory,
+            $this->dataHelper
+        );
+    }
+
+    /**
+     * @test
+     */
+    public function testSave()
+    {
+        $this->blockResource->expects($this->once())
+            ->method('save')
+            ->with($this->block)
+            ->willReturnSelf();
+        $this->assertEquals($this->block, $this->repository->save($this->block));
+    }
+
+    /**
+     * @test
+     */
+    public function testDeleteById()
+    {
+        $blockId = '123';
+
+        $this->block->expects($this->once())
+            ->method('getId')
+            ->willReturn(true);
+        $this->blockResource->expects($this->once())
+            ->method('load')
+            ->with($this->block, $blockId)
+            ->willReturn($this->block);
+        $this->blockResource->expects($this->once())
+            ->method('delete')
+            ->with($this->block)
+            ->willReturnSelf();
+
+        $this->assertTrue($this->repository->deleteById($blockId));
+    }
+
+    /**
+     * @test
+     *
+     * @expectedException \Magento\Framework\Exception\CouldNotSaveException
+     */
+    public function testSaveException()
+    {
+        $this->blockResource->expects($this->once())
+            ->method('save')
+            ->with($this->block)
+            ->willThrowException(new \Exception());
+        $this->repository->save($this->block);
+    }
+
+    /**
+     * @test
+     *
+     * @expectedException \Magento\Framework\Exception\CouldNotDeleteException
+     */
+    public function testDeleteException()
+    {
+        $this->blockResource->expects($this->once())
+            ->method('delete')
+            ->with($this->block)
+            ->willThrowException(new \Exception());
+        $this->repository->delete($this->block);
+    }
+
+    /**
+     * @test
+     *
+     * @expectedException \Magento\Framework\Exception\NoSuchEntityException
+     */
+    public function testGetByIdException()
+    {
+        $blockId = '123';
+
+        $this->block->expects($this->once())
+            ->method('getId')
+            ->willReturn(false);
+        $this->blockResource->expects($this->once())
+            ->method('load')
+            ->with($this->block, $blockId)
+            ->willReturn($this->block);
+        $this->repository->getById($blockId);
+    }
+
+    /**
+     * @test
+     */
+    public function testGetList()
+    {
+        $field = 'name';
+        $value = 'magento';
+        $condition = 'eq';
+        $total = 10;
+        $currentPage = 3;
+        $pageSize = 2;
+        $sortField = 'id';
+
+        $criteria = $this->getMockBuilder('Magento\Framework\Api\SearchCriteriaInterface')->getMock();
+        $filterGroup = $this->getMockBuilder('Magento\Framework\Api\Search\FilterGroup')->getMock();
+        $filter = $this->getMockBuilder('Magento\Framework\Api\Filter')->getMock();
+        $storeFilter = $this->getMockBuilder('Magento\Framework\Api\Filter')->getMock();
+        $sortOrder = $this->getMockBuilder('Magento\Framework\Api\SortOrder')->getMock();
+
+        $criteria->expects($this->once())
+            ->method('getFilterGroups')
+            ->willReturn([$filterGroup]);
+        $criteria->expects($this->once())
+            ->method('getSortOrders')
+            ->willReturn([$sortOrder]);
+        $criteria->expects($this->once())
+            ->method('getCurrentPage')
+            ->willReturn($currentPage);
+        $criteria->expects($this->once())
+            ->method('getPageSize')
+            ->willReturn($pageSize);
+        $filterGroup->expects($this->once())
+            ->method('getFilters')
+            ->willReturn([$storeFilter, $filter]);
+        $filter->expects($this->once())
+            ->method('getConditionType')
+            ->willReturn($condition);
+        $filter->expects($this->any())
+            ->method('getField')
+            ->willReturn($field);
+        $filter->expects($this->once())
+            ->method('getValue')
+            ->willReturn($value);
+        $storeFilter->expects($this->any())
+            ->method('getField')
+            ->willReturn('store_id');
+        $storeFilter->expects($this->once())
+            ->method('getValue')
+            ->willReturn(1);
+        $sortOrder->expects($this->once())
+            ->method('getField')
+            ->willReturn($sortField);
+        $sortOrder->expects($this->once())
+            ->method('getDirection')
+            ->willReturn(SearchCriteriaInterface::SORT_DESC);
+
+        /** @var \Magento\Framework\Api\SearchCriteriaInterface $criteria */
+
+        $this->collection->addItem($this->block);
+        $this->blockSearchResult->expects($this->once())
+            ->method('setSearchCriteria')
+            ->with($criteria)
+            ->willReturnSelf();
+        $this->collection->expects($this->once())
+            ->method('addFieldToFilter')
+            ->with([['attribute' => $field, $condition => $value]], [])
+            ->willReturnSelf();
+        $this->blockSearchResult->expects($this->once())
+            ->method('setTotalCount')
+            ->with($total)
+            ->willReturnSelf();
+        $this->collection->expects($this->once())
+            ->method('getSize')
+            ->willReturn($total);
+        $this->collection->expects($this->once())
+            ->method('setCurPage')
+            ->with($currentPage)
+            ->willReturnSelf();
+        $this->collection->expects($this->once())
+            ->method('setPageSize')
+            ->with($pageSize)
+            ->willReturnSelf();
+        $this->collection->expects($this->once())
+            ->method('addOrder')
+            ->with($sortField, 'DESC')
+            ->willReturnSelf();
+        $this->block->expects($this->once())
+            ->method('getData')
+            ->willReturn(['data']);
+        $this->blockSearchResult->expects($this->once())
+            ->method('setItems')
+            ->with(['someData'])
+            ->willReturnSelf();
+        $this->dataHelper->expects($this->once())
+            ->method('populateWithArray')
+            ->with($this->blockData, ['data'], 'Magento\Cms\Api\Data\BlockInterface')
+            ->willReturn('someData');
+
+        $this->assertEquals($this->blockSearchResult, $this->repository->getList($criteria));
+    }
+}
diff --git a/app/code/Magento/Cms/Test/Unit/Model/Config/Source/PageTest.php b/app/code/Magento/Cms/Test/Unit/Model/Config/Source/PageTest.php
index 234de25b3a6866038240be08d00d6fbc2da77370..a4602ea501dc26e141aa9003b763bd33ac7c745e 100644
--- a/app/code/Magento/Cms/Test/Unit/Model/Config/Source/PageTest.php
+++ b/app/code/Magento/Cms/Test/Unit/Model/Config/Source/PageTest.php
@@ -11,14 +11,9 @@ namespace Magento\Cms\Test\Unit\Model\Config\Source;
 class PageTest extends \PHPUnit_Framework_TestCase
 {
     /**
-     * @var \Magento\Cms\Model\PageRepository|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\Cms\Model\Resource\Page\CollectionFactory|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $pageRepositoryMock;
-
-    /**
-     * @var \Magento\Cms\Model\Resource\PageCriteria|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $pageCriteriaFactoryMock;
+    protected $collectionFactory;
 
     /**
      * @var \Magento\Cms\Model\Config\Source\Page
@@ -34,15 +29,8 @@ class PageTest extends \PHPUnit_Framework_TestCase
     {
         $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
 
-        $this->pageRepositoryMock = $this->getMock(
-            'Magento\Cms\Model\PageRepository',
-            [],
-            [],
-            '',
-            false
-        );
-        $this->pageCriteriaFactoryMock = $this->getMock(
-            'Magento\Cms\Model\Resource\PageCriteriaFactory',
+        $this->collectionFactory = $this->getMock(
+            'Magento\Cms\Model\Resource\Page\CollectionFactory',
             ['create'],
             [],
             '',
@@ -52,8 +40,7 @@ class PageTest extends \PHPUnit_Framework_TestCase
         $this->page = $objectManager->getObject(
             'Magento\Cms\Model\Config\Source\Page',
             [
-                'pageRepository' => $this->pageRepositoryMock,
-                'pageCriteriaFactory' => $this->pageCriteriaFactoryMock
+                'collectionFactory' => $this->collectionFactory,
             ]
         );
     }
@@ -72,22 +59,10 @@ class PageTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
-        $pageCriteriaMock = $this->getMock(
-            'Magento\Cms\Model\Resource\PageCriteria',
-            [],
-            [],
-            '',
-            false
-        );
-
-        $this->pageRepositoryMock->expects($this->once())
-            ->method('getList')
-            ->with($pageCriteriaMock)
-            ->will($this->returnValue($pageCollectionMock));
 
-        $this->pageCriteriaFactoryMock->expects($this->once())
+        $this->collectionFactory->expects($this->once())
             ->method('create')
-            ->will($this->returnValue($pageCriteriaMock));
+            ->will($this->returnValue($pageCollectionMock));
 
         $pageCollectionMock->expects($this->once())
             ->method('toOptionIdArray')
diff --git a/app/code/Magento/Cms/Test/Unit/Model/DataSource/PageCollectionTest.php b/app/code/Magento/Cms/Test/Unit/Model/DataSource/PageCollectionTest.php
deleted file mode 100644
index 227a7c2280ccc75e1b0a457fb5f2119b0794072b..0000000000000000000000000000000000000000
--- a/app/code/Magento/Cms/Test/Unit/Model/DataSource/PageCollectionTest.php
+++ /dev/null
@@ -1,106 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Cms\Test\Unit\Model\DataSource;
-
-/**
- * Class PageCollectionTest
- */
-class PageCollectionTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\Cms\Model\Resource\PageCriteria|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $criteriaMock;
-
-    /**
-     * @var \Magento\Cms\Model\PageRepository|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $repositoryMock;
-
-    /**
-     * @var \Magento\Cms\Model\DataSource\PageCollection
-     */
-    protected $pageCollection;
-
-    /**
-     * Set up
-     *
-     * @return void
-     */
-    protected function setUp()
-    {
-        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
-        $this->repositoryMock = $this->getMock(
-            'Magento\Cms\Model\PageRepository',
-            [],
-            [],
-            '',
-            false
-        );
-
-        $this->pageCollection = $objectManager->getObject(
-            'Magento\Cms\Model\DataSource\PageCollection',
-            [
-                'repository' => $this->repositoryMock,
-                'mapper' => ''
-            ]
-        );
-    }
-
-    /**
-     * Run test addFilter method
-     *
-     * @param string $name
-     * @param string $field
-     * @param mixed $condition
-     * @param string $type
-     * @return void
-     *
-     * @dataProvider dataProviderAddFilter
-     */
-    public function testAddFilter($name, $field, $condition, $type)
-    {
-        $this->pageCollection->addFilter($name, $field, $condition, $type);
-    }
-
-    /**
-     * Run test getResultCollection method
-     *
-     * @return void
-     */
-    public function testGetResultCollection()
-    {
-        $this->repositoryMock->expects($this->once())
-            ->method('getList')
-            ->with($this->pageCollection)
-            ->will($this->returnValue('return-value'));
-
-        $this->assertEquals('return-value', $this->pageCollection->getResultCollection());
-    }
-
-    /**
-     * Data provider for addFilter method
-     *
-     * @return array
-     */
-    public function dataProviderAddFilter()
-    {
-        return [
-            [
-                'name' => 'test-name',
-                'field' => 'store_id',
-                'condition' => null,
-                'type' => 'public',
-            ],
-            [
-                'name' => 'test-name',
-                'field' => 'any_field',
-                'condition' => 10,
-                'type' => 'private'
-            ]
-        ];
-    }
-}
diff --git a/app/code/Magento/Cms/Test/Unit/Model/PageRepositoryTest.php b/app/code/Magento/Cms/Test/Unit/Model/PageRepositoryTest.php
index d300268f7ab044c6228031707df86c8dd1d29f43..a5127dc51823910b45ebcc68d6c1cca26e53541a 100644
--- a/app/code/Magento/Cms/Test/Unit/Model/PageRepositoryTest.php
+++ b/app/code/Magento/Cms/Test/Unit/Model/PageRepositoryTest.php
@@ -5,261 +5,296 @@
  */
 namespace Magento\Cms\Test\Unit\Model;
 
+use Magento\Cms\Model\PageRepository;
+use Magento\Framework\Api\SearchCriteriaInterface;
+
 /**
- * Class PageRepositoryTest
+ * Test for Magento\Cms\Model\PageRepository
  */
 class PageRepositoryTest extends \PHPUnit_Framework_TestCase
 {
     /**
-     * @var \Magento\Cms\Model\Resource\Page|\PHPUnit_Framework_MockObject_MockObject
+     * @var PageRepository
      */
-    protected $resourceMock;
+    protected $repository;
 
     /**
-     * @var \Magento\Cms\Model\PageFactory|\PHPUnit_Framework_MockObject_MockObject
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Cms\Model\Resource\Page
      */
-    protected $pageFactoryMock;
+    protected $pageResource;
 
     /**
-     * @var \Magento\Cms\Model\Resource\Page\CollectionFactory|\PHPUnit_Framework_MockObject_MockObject
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Cms\Model\Page
      */
-    protected $pageCollectionFactoryMock;
+    protected $page;
 
     /**
-     * @var \Magento\Framework\DB\QueryBuilderFactory|\PHPUnit_Framework_MockObject_MockObject
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Cms\Api\Data\PageInterface
      */
-    protected $queryBuilderFactoryMock;
+    protected $pageData;
 
     /**
-     * @var \Magento\Framework\DB\MapperFactory|\PHPUnit_Framework_MockObject_MockObject
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Cms\Api\Data\PageSearchResultsInterface
      */
-    protected $mapperFactoryMock;
+    protected $pageSearchResult;
 
     /**
-     * @var \Magento\Cms\Model\PageRepository
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Api\DataObjectHelper
      */
-    protected $pageRepository;
+    protected $dataHelper;
 
     /**
-     * Set up
-     *
-     * @return void
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Cms\Model\Resource\Page\Collection
      */
-    protected function setUp()
+    protected $collection;
+
+    /**
+     * Initialize repository
+     */
+    public function setUp()
     {
-        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $this->pageResource = $this->getMockBuilder('Magento\Cms\Model\Resource\Page')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $pageFactory = $this->getMockBuilder('Magento\Cms\Model\PageFactory')
+            ->disableOriginalConstructor()
+            ->setMethods(['create'])
+            ->getMock();
+        $pageDataFactory = $this->getMockBuilder('Magento\Cms\Api\Data\PageInterfaceFactory')
+            ->disableOriginalConstructor()
+            ->setMethods(['create'])
+            ->getMock();
+        $pageSearchResultFactory = $this->getMockBuilder('Magento\Cms\Api\Data\PageSearchResultsInterfaceFactory')
+            ->disableOriginalConstructor()
+            ->setMethods(['create'])
+            ->getMock();
+        $collectionFactory = $this->getMockBuilder('Magento\Cms\Model\Resource\Page\CollectionFactory')
+            ->disableOriginalConstructor()
+            ->setMethods(['create'])
+            ->getMock();
 
-        $this->resourceMock = $this->getMock(
-            'Magento\Cms\Model\Resource\Page',
-            ['save', 'load', 'delete'],
-            [],
-            '',
-            false
-        );
-        $this->pageFactoryMock = $this->getMock(
-            'Magento\Cms\Model\PageFactory',
-            ['create'],
-            [],
-            '',
-            false
-        );
-        $this->pageCollectionFactoryMock = $this->getMock(
-            'Magento\Cms\Model\Resource\Page\CollectionFactory',
-            ['create'],
-            [],
-            '',
-            false
-        );
-        $this->queryBuilderFactoryMock = $this->getMock(
-            'Magento\Framework\DB\QueryBuilderFactory',
-            ['create'],
-            [],
-            '',
-            false
-        );
-        $this->mapperFactoryMock = $this->getMock(
-            'Magento\Framework\DB\MapperFactory',
-            [],
-            [],
-            '',
-            false
-        );
+        $this->page = $this->getMockBuilder('Magento\Cms\Model\Page')->disableOriginalConstructor()->getMock();
+        $this->pageData = $this->getMockBuilder('Magento\Cms\Api\Data\PageInterface')
+            ->getMock();
+        $this->pageSearchResult = $this->getMockBuilder('Magento\Cms\Api\Data\PageSearchResultsInterface')
+            ->getMock();
+        $this->collection = $this->getMockBuilder('Magento\Cms\Model\Resource\Page\Collection')
+            ->disableOriginalConstructor()
+            ->setMethods(['addFieldToFilter', 'getSize', 'setCurPage', 'setPageSize', 'load', 'addOrder'])
+            ->getMock();
+
+        $pageFactory->expects($this->any())
+            ->method('create')
+            ->willReturn($this->page);
+        $pageDataFactory->expects($this->any())
+            ->method('create')
+            ->willReturn($this->pageData);
+        $pageSearchResultFactory->expects($this->any())
+            ->method('create')
+            ->willReturn($this->pageSearchResult);
+        $collectionFactory->expects($this->any())
+            ->method('create')
+            ->willReturn($this->collection);
+        /**
+         * @var \Magento\Cms\Model\PageFactory $pageFactory
+         * @var \Magento\Cms\Api\Data\PageInterfaceFactory $pageDataFactory
+         * @var \Magento\Cms\Api\Data\PageSearchResultsInterfaceFactory $pageSearchResultFactory
+         * @var \Magento\Cms\Model\Resource\Page\CollectionFactory $collectionFactory
+         */
+
+        $this->dataHelper = $this->getMockBuilder('Magento\Framework\Api\DataObjectHelper')
+            ->disableOriginalConstructor()
+            ->getMock();
 
-        $this->pageRepository = $objectManager->getObject(
-            'Magento\Cms\Model\PageRepository',
-            [
-                'resource' => $this->resourceMock,
-                'pageFactory' => $this->pageFactoryMock,
-                'pageCollectionFactory' => $this->pageCollectionFactoryMock,
-                'queryBuilderFactory' => $this->queryBuilderFactoryMock,
-                'mapperFactory' => $this->mapperFactoryMock
-            ]
+        $this->repository = new PageRepository(
+            $this->pageResource,
+            $pageFactory,
+            $pageDataFactory,
+            $collectionFactory,
+            $pageSearchResultFactory,
+            $this->dataHelper
         );
     }
 
     /**
-     * Run test save method
-     *
-     * @return void
+     * @test
      */
     public function testSave()
     {
-        $pageMock = $this->getMock(
-            'Magento\Cms\Model\Page',
-            [],
-            [],
-            '',
-            false
-        );
-
-        $this->resourceMock->expects($this->once())
+        $this->pageResource->expects($this->once())
             ->method('save')
-            ->with($pageMock);
-
-        $this->assertEquals($pageMock, $this->pageRepository->save($pageMock));
+            ->with($this->page)
+            ->willReturnSelf();
+        $this->assertEquals($this->page, $this->repository->save($this->page));
     }
 
     /**
-     * Run test get method
-     *
-     * @return void
+     * @test
      */
-    public function testGet()
+    public function testDeleteById()
     {
-        $id = 20;
-        $pageMock = $this->getMockForAbstractClass(
-            'Magento\Cms\Model\Page',
-            [],
-            '',
-            false,
-            true,
-            true,
-            ['getId']
-        );
+        $pageId = '123';
 
-        $pageMock->expects($this->atLeastOnce())
+        $this->page->expects($this->once())
             ->method('getId')
-            ->will($this->returnValue($id));
-        $this->pageFactoryMock->expects($this->once())
-            ->method('create')
-            ->will($this->returnValue($pageMock));
-        $this->resourceMock->expects($this->once())
+            ->willReturn(true);
+        $this->pageResource->expects($this->once())
             ->method('load')
-            ->with($pageMock, $id);
+            ->with($this->page, $pageId)
+            ->willReturn($this->page);
+        $this->pageResource->expects($this->once())
+            ->method('delete')
+            ->with($this->page)
+            ->willReturnSelf();
 
-        $this->assertEquals($pageMock, $this->pageRepository->get($id));
+        $this->assertTrue($this->repository->deleteById($pageId));
     }
 
     /**
-     * Run test getList method
+     * @test
      *
-     * @return void
+     * @expectedException \Magento\Framework\Exception\CouldNotSaveException
      */
-    public function testGetList()
+    public function testSaveException()
     {
-        $criteriaMock = $this->getMock(
-            'Magento\Cms\Model\Resource\PageCriteria',
-            [],
-            [],
-            '',
-            false
-        );
-        $queryBuilderMock = $this->getMock(
-            'Magento\Framework\DB\QueryBuilder',
-            ['setCriteria', 'setResource', 'create'],
-            [],
-            '',
-            false
-        );
-        $queryMock = $this->getMockForAbstractClass(
-            'Magento\Framework\DB\QueryInterface',
-            [],
-            '',
-            false
-        );
-        $collectionMock = $this->getMock(
-            'Magento\Cms\Model\Resource\Page\Collection',
-            [],
-            [],
-            '',
-            false
-        );
-
-        $this->queryBuilderFactoryMock->expects($this->once())
-            ->method('create')
-            ->will($this->returnValue($queryBuilderMock));
-        $queryBuilderMock->expects($this->once())
-            ->method('setCriteria')
-            ->with($criteriaMock);
-        $queryBuilderMock->expects($this->once())
-            ->method('setResource')
-            ->with($this->resourceMock);
-        $queryBuilderMock->expects($this->once())
-            ->method('create')
-            ->will($this->returnValue($queryMock));
-        $this->pageCollectionFactoryMock->expects($this->once())
-            ->method('create')
-            ->with(['query' => $queryMock])
-            ->will($this->returnValue($collectionMock));
-
-        $this->assertEquals($collectionMock, $this->pageRepository->getList($criteriaMock));
+        $this->pageResource->expects($this->once())
+            ->method('save')
+            ->with($this->page)
+            ->willThrowException(new \Exception());
+        $this->repository->save($this->page);
     }
 
     /**
-     * Run test delete method
+     * @test
      *
-     * @return void
+     * @expectedException \Magento\Framework\Exception\CouldNotDeleteException
      */
-    public function testDelete()
+    public function testDeleteException()
     {
-        $pageMock = $this->getMockForAbstractClass(
-            'Magento\Cms\Model\Page',
-            [],
-            '',
-            false,
-            true,
-            true,
-            ['getPageId']
-        );
-
-        $this->resourceMock->expects($this->once())
+        $this->pageResource->expects($this->once())
             ->method('delete')
-            ->with($pageMock);
-
-        $this->assertTrue($this->pageRepository->delete($pageMock));
+            ->with($this->page)
+            ->willThrowException(new \Exception());
+        $this->repository->delete($this->page);
     }
 
     /**
-     * Run test deleteById method
+     * @test
      *
-     * @return void
+     * @expectedException \Magento\Framework\Exception\NoSuchEntityException
      */
-    public function testDeleteById()
+    public function testGetByIdException()
     {
-        $id = 20;
-        $pageMock = $this->getMockForAbstractClass(
-            'Magento\Cms\Model\Page',
-            [],
-            '',
-            false,
-            true,
-            true,
-            ['getId']
-        );
+        $pageId = '123';
 
-        $this->pageFactoryMock->expects($this->once())
-            ->method('create')
-            ->will($this->returnValue($pageMock));
-        $this->resourceMock->expects($this->once())
-            ->method('load')
-            ->with($pageMock, $id);
-        $pageMock->expects($this->once())
+        $this->page->expects($this->once())
             ->method('getId')
-            ->will($this->returnValue($id));
-        $this->resourceMock->expects($this->once())
-            ->method('delete')
-            ->with($pageMock);
+            ->willReturn(false);
+        $this->pageResource->expects($this->once())
+            ->method('load')
+            ->with($this->page, $pageId)
+            ->willReturn($this->page);
+        $this->repository->getById($pageId);
+    }
+
+    /**
+     * @test
+     */
+    public function testGetList()
+    {
+        $field = 'name';
+        $value = 'magento';
+        $condition = 'eq';
+        $total = 10;
+        $currentPage = 3;
+        $pageSize = 2;
+        $sortField = 'id';
+
+        $criteria = $this->getMockBuilder('Magento\Framework\Api\SearchCriteriaInterface')->getMock();
+        $filterGroup = $this->getMockBuilder('Magento\Framework\Api\Search\FilterGroup')->getMock();
+        $filter = $this->getMockBuilder('Magento\Framework\Api\Filter')->getMock();
+        $storeFilter = $this->getMockBuilder('Magento\Framework\Api\Filter')->getMock();
+        $sortOrder = $this->getMockBuilder('Magento\Framework\Api\SortOrder')->getMock();
+
+        $criteria->expects($this->once())
+            ->method('getFilterGroups')
+            ->willReturn([$filterGroup]);
+        $criteria->expects($this->once())
+            ->method('getSortOrders')
+            ->willReturn([$sortOrder]);
+        $criteria->expects($this->once())
+            ->method('getCurrentPage')
+            ->willReturn($currentPage);
+        $criteria->expects($this->once())
+            ->method('getPageSize')
+            ->willReturn($pageSize);
+        $filterGroup->expects($this->once())
+            ->method('getFilters')
+            ->willReturn([$storeFilter, $filter]);
+        $filter->expects($this->once())
+            ->method('getConditionType')
+            ->willReturn($condition);
+        $filter->expects($this->any())
+            ->method('getField')
+            ->willReturn($field);
+        $filter->expects($this->once())
+            ->method('getValue')
+            ->willReturn($value);
+        $storeFilter->expects($this->any())
+            ->method('getField')
+            ->willReturn('store_id');
+        $storeFilter->expects($this->once())
+            ->method('getValue')
+            ->willReturn(1);
+        $sortOrder->expects($this->once())
+            ->method('getField')
+            ->willReturn($sortField);
+        $sortOrder->expects($this->once())
+            ->method('getDirection')
+            ->willReturn(SearchCriteriaInterface::SORT_DESC);
+
+        /** @var \Magento\Framework\Api\SearchCriteriaInterface $criteria */
+
+        $this->collection->addItem($this->page);
+        $this->pageSearchResult->expects($this->once())
+            ->method('setSearchCriteria')
+            ->with($criteria)
+            ->willReturnSelf();
+        $this->collection->expects($this->once())
+            ->method('addFieldToFilter')
+            ->with([['attribute' => $field, $condition => $value]], [])
+            ->willReturnSelf();
+        $this->pageSearchResult->expects($this->once())
+            ->method('setTotalCount')
+            ->with($total)
+            ->willReturnSelf();
+        $this->collection->expects($this->once())
+            ->method('getSize')
+            ->willReturn($total);
+        $this->collection->expects($this->once())
+            ->method('setCurPage')
+            ->with($currentPage)
+            ->willReturnSelf();
+        $this->collection->expects($this->once())
+            ->method('setPageSize')
+            ->with($pageSize)
+            ->willReturnSelf();
+        $this->collection->expects($this->once())
+            ->method('addOrder')
+            ->with($sortField, 'DESC')
+            ->willReturnSelf();
+        $this->page->expects($this->once())
+            ->method('getData')
+            ->willReturn(['data']);
+        $this->pageSearchResult->expects($this->once())
+            ->method('setItems')
+            ->with(['someData'])
+            ->willReturnSelf();
+        $this->dataHelper->expects($this->once())
+            ->method('populateWithArray')
+            ->with($this->pageData, ['data'], 'Magento\Cms\Api\Data\PageInterface')
+            ->willReturn('someData');
 
-        $this->assertTrue($this->pageRepository->deleteById($id));
+        $this->assertEquals($this->pageSearchResult, $this->repository->getList($criteria));
     }
 }
diff --git a/app/code/Magento/Cms/Test/Unit/Model/Resource/Block/Grid/CollectionTest.php b/app/code/Magento/Cms/Test/Unit/Model/Resource/Block/Grid/CollectionTest.php
index 9db74457f743fa561510a622b3c439472a819085..5b267bc224b84db9894c9416ecc26deac3f8fb4c 100644
--- a/app/code/Magento/Cms/Test/Unit/Model/Resource/Block/Grid/CollectionTest.php
+++ b/app/code/Magento/Cms/Test/Unit/Model/Resource/Block/Grid/CollectionTest.php
@@ -5,7 +5,7 @@
  */
 namespace Magento\Cms\Test\Unit\Model\Resource\Block\Grid;
 
-use Magento\Cms\Model\Resource\Block\Grid\Collection;
+use Magento\Cms\Model\Resource\Block\Collection;
 
 class CollectionTest extends \PHPUnit_Framework_TestCase
 {
@@ -42,11 +42,11 @@ class CollectionTest extends \PHPUnit_Framework_TestCase
 
         $objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
         $arguments = $objectManagerHelper->getConstructArguments(
-            'Magento\Cms\Model\Resource\Block\Grid\Collection',
+            'Magento\Cms\Model\Resource\Block\Collection',
             ['resource' => $resource, 'connection' => $connection]
         );
 
-        $this->collection = $this->getMockBuilder('Magento\Cms\Model\Resource\Block\Grid\Collection')
+        $this->collection = $this->getMockBuilder('Magento\Cms\Model\Resource\Block\Collection')
             ->setConstructorArgs($arguments)
             ->setMethods(['addFilter', '_translateCondition', 'getMainTable'])
             ->getMock();
diff --git a/app/code/Magento/Cms/Test/Unit/Model/Resource/Page/CollectionTest.php b/app/code/Magento/Cms/Test/Unit/Model/Resource/Page/CollectionTest.php
deleted file mode 100644
index 2abd96842cf321873d5d6949bcf80f4d1e954d30..0000000000000000000000000000000000000000
--- a/app/code/Magento/Cms/Test/Unit/Model/Resource/Page/CollectionTest.php
+++ /dev/null
@@ -1,278 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Cms\Test\Unit\Model\Resource\Page;
-
-/**
- * Class CollectionTest
- */
-class CollectionTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $storeManagerMock;
-
-    /**
-     * @var \Magento\Framework\DB\QueryInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $queryMock;
-
-    /**
-     * @var \Magento\Framework\Event\ManagerInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $eventManagerMock;
-
-    /**
-     * @var \Magento\Framework\Data\Collection\EntityFactoryInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $entityFactoryMock;
-
-    /**
-     * @var \Magento\Framework\Data\SearchResultIteratorFactory|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $resultIteratorFactoryMock;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $searchResultProcessorMock;
-
-    /**
-     * @var \Magento\Cms\Model\Resource\Page\Collection
-     */
-    protected $collection;
-
-    /**
-     * Set up
-     *
-     * @return void
-     */
-    protected function setUp()
-    {
-        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
-
-        $this->queryMock = $this->getMockForAbstractClass(
-            'Magento\Framework\DB\QueryInterface',
-            [],
-            '',
-            false,
-            true,
-            true,
-            ['fetchAll', 'getIdFieldName', 'getConnection', 'getResource']
-        );
-        $this->entityFactoryMock = $this->getMockForAbstractClass(
-            'Magento\Framework\Data\Collection\EntityFactoryInterface',
-            [],
-            '',
-            false,
-            true,
-            true,
-            []
-        );
-        $this->eventManagerMock = $this->getMockForAbstractClass(
-            'Magento\Framework\Event\ManagerInterface',
-            [],
-            '',
-            false,
-            true,
-            true,
-            ['dispatch']
-        );
-        $this->resultIteratorFactoryMock = $this->getMock(
-            'Magento\Framework\Data\SearchResultIteratorFactory',
-            [],
-            [],
-            '',
-            false
-        );
-        $this->searchResultProcessorMock = $this->getMock(
-            'Magento\Framework\Data\SearchResultProcessor',
-            [],
-            [],
-            '',
-            false
-        );
-        $searchResultProcessorFactoryMock = $this->getMock(
-            'Magento\Framework\Data\SearchResultProcessorFactory',
-            [],
-            [],
-            '',
-            false
-        );
-        $searchResultProcessorFactoryMock->expects($this->any())
-            ->method('create')
-            ->withAnyParameters()
-            ->willReturn($this->searchResultProcessorMock);
-        $this->storeManagerMock = $this->getMockForAbstractClass(
-            'Magento\Store\Model\StoreManagerInterface',
-            [],
-            '',
-            false,
-            true,
-            true,
-            ['getStore']
-        );
-
-        $this->collection = $objectManager->getObject(
-            'Magento\Cms\Model\Resource\Page\Collection',
-            [
-                'query' => $this->queryMock,
-                'entityFactory' => $this->entityFactoryMock,
-                'eventManager' => $this->eventManagerMock,
-                'resultIteratorFactory' => $this->resultIteratorFactoryMock,
-                'storeManager' => $this->storeManagerMock,
-                'searchResultProcessorFactory' => $searchResultProcessorFactoryMock
-            ]
-        );
-    }
-
-    /**
-     * Run test toOptionIdArray method
-     *
-     * @return void
-     *
-     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
-     */
-    public function testToOptionIdArray()
-    {
-        $itemsByPageId = array_fill(0, 4, 123);
-        $data = [
-            'item1' => ['test' => 'test'],
-            'item2' => ['test' => 'test'],
-            'item3' => ['test' => 'test'],
-            'item4' => ['test' => 'test'],
-        ];
-
-        $objectMock = $this->getMock(
-            'Magento\Framework\Object',
-            ['getData', 'getId', 'setData', 'getTitle', 'getIdentifier'],
-            [],
-            '',
-            false
-        );
-        $criteriaMock = $this->getMockForAbstractClass('Magento\Framework\Api\CriteriaInterface');
-        $connectionMock = $this->getMockForAbstractClass('Magento\Framework\DB\Adapter\AdapterInterface');
-        $resourceMock = $this->getMockForAbstractClass(
-            'Magento\Framework\Model\Resource\Db\AbstractDb',
-            [],
-            '',
-            false,
-            true,
-            true,
-            ['getTable']
-        );
-        $selectMock = $this->getMock(
-            'Magento\Framework\DB\Select',
-            ['from', 'where'],
-            [],
-            '',
-            false
-        );
-        $storeMock = $this->getMock(
-            'Magento\Store\Model\Store',
-            ['getCode'],
-            [],
-            '',
-            false
-        );
-
-        $this->queryMock->expects($this->once())
-            ->method('fetchAll')
-            ->will($this->returnValue($data));
-
-        $this->searchResultProcessorMock->expects($this->once())
-            ->method('getColumnValues')
-            ->with('page_id')
-            ->will($this->returnValue($itemsByPageId));
-        $this->queryMock->expects($this->any())
-            ->method('getIdFieldName')
-            ->will($this->returnValue('id_field_name'));
-        $objectMock->expects($this->any())
-            ->method('getData')
-            ->will(
-                $this->returnValueMap(
-                    [
-                        ['id_field_name', null, null],
-                        ['page_id', null, 123],
-                    ]
-                )
-            );
-        $this->entityFactoryMock->expects($this->any())
-            ->method('create')
-            ->with('Magento\Cms\Model\Page', ['data' => ['test' => 'test']])
-            ->will($this->returnValue($objectMock));
-        $this->queryMock->expects($this->once())
-            ->method('getCriteria')
-            ->will($this->returnValue($criteriaMock));
-        $criteriaMock->expects($this->once())
-            ->method('getPart')
-            ->with('first_store_flag')
-            ->will($this->returnValue(true));
-        $this->queryMock->expects($this->once())
-            ->method('getConnection')
-            ->will($this->returnValue($connectionMock));
-        $this->queryMock->expects($this->once())
-            ->method('getResource')
-            ->will($this->returnValue($resourceMock));
-        $connectionMock->expects($this->once())
-            ->method('select')
-            ->will($this->returnValue($selectMock));
-        $selectMock->expects($this->once())
-            ->method('from')
-            ->with(['cps' => 'query_table'])
-            ->will($this->returnSelf());
-        $resourceMock->expects($this->once())
-            ->method('getTable')
-            ->with('cms_page_store')
-            ->will($this->returnValue('query_table'));
-        $selectMock->expects($this->once())
-            ->method('where')
-            ->with('cps.page_id IN (?)', array_fill(0, 4, 123))
-            ->will($this->returnSelf());
-        $connectionMock->expects($this->once())
-            ->method('fetchPairs')
-            ->with($selectMock)
-            ->will($this->returnValue([123 => 999]));
-        $objectMock->expects($this->any())
-            ->method('getId')
-            ->will($this->returnValue(123));
-        $this->storeManagerMock->expects($this->any())
-            ->method('getStore')
-            ->with(999)
-            ->will($this->returnValue($storeMock));
-        $storeMock->expects($this->any())
-            ->method('getCode')
-            ->will($this->returnValue('store_code'));
-        $objectMock->expects($this->any())
-            ->method('setData');
-        $objectMock->expects($this->any())
-            ->method('getTitle')
-            ->will($this->returnValue('item-value'));
-        $objectMock->expects($this->any())
-            ->method('getIdentifier')
-            ->will($this->returnValue('identifier-value'));
-
-        $expected = [
-            [
-                'value' => 'identifier-value',
-                'label' => 'item-value',
-            ],
-            [
-                'value' => 'identifier-value|123',
-                'label' => 'item-value'
-            ],
-            [
-                'value' => 'identifier-value|123',
-                'label' => 'item-value'
-            ],
-            [
-                'value' => 'identifier-value|123',
-                'label' => 'item-value'
-            ],
-        ];
-        $this->assertEquals($expected, $this->collection->toOptionIdArray());
-    }
-}
diff --git a/app/code/Magento/Cms/Test/Unit/Model/Resource/PageCriteriaMapperTest.php b/app/code/Magento/Cms/Test/Unit/Model/Resource/PageCriteriaMapperTest.php
deleted file mode 100644
index 19ac623ed6b10f98e592e6308409c401ea961cda..0000000000000000000000000000000000000000
--- a/app/code/Magento/Cms/Test/Unit/Model/Resource/PageCriteriaMapperTest.php
+++ /dev/null
@@ -1,135 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Cms\Test\Unit\Model\Resource;
-
-/**
- * Class PageCriteriaMapperTest
- */
-class PageCriteriaMapperTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $loggerMock;
-
-    /**
-     * @var \Magento\Framework\Data\Collection\Db\FetchStrategyInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $fetchStrategyMock;
-
-    /**
-     * @var \Magento\Framework\Data\ObjectFactory|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $objectFactoryMock;
-
-    /**
-     * @var \Magento\Framework\DB\MapperFactory|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $mapperFactoryMock;
-
-    /**
-     * @var \Magento\Framework\DB\Select|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $selectMock;
-
-    /**
-     * @var \Magento\Cms\Model\Resource\PageCriteriaMapper|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $pageCriteria;
-
-    /**
-     * Set up
-     *
-     * @return void
-     */
-    protected function setUp()
-    {
-        $this->loggerMock = $this->getMock('Psr\Log\LoggerInterface');
-        $this->fetchStrategyMock = $this->getMockForAbstractClass(
-            'Magento\Framework\Data\Collection\Db\FetchStrategyInterface',
-            [],
-            '',
-            false
-        );
-        $this->objectFactoryMock = $this->getMock(
-            'Magento\Framework\Data\ObjectFactory',
-            [],
-            [],
-            '',
-            false
-        );
-        $this->mapperFactoryMock = $this->getMock(
-            'Magento\Framework\DB\MapperFactory',
-            [],
-            [],
-            '',
-            false
-        );
-        $this->selectMock = $this->getMock(
-            'Magento\Framework\DB\Select',
-            ['join', 'group', 'where'],
-            [],
-            '',
-            false
-        );
-
-        $this->pageCriteria = $this->getMockBuilder('Magento\Cms\Model\Resource\PageCriteriaMapper')
-            ->setConstructorArgs(
-                [
-                    'logger' => $this->loggerMock,
-                    'fetchStrategy' => $this->fetchStrategyMock,
-                    'objectFactory' => $this->objectFactoryMock,
-                    'mapperFactory' => $this->mapperFactoryMock,
-                    'select' => $this->selectMock,
-                ]
-            )->setMethods(['init', 'getTable', 'getMappedField', 'getConditionSql'])
-            ->getMock();
-    }
-
-    /**
-     * Run test mapStoreFilter method
-     *
-     * @return void
-     */
-    public function testMapStoreFilter()
-    {
-        $reflection = new \ReflectionClass($this->pageCriteria);
-        $reflectionProperty = $reflection->getProperty('storeTableName');
-        $reflectionProperty->setAccessible(true);
-        $reflectionProperty->setValue($this->pageCriteria, 'cms_page_store');
-        $reflectionProperty = $reflection->getProperty('linkFieldName');
-        $reflectionProperty->setAccessible(true);
-        $reflectionProperty->setValue($this->pageCriteria, 'page_id');
-
-        $this->pageCriteria->expects($this->once())
-            ->method('getTable')
-            ->with('cms_page_store')
-            ->will($this->returnValue('table-name'));
-        $this->pageCriteria->expects($this->once())
-            ->method('getMappedField')
-            ->with('store')
-            ->will($this->returnValue('mapped-field-result'));
-        $this->selectMock->expects($this->once())
-            ->method('join')
-            ->with(
-                ['store_table' => 'table-name'],
-                'main_table.page_id = store_table.page_id',
-                []
-            )->will($this->returnSelf());
-        $this->selectMock->expects($this->once())
-            ->method('group')
-            ->with('main_table.page_id');
-        $this->pageCriteria->expects($this->once())
-            ->method('getConditionSql')
-            ->with('mapped-field-result', ['in' => [1]])
-            ->will($this->returnValue('condition-sql-result'));
-        $this->selectMock->expects($this->once())
-            ->method('where')
-            ->with('condition-sql-result', null, \Magento\Framework\DB\Select::TYPE_CONDITION);
-
-        $this->pageCriteria->mapStoreFilter(1, false);
-    }
-}
diff --git a/app/code/Magento/Cms/composer.json b/app/code/Magento/Cms/composer.json
index bb170a779ef25fc387efcdcb606f631f9dfcf0b5..d98e7df4c6fc084b82a8279bf5d69c2d4c25d446 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-beta1",
-        "magento/module-theme": "0.74.0-beta1",
-        "magento/module-widget": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-catalog": "0.74.0-beta1",
-        "magento/module-email": "0.74.0-beta1",
-        "magento/module-ui": "0.74.0-beta1",
-        "magento/module-variable": "0.74.0-beta1",
-        "magento/module-media-storage": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-theme": "0.74.0-beta2",
+        "magento/module-widget": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/module-email": "0.74.0-beta2",
+        "magento/module-ui": "0.74.0-beta2",
+        "magento/module-variable": "0.74.0-beta2",
+        "magento/module-media-storage": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Cms/etc/di.xml b/app/code/Magento/Cms/etc/di.xml
index 5180d2671ad2e15dab12a891e221812f0665ab74..d25ddfd399e02b299b8cc9be0c901fe03b795f3d 100644
--- a/app/code/Magento/Cms/etc/di.xml
+++ b/app/code/Magento/Cms/etc/di.xml
@@ -6,8 +6,14 @@
  */
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
-    <preference for="Magento\Cms\Model\PageCriteriaInterface" type="Magento\Cms\Model\Resource\PageCriteria" />
-    <preference for="Magento\Cms\Model\BlockCriteriaInterface" type="Magento\Cms\Model\Resource\BlockCriteria" />
+    <preference for="Magento\Cms\Api\Data\PageSearchResultsInterface"
+                type="Magento\Framework\Api\SearchResults" />
+    <preference for="Magento\Cms\Api\Data\BlockSearchResultsInterface"
+                type="Magento\Framework\Api\SearchResults" />
+    <preference for="Magento\Cms\Api\Data\PageInterface" type="Magento\Cms\Model\Page" />
+    <preference for="Magento\Cms\Api\Data\BlockInterface" type="Magento\Cms\Model\Block" />
+    <preference for="Magento\Cms\Api\BlockRepositoryInterface" type="Magento\Cms\Model\BlockRepository" />
+    <preference for="Magento\Cms\Api\PageRepositoryInterface" type="Magento\Cms\Model\PageRepository" />
     <type name="Magento\Cms\Model\Wysiwyg\Config">
         <arguments>
             <argument name="windowSize" xsi:type="array">
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 83f7ab821f23355be1d399dc85244287af31d8bc..6f1975adb97cd11e5032ed1b455183ac0a653f31 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
@@ -10,7 +10,7 @@
         <referenceBlock name="listing">
             <arguments>
                 <argument name="name" xsi:type="string">cms_block_listing</argument>
-                <argument name="dataSource" xsi:type="object">Magento\Cms\Model\DataSource\BlockCollection</argument>
+                <argument name="dataSource" xsi:type="object">Magento\Cms\Model\Resource\Block\Collection</argument>
                 <argument name="save_parameters_in_session" xsi:type="string">1</argument>
                 <argument name="configuration" xsi:type="array">
                     <item name="page_actions" xsi:type="array">
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 48bdecdc6696955d394dc16dc148d4f231b01c6b..bebf23cacd86b98d4f7e4f6c3af734c4cba77515 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
@@ -10,7 +10,7 @@
         <referenceBlock name="listing">
             <arguments>
                 <argument name="name" xsi:type="string">cms_page_listing</argument>
-                <argument name="dataSource" xsi:type="object">Magento\Cms\Model\DataSource\PageCollection</argument>
+                <argument name="dataSource" xsi:type="object">Magento\Cms\Model\Resource\Page\Collection</argument>
                 <argument name="save_parameters_in_session" xsi:type="string">1</argument>
                 <argument name="configuration" xsi:type="array">
                     <item name="page_actions" xsi:type="array">
diff --git a/app/code/Magento/CmsUrlRewrite/composer.json b/app/code/Magento/CmsUrlRewrite/composer.json
index 7f4ce715dab58c3447aa8f84308990613b359ae1..9d32b3444bbb28713fdb769c65b01506cb3dd1ae 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-beta1",
-        "magento/module-cms": "0.74.0-beta1",
-        "magento/module-url-rewrite": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-cms": "0.74.0-beta2",
+        "magento/module-url-rewrite": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Config/composer.json b/app/code/Magento/Config/composer.json
index f67e70b620e702c1490466ca08f342f94db2da28..72d17066f3299561cd531e7a1a27f32330c58830 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-beta1",
-        "magento/module-store": "0.74.0-beta1",
-        "magento/module-cron": "0.74.0-beta1",
-        "magento/module-email": "0.74.0-beta1",
-        "magento/module-directory": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-media-storage": "0.74.0-beta1",
+        "magento/framework": "0.74.0-beta2",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-cron": "0.74.0-beta2",
+        "magento/module-email": "0.74.0-beta2",
+        "magento/module-directory": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-media-storage": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/ConfigurableImportExport/composer.json b/app/code/Magento/ConfigurableImportExport/composer.json
index 1144bb9390be0053eb5a529ccf54861e62a08172..159d501aab3926c6ea08cb36613de2f915b90960 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-beta1",
-        "magento/module-catalog-import-export": "0.74.0-beta1",
-        "magento/module-eav": "0.74.0-beta1",
-        "magento/module-import-export": "0.74.0-beta1",
-        "magento/module-configurable-product": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/module-catalog-import-export": "0.74.0-beta2",
+        "magento/module-eav": "0.74.0-beta2",
+        "magento/module-import-export": "0.74.0-beta2",
+        "magento/module-configurable-product": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/ConfigurableProduct/composer.json b/app/code/Magento/ConfigurableProduct/composer.json
index b5a49513dedb3ce1b0e367e796d92ba436d9c7e1..1b82ecacc37d54c27ecdd6a2bfee6e625b40a939 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-beta1",
-        "magento/module-catalog": "0.74.0-beta1",
-        "magento/module-catalog-inventory": "0.74.0-beta1",
-        "magento/module-sales": "0.74.0-beta1",
-        "magento/module-checkout": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-eav": "0.74.0-beta1",
-        "magento/module-customer": "0.74.0-beta1",
-        "magento/module-catalog-rule": "0.74.0-beta1",
-        "magento/module-directory": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
-        "magento/module-media-storage": "0.74.0-beta1",
-        "magento/module-quote": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/module-catalog-inventory": "0.74.0-beta2",
+        "magento/module-sales": "0.74.0-beta2",
+        "magento/module-checkout": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-eav": "0.74.0-beta2",
+        "magento/module-customer": "0.74.0-beta2",
+        "magento/module-catalog-rule": "0.74.0-beta2",
+        "magento/module-directory": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
+        "magento/module-media-storage": "0.74.0-beta2",
+        "magento/module-quote": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "suggest": {
-      "magento/module-webapi": "0.74.0-beta1"
+      "magento/module-webapi": "0.74.0-beta2"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Contact/composer.json b/app/code/Magento/Contact/composer.json
index 85af063ad24caf5edd01ce7305a966e184d28722..57b5f1fb07d116c5a6def7ee13b40e6bd8efe874 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-beta1",
-        "magento/module-store": "0.74.0-beta1",
-        "magento/module-customer": "0.74.0-beta1",
-        "magento/module-cms": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-config": "0.74.0-beta2",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-customer": "0.74.0-beta2",
+        "magento/module-cms": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Cookie/composer.json b/app/code/Magento/Cookie/composer.json
index d671460b9f065a3d80741d81be7bf1508060d346..6eb0244da272a35850eaeeb2aede214145e1fea6 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-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "suggest": {
-        "magento/module-backend": "0.74.0-beta1"
+        "magento/module-backend": "0.74.0-beta2"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Cron/composer.json b/app/code/Magento/Cron/composer.json
index 58c67083c1b1c0d7580e5de643fed7716ad1424f..a5f2fd8de55aa27542811c9361cfac9e3d3ba001 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-beta1",
-        "magento/module-store": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-config": "0.74.0-beta2",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/CurrencySymbol/composer.json b/app/code/Magento/CurrencySymbol/composer.json
index 3c4206446733865d0afe6c82bfc3255463db6ac2..7010fffc07b1b69be0f4e47d1f7cb164ee2009d7 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-beta1",
-        "magento/module-store": "0.74.0-beta1",
-        "magento/module-page-cache": "0.74.0-beta1",
-        "magento/module-directory": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-config": "0.74.0-beta2",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-page-cache": "0.74.0-beta2",
+        "magento/module-directory": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Customer/Model/AccountManagement.php b/app/code/Magento/Customer/Model/AccountManagement.php
index 59fbcb7f9f09fd5e28a2bc50faaff02255938ecc..4d0ca1e9efbedea3be686e2bff50b42a97055013 100644
--- a/app/code/Magento/Customer/Model/AccountManagement.php
+++ b/app/code/Magento/Customer/Model/AccountManagement.php
@@ -1047,12 +1047,13 @@ class AccountManagement implements AccountManagementInterface
         //TODO : Fix how template is built. Maybe Framework Object or create new Email template data model?
         // Check template to see what values need to be set in the data model to be passed
         // Need to set the reset_password_url property of the object
+        $store = $this->storeManager->getStore($customer->getStoreId());
         $resetUrl = $this->url->getUrl(
             'customer/account/createPassword',
             [
                 '_query' => ['id' => $customer->getId(), 'token' => $newPasswordToken],
                 '_store' => $customer->getStoreId(),
-                '_nosid' => true,
+                '_secure' => $store->isFrontUrlSecure(),
             ]
         );
 
@@ -1063,7 +1064,7 @@ class AccountManagement implements AccountManagementInterface
             $customer,
             self::XML_PATH_REMIND_EMAIL_TEMPLATE,
             self::XML_PATH_FORGOT_EMAIL_IDENTITY,
-            ['customer' => $customerEmailData, 'store' => $this->storeManager->getStore($customer->getStoreId())],
+            ['customer' => $customerEmailData, 'store' => $store],
             $customer->getStoreId()
         );
 
diff --git a/app/code/Magento/Customer/Test/Unit/Block/Adminhtml/Edit/Tab/View/PersonalInfoTest.php b/app/code/Magento/Customer/Test/Unit/Block/Adminhtml/Edit/Tab/View/PersonalInfoTest.php
index a196a2917f99477245f5f7e8cc7fd6b74533dfcb..29adf1a01cca112fc6833837accaef7d1c3864ad 100644
--- a/app/code/Magento/Customer/Test/Unit/Block/Adminhtml/Edit/Tab/View/PersonalInfoTest.php
+++ b/app/code/Magento/Customer/Test/Unit/Block/Adminhtml/Edit/Tab/View/PersonalInfoTest.php
@@ -165,6 +165,14 @@ class PersonalInfoTest extends \PHPUnit_Framework_TestCase
      */
     public function testGetCurrentStatus($status, $lastLoginAt, $lastVisitAt, $lastLogoutAt)
     {
+        $this->scopeConfig->expects($this->any())
+            ->method('getValue')
+            ->with(
+                'customer/online_customers/online_minutes_interval',
+                \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+            )
+            ->willReturn(60); //TODO: it's value mocked because unit tests run data providers before all testsuite
+
         $this->customerLog->expects($this->any())->method('getLastLoginAt')->willReturn($lastLoginAt);
         $this->customerLog->expects($this->any())->method('getLastVisitAt')->willReturn($lastVisitAt);
         $this->customerLog->expects($this->any())->method('getLastLogoutAt')->willReturn($lastLogoutAt);
diff --git a/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php b/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..9c7c2f1dde35575eb3cbdf2c98657bb05b16d496
--- /dev/null
+++ b/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php
@@ -0,0 +1,311 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Customer\Test\Unit\Model;
+
+use Magento\Customer\Model\AccountManagement;
+use Magento\Framework\App\Area;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
+use Magento\Store\Model\ScopeInterface;
+
+/**
+ * @SuppressWarnings(PHPMD.TooManyFields)
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
+class AccountManagementTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var AccountManagement */
+    protected $accountManagement;
+
+    /** @var ObjectManagerHelper */
+    protected $objectManagerHelper;
+
+    /** @var \Magento\Customer\Model\CustomerFactory|\PHPUnit_Framework_MockObject_MockObject */
+    protected $customerFactory;
+
+    /** @var \Magento\Framework\Event\ManagerInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $manager;
+
+    /** @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $storeManager;
+
+    /** @var \Magento\Framework\Math\Random|\PHPUnit_Framework_MockObject_MockObject */
+    protected $random;
+
+    /** @var \Magento\Customer\Model\Metadata\Validator|\PHPUnit_Framework_MockObject_MockObject */
+    protected $validator;
+
+    /** @var \Magento\Customer\Api\Data\ValidationResultsInterfaceFactory|\PHPUnit_Framework_MockObject_MockObject */
+    protected $validationResultsInterfaceFactory;
+
+    /** @var \Magento\Customer\Api\AddressRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $addressRepository;
+
+    /** @var \Magento\Customer\Api\CustomerMetadataInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $customerMetadata;
+
+    /** @var \Magento\Customer\Model\CustomerRegistry|\PHPUnit_Framework_MockObject_MockObject */
+    protected $customerRegistry;
+
+    /** @var \Magento\Framework\Url|\PHPUnit_Framework_MockObject_MockObject */
+    protected $url;
+
+    /** @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $logger;
+
+    /** @var \Magento\Framework\Encryption\EncryptorInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $encryptor;
+
+    /** @var \Magento\Customer\Model\Config\Share|\PHPUnit_Framework_MockObject_MockObject */
+    protected $share;
+
+    /** @var \Magento\Framework\Stdlib\String|\PHPUnit_Framework_MockObject_MockObject */
+    protected $string;
+
+    /** @var \Magento\Customer\Api\CustomerRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $customerRepository;
+
+    /** @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\Framework\Reflection\DataObjectProcessor|\PHPUnit_Framework_MockObject_MockObject */
+    protected $dataObjectProcessor;
+
+    /** @var \Magento\Framework\Registry|\PHPUnit_Framework_MockObject_MockObject */
+    protected $registry;
+
+    /** @var \Magento\Customer\Helper\View|\PHPUnit_Framework_MockObject_MockObject */
+    protected $customerViewHelper;
+
+    /** @var \Magento\Framework\Stdlib\DateTime|\PHPUnit_Framework_MockObject_MockObject */
+    protected $dateTime;
+
+    /** @var \Magento\Customer\Model\Customer|\PHPUnit_Framework_MockObject_MockObject */
+    protected $customer;
+
+    /** @var \Magento\Framework\ObjectFactory|\PHPUnit_Framework_MockObject_MockObject */
+    protected $objectFactory;
+
+    /** @var \Magento\Framework\Api\ExtensibleDataObjectConverter|\PHPUnit_Framework_MockObject_MockObject */
+    protected $extensibleDataObjectConverter;
+
+    /**
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     */
+    protected function setUp()
+    {
+        $this->customerFactory = $this->getMock('Magento\Customer\Model\CustomerFactory', [], [], '', false);
+        $this->manager = $this->getMock('Magento\Framework\Event\ManagerInterface');
+        $this->storeManager = $this->getMock('Magento\Store\Model\StoreManagerInterface');
+        $this->random = $this->getMock('Magento\Framework\Math\Random');
+        $this->validator = $this->getMock('Magento\Customer\Model\Metadata\Validator', [], [], '', false);
+        $this->validationResultsInterfaceFactory = $this->getMock(
+            'Magento\Customer\Api\Data\ValidationResultsInterfaceFactory',
+            [],
+            [],
+            '',
+            false
+        );
+        $this->addressRepository = $this->getMock('Magento\Customer\Api\AddressRepositoryInterface');
+        $this->customerMetadata = $this->getMock('Magento\Customer\Api\CustomerMetadataInterface');
+        $this->customerRegistry = $this->getMock('Magento\Customer\Model\CustomerRegistry', [], [], '', false);
+        $this->url = $this->getMock('Magento\Framework\Url', [], [], '', false);
+        $this->logger = $this->getMock('Psr\Log\LoggerInterface');
+        $this->encryptor = $this->getMock('Magento\Framework\Encryption\EncryptorInterface');
+        $this->share = $this->getMock('Magento\Customer\Model\Config\Share', [], [], '', false);
+        $this->string = $this->getMock('Magento\Framework\Stdlib\String');
+        $this->customerRepository = $this->getMock('Magento\Customer\Api\CustomerRepositoryInterface');
+        $this->scopeConfig = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface');
+        $this->transportBuilder = $this->getMock(
+            'Magento\Framework\Mail\Template\TransportBuilder',
+            [],
+            [],
+            '',
+            false
+        );
+        $this->dataObjectProcessor = $this->getMock(
+            'Magento\Framework\Reflection\DataObjectProcessor',
+            [],
+            [],
+            '',
+            false
+        );
+        $this->registry = $this->getMock('Magento\Framework\Registry');
+        $this->customerViewHelper = $this->getMock('Magento\Customer\Helper\View', [], [], '', false);
+        $this->dateTime = $this->getMock('Magento\Framework\Stdlib\DateTime');
+        $this->customer = $this->getMock('Magento\Customer\Model\Customer', [], [], '', false);
+        $this->objectFactory = $this->getMock('Magento\Framework\ObjectFactory', [], [], '', false);
+        $this->extensibleDataObjectConverter = $this->getMock(
+            'Magento\Framework\Api\ExtensibleDataObjectConverter',
+            [],
+            [],
+            '',
+            false
+        );
+
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+        $this->accountManagement = $this->objectManagerHelper->getObject(
+            'Magento\Customer\Model\AccountManagement',
+            [
+                'customerFactory' => $this->customerFactory,
+                'eventManager' => $this->manager,
+                'storeManager' => $this->storeManager,
+                'mathRandom' => $this->random,
+                'validator' => $this->validator,
+                'validationResultsDataFactory' => $this->validationResultsInterfaceFactory,
+                'addressRepository' => $this->addressRepository,
+                'customerMetadataService' => $this->customerMetadata,
+                'customerRegistry' => $this->customerRegistry,
+                'url' => $this->url,
+                'logger' => $this->logger,
+                'encryptor' => $this->encryptor,
+                'configShare' => $this->share,
+                'stringHelper' => $this->string,
+                'customerRepository' => $this->customerRepository,
+                'scopeConfig' => $this->scopeConfig,
+                'transportBuilder' => $this->transportBuilder,
+                'dataProcessor' => $this->dataObjectProcessor,
+                'registry' => $this->registry,
+                'customerViewHelper' => $this->customerViewHelper,
+                'dateTime' => $this->dateTime,
+                'customerModel' => $this->customer,
+                'objectFactory' => $this->objectFactory,
+                'extensibleDataObjectConverter' => $this->extensibleDataObjectConverter
+            ]
+        );
+    }
+
+    /**
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     */
+    public function testSendPasswordReminderEmail()
+    {
+        $customerId = 1;
+        $customerStoreId = 2;
+        $customerEmail = 'email@email.com';
+        $passwordToken = 'token';
+        $isFrontendSecure = true;
+        $resetUrl = 'reset url';
+        $customerData = ['key' => 'value'];
+        $customerName = 'Customer Name';
+        $templateIdentifier = 'Template Identifier';
+        $sender = 'Sender';
+
+        $customer = $this->getMockBuilder('Magento\Customer\Api\Data\CustomerInterface')
+            ->getMock();
+        $customer->expects($this->any())
+            ->method('getStoreId')
+            ->willReturn($customerStoreId);
+        $customer->expects($this->any())
+            ->method('getId')
+            ->willReturn($customerId);
+        $customer->expects($this->any())
+            ->method('getEmail')
+            ->willReturn($customerEmail);
+
+        $store = $this->getMockBuilder('Magento\Store\Model\Store')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->storeManager->expects($this->any())
+            ->method('getStore')
+            ->with($customerStoreId)
+            ->willReturn($store);
+
+        $store->expects($this->any())
+            ->method('isFrontUrlSecure')
+            ->willReturn($isFrontendSecure);
+
+        $this->url->expects($this->once())
+            ->method('getUrl')
+            ->with(
+                'customer/account/createPassword',
+                [
+                    '_query' => ['id' => $customerId, 'token' => $passwordToken],
+                    '_store' => $customerStoreId,
+                    '_secure' => $isFrontendSecure,
+                ]
+            )->willReturn($resetUrl);
+
+        $customerSecure = $this->getMockBuilder('\Magento\Customer\Model\Data\CustomerSecure')
+            ->disableOriginalConstructor()
+            ->setMethods(['addData', 'setData', 'setResetPasswordUrl'])
+            ->getMock();
+
+        $this->customerRegistry->expects($this->once())
+            ->method('retrieveSecureData')
+            ->with($customerId)
+            ->willReturn($customerSecure);
+
+        $this->dataObjectProcessor->expects($this->once())
+            ->method('buildOutputDataArray')
+            ->with($customer, '\Magento\Customer\Api\Data\CustomerInterface')
+            ->willReturn($customerData);
+
+        $this->customerViewHelper->expects($this->any())
+            ->method('getCustomerName')
+            ->with($customer)
+            ->willReturn($customerName);
+
+        $customerSecure->expects($this->once())
+            ->method('addData')
+            ->with($customerData)
+            ->willReturnSelf();
+        $customerSecure->expects($this->once())
+            ->method('setData')
+            ->with('name', $customerName)
+            ->willReturnSelf();
+        $customerSecure->expects($this->once())
+            ->method('setResetPasswordUrl')
+            ->with($resetUrl);
+
+        $this->scopeConfig->expects($this->at(0))
+            ->method('getValue')
+            ->with(AccountManagement::XML_PATH_REMIND_EMAIL_TEMPLATE, ScopeInterface::SCOPE_STORE, $customerStoreId)
+            ->willReturn($templateIdentifier);
+        $this->scopeConfig->expects($this->at(1))
+            ->method('getValue')
+            ->with(AccountManagement::XML_PATH_FORGOT_EMAIL_IDENTITY, ScopeInterface::SCOPE_STORE, $customerStoreId)
+            ->willReturn($sender);
+
+        $transport = $this->getMockBuilder('Magento\Framework\Mail\TransportInterface')
+            ->getMock();
+
+        $this->transportBuilder->expects($this->once())
+            ->method('setTemplateIdentifier')
+            ->with($templateIdentifier)
+            ->willReturnSelf();
+        $this->transportBuilder->expects($this->once())
+            ->method('setTemplateOptions')
+            ->with(['area' => Area::AREA_FRONTEND, 'store' => $customerStoreId])
+            ->willReturnSelf();
+        $this->transportBuilder->expects($this->once())
+            ->method('setTemplateVars')
+            ->with(['customer' => $customerSecure, 'store' => $store])
+            ->willReturnSelf();
+        $this->transportBuilder->expects($this->once())
+            ->method('setFrom')
+            ->with($sender)
+            ->willReturnSelf();
+        $this->transportBuilder->expects($this->once())
+            ->method('addTo')
+            ->with($customerEmail, $customerName)
+            ->willReturnSelf();
+        $this->transportBuilder->expects($this->once())
+            ->method('getTransport')
+            ->willReturn($transport);
+
+        $transport->expects($this->once())
+            ->method('sendMessage');
+
+        $this->assertEquals(
+            $this->accountManagement,
+            $this->accountManagement->sendPasswordReminderEmail($customer, $passwordToken)
+        );
+    }
+}
diff --git a/app/code/Magento/Customer/composer.json b/app/code/Magento/Customer/composer.json
index c7fe524a9cd1af4ecf0af22154559c3006ce9bdf..aa814c3b434f9ca4becb84a524e2daaff6ac6154 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-beta1",
-        "magento/module-eav": "0.74.0-beta1",
-        "magento/module-directory": "0.74.0-beta1",
-        "magento/module-catalog": "0.74.0-beta1",
-        "magento/module-newsletter": "0.74.0-beta1",
-        "magento/module-sales": "0.74.0-beta1",
-        "magento/module-checkout": "0.74.0-beta1",
-        "magento/module-wishlist": "0.74.0-beta1",
-        "magento/module-theme": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-review": "0.74.0-beta1",
-        "magento/module-tax": "0.74.0-beta1",
-        "magento/module-page-cache": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
-        "magento/module-authorization": "0.74.0-beta1",
-        "magento/module-integration": "0.74.0-beta1",
-        "magento/module-media-storage": "0.74.0-beta1",
-        "magento/module-ui": "0.74.0-beta1",
-        "magento/module-config": "0.74.0-beta1",
-        "magento/module-quote": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-eav": "0.74.0-beta2",
+        "magento/module-directory": "0.74.0-beta2",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/module-newsletter": "0.74.0-beta2",
+        "magento/module-sales": "0.74.0-beta2",
+        "magento/module-checkout": "0.74.0-beta2",
+        "magento/module-wishlist": "0.74.0-beta2",
+        "magento/module-theme": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-review": "0.74.0-beta2",
+        "magento/module-tax": "0.74.0-beta2",
+        "magento/module-page-cache": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
+        "magento/module-authorization": "0.74.0-beta2",
+        "magento/module-integration": "0.74.0-beta2",
+        "magento/module-media-storage": "0.74.0-beta2",
+        "magento/module-ui": "0.74.0-beta2",
+        "magento/module-config": "0.74.0-beta2",
+        "magento/module-quote": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "suggest": {
-        "magento/module-cookie": "0.74.0-beta1"
+        "magento/module-cookie": "0.74.0-beta2"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Customer/etc/adminhtml/di.xml b/app/code/Magento/Customer/etc/adminhtml/di.xml
index 103a78335aa95789ae5457b8665f0639cbb501c7..e656bcb2eba01b4f2a6d3d3c118eb44b25efcd2b 100644
--- a/app/code/Magento/Customer/etc/adminhtml/di.xml
+++ b/app/code/Magento/Customer/etc/adminhtml/di.xml
@@ -12,11 +12,4 @@
             <argument name="modelName" xsi:type="string">Magento\Customer\Model\Backend\Customer</argument>
         </arguments>
     </type>
-    <type name="Magento\Framework\Url\SecurityInfo">
-        <arguments>
-            <argument name="secureUrlList" xsi:type="array">
-                <item name="customer" xsi:type="string">/customer/</item>
-            </argument>
-        </arguments>
-    </type>
 </config>
diff --git a/app/code/Magento/CustomerImportExport/composer.json b/app/code/Magento/CustomerImportExport/composer.json
index 45ff4fa4dc755ae1e1c81d7f170153189125ac44..6163121f930528b81563fcbfd5166c6fbd3e75cb 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-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-customer": "0.74.0-beta1",
-        "magento/module-eav": "0.74.0-beta1",
-        "magento/module-import-export": "0.74.0-beta1",
-        "magento/module-directory": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-customer": "0.74.0-beta2",
+        "magento/module-eav": "0.74.0-beta2",
+        "magento/module-import-export": "0.74.0-beta2",
+        "magento/module-directory": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/DesignEditor/composer.json b/app/code/Magento/DesignEditor/composer.json
index 7d56ea7bf7d9fb4675bf40b8e6b4de2b07f09c46..35909f252fa2800b842cd827b53d96d23e21a3f0 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-beta1",
-        "magento/module-theme": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-eav": "0.74.0-beta1",
-        "magento/module-translation": "0.74.0-beta1",
-        "magento/module-config": "0.74.0-beta1",
-        "magento/module-media-storage": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-theme": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-eav": "0.74.0-beta2",
+        "magento/module-translation": "0.74.0-beta2",
+        "magento/module-config": "0.74.0-beta2",
+        "magento/module-media-storage": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Developer/composer.json b/app/code/Magento/Developer/composer.json
index 11372d7006e1095473b280e83646581040a1cd43..4481cd9cef6b380a943b5c9090bbded76cf2a2c4 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-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Dhl/composer.json b/app/code/Magento/Dhl/composer.json
index 3318cc573a782ab25fd78bfa1255db5569a0348c..0b55a5e7fb7583d45e8f575500caeec4108fbf84 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-beta1",
-        "magento/module-store": "0.74.0-beta1",
-        "magento/module-shipping": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-directory": "0.74.0-beta1",
-        "magento/module-sales": "0.74.0-beta1",
-        "magento/module-checkout": "0.74.0-beta1",
-        "magento/module-catalog": "0.74.0-beta1",
-        "magento/module-catalog-inventory": "0.74.0-beta1",
-        "magento/module-quote": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-config": "0.74.0-beta2",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-shipping": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-directory": "0.74.0-beta2",
+        "magento/module-sales": "0.74.0-beta2",
+        "magento/module-checkout": "0.74.0-beta2",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/module-catalog-inventory": "0.74.0-beta2",
+        "magento/module-quote": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "lib-libxml": "*",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Directory/composer.json b/app/code/Magento/Directory/composer.json
index 27c2fd01b7b7e449f5ada161f5c5af47b6b6caa3..9fe7db235aa15e9e2fc07d008c844581b73ece0b 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-beta1",
-        "magento/module-store": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-config": "0.74.0-beta2",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "lib-libxml": "*",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Downloadable/composer.json b/app/code/Magento/Downloadable/composer.json
index e56b7b434fa6573d1bd8dfa7179fa98014f606e0..e1c4c4f63618d9fc705d4722a1ee9cda57b5f62a 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-beta1",
-        "magento/module-catalog": "0.74.0-beta1",
-        "magento/module-customer": "0.74.0-beta1",
-        "magento/module-tax": "0.74.0-beta1",
-        "magento/module-theme": "0.74.0-beta1",
-        "magento/module-eav": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-sales": "0.74.0-beta1",
-        "magento/module-checkout": "0.74.0-beta1",
-        "magento/module-directory": "0.74.0-beta1",
-        "magento/module-wishlist": "0.74.0-beta1",
-        "magento/module-gift-message": "0.74.0-beta1",
-        "magento/module-catalog-inventory": "0.74.0-beta1",
-        "magento/module-msrp": "0.74.0-beta1",
-        "magento/module-config": "0.74.0-beta1",
-        "magento/module-media-storage": "0.74.0-beta1",
-        "magento/module-quote": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/module-customer": "0.74.0-beta2",
+        "magento/module-tax": "0.74.0-beta2",
+        "magento/module-theme": "0.74.0-beta2",
+        "magento/module-eav": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-sales": "0.74.0-beta2",
+        "magento/module-checkout": "0.74.0-beta2",
+        "magento/module-directory": "0.74.0-beta2",
+        "magento/module-wishlist": "0.74.0-beta2",
+        "magento/module-gift-message": "0.74.0-beta2",
+        "magento/module-catalog-inventory": "0.74.0-beta2",
+        "magento/module-msrp": "0.74.0-beta2",
+        "magento/module-config": "0.74.0-beta2",
+        "magento/module-media-storage": "0.74.0-beta2",
+        "magento/module-quote": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable.phtml b/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable.phtml
index db3a01d67c3cf61a3b8469d5b995c2dbd79b0810..b09be18c66169f4c3d0e1242cdd2585609a50499 100644
--- a/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable.phtml
+++ b/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable.phtml
@@ -26,7 +26,7 @@ require([
 var uploaderTemplate = '<div class="no-display" id="[[idName]]-template">' +
                                 '<div id="<%- data.id %>" class="file-row file-row-narrow">' +
                                     '<span class="file-info">' +
-                                        '<span class="file-info-name"><%- data.name %></span>' +
+                                        '<span class="file-info-name"><%= data.name %></span>' +
                                         ' ' +
                                         '<span class="file-info-size">(<%- data.size %>)</span>' +
                                     '</span>' +
@@ -41,7 +41,7 @@ var uploaderTemplate = '<div class="no-display" id="[[idName]]-template">' +
                                 '</div>';
 
     var fileListTemplate = '<span class="file-info">' +
-                                '<span class="file-info-name"><%- data.name %></span>' +
+                                '<span class="file-info-name"><%= data.name %></span>' +
                                 ' ' +
                                 '<span class="file-info-size">(<%- data.size %>)</span>' +
                             '</span>';
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 bf2b72140ba8a082faa3e7824016fe7310ce724b..c7db53b3b85d63a7a0a6568f3efe26dea28270e1 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
@@ -15,58 +15,61 @@
 ?>
 <?php $_product = $block->getProduct()?>
 <?php $block->getConfigJson() ?>
-<div class="form-inline">
-    <div class="field">
-        <label class="label" for="name"><span><?php echo __('Title')?></span></label>
-        <div class="control">
-            <input type="text" class="input-text" id="downloadable_links_title" name="product[links_title]" value="<?php echo $block->getLinksTitle() ?>" <?php echo($_product->getStoreId() && $block->getUsedDefault()) ? 'disabled="disabled"' : '' ?>>
-            <?php if ($_product->getStoreId()): ?>
-                <input id="link_title_default" type="checkbox" name="use_default[]" value="links_title" onclick="toggleValueElements(this, this.parentNode.parentNode)" <?php echo $block->getUsedDefault() ? 'checked="checked"' : '' ?> />
-                <label class="normal" for="link_title_default"><?php echo __('Use Default Value'); ?></label>
-            <?php endif; ?>
-        </div>
-        <div class="field-service">
-            <?php echo !$block->isSingleStoreMode() ? __('[STORE VIEW]') : ''; ?>
+<div class="admin__scope">
+    <fieldset class="admin__fieldset downloadable-form">
+
+        <div class="admin__field" <?php echo !$block->isSingleStoreMode() ? ' data-config-scope="' . __('[STORE VIEW]') . '"' : ''; ?>>
+            <label class="admin__field-label" for="downloadable_links_title"><span><?php echo __('Title')?></span></label>
+            <div class="admin__field-control">
+                <input type="text" class="admin__control-text" id="downloadable_links_title" name="product[links_title]" value="<?php echo $block->getLinksTitle() ?>" <?php echo($_product->getStoreId() && $block->getUsedDefault()) ? 'disabled="disabled"' : '' ?>>
+                <?php if ($_product->getStoreId()): ?>
+                    <div class="admin__field admin__field-option">
+                        <input id="link_title_default" class="admin__control-checkbox" type="checkbox" name="use_default[]" value="links_title" onclick="toggleValueElements(this, this.parentNode.parentNode)" <?php echo $block->getUsedDefault() ? 'checked="checked"' : '' ?> />
+                        <label class="admin__field-label" for="link_title_default"><span><?php echo __('Use Default Value'); ?></span></label>
+                    </div>
+                <?php endif; ?>
+            </div>
         </div>
-    </div>
 
-    <div class="field">
-        <label class="label" for="name"><span><?php echo __('Links can be purchased separately')?></span></label>
-        <div class="control">
-            <?php echo $block->getPurchasedSeparatelySelect()?>
+        <div class="admin__field" <?php echo !$block->isSingleStoreMode() ? ' data-config-scope="' . __('[GLOBAL]') . '"' : ''; ?>>
+            <label class="admin__field-label" for="downloadable_link_purchase_type"><span><?php echo __('Links can be purchased separately')?></span></label>
+            <div class="admin__field-control">
+                <?php echo $block->getPurchasedSeparatelySelect()?>
+            </div>
         </div>
-        <div class="field-service">
-            <?php echo !$block->isSingleStoreMode() ? __('[GLOBAL]') : ''; ?>
+        <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">
+                        <thead>
+                            <tr>
+                                <th class="col-title _required"><span><?php echo __('Title') ?></span></th>
+                                <?php if ($block->getCanReadPrice() !== false) : ?>
+                                    <th class="col-price"><span><?php echo __('Price') ?></span></th>
+                                <?php endif; ?>
+                                <th class="col-limit"><span><?php echo __('Max. Downloads') ?></span></th>
+                                <th class="col-option"><span><?php echo __('Shareable') ?></span></th>
+                                <th class="col-sample"><span><?php echo __('Sample') ?></span></th>
+                                <th class="col-file"><span><?php echo __('File') ?></span></th>
+                                <th class="col-sort"><span><?php echo __('Sort Order') ?></span></th>
+                                <th class="col-actions">&nbsp;</th>
+                            </tr>
+                        </thead>
+                        <tfoot>
+                            <tr>
+                                <td class="col-actions-add" colspan="8"><?php echo $block->getAddButtonHtml() ?></td>
+                            </tr>
+                        </tfoot>
+                        <tbody id="link_items_body">
+                        </tbody>
+                    </table>
+                </div>
+                <div class="admin__field-note">
+                    <span><?php echo __('Alphanumeric, dash and underscore characters are recommended for filenames. Improper characters are replaced with \'_\'.')?></span>
+                </div>
+            </div>
         </div>
-    </div>
-
-    <table cellspacing="0" class="data-table">
-        <thead>
-            <tr>
-                <th><?php echo __('Title')?> <span class="required">*</span></th>
-                <?php if ($block->getCanReadPrice() !== false) : ?>
-                <th><?php echo __('Price')?></th>
-                <?php endif; ?>
-                <th><?php echo __('Max. Downloads')?></th>
-                <th><?php echo __('Shareable')?></th>
-                <th><?php echo __('Sample')?></th>
-                <th><?php echo __('File')?></th>
-                <th><?php echo __('Sort Order')?></th>
-                <th class="col-delete">&nbsp;</th>
-            </tr>
-        </thead>
-        <tfoot>
-            <tr>
-                <td colspan="8" class="col-actions-add"><?php echo $block->getAddButtonHtml()?></td>
-            </tr>
-        </tfoot>
-        <tbody id="link_items_body">
-        </tbody>
-    </table>
-
-<div><small><?php echo __('Alphanumeric, dash and underscore characters are recommended for filenames. Improper characters are replaced with \'_\'.')?></small></div>
-
-
+    </fieldset>
 </div>
 <script>
 require([
@@ -79,15 +82,15 @@ require([
 ], function(jQuery, registry, mageTemplate){
     registry.get('downloadable', function (Downloadable) {
         var linkTemplate = '<tr>'+
-            '<td>'+
+            '<td class="col-title">'+
                 '<input type="hidden" class="__delete__" name="downloadable[link][<%- data.id %>][is_delete]" value="" />'+
                 '<input type="hidden" name="downloadable[link][<%- data.id %>][link_id]" value="<%- data.link_id %>" />'+
-                '<input type="text" class="required-entry input-text" name="downloadable[link][<%- data.id %>][title]" value="<%- data.title %>" />'+
+                '<input type="text" class="required-entry input-text admin__control-text" name="downloadable[link][<%- data.id %>][title]" value="<%- data.title %>" />'+
                 '<?php echo $_product->getStoreId() ? '<input type="checkbox" id="downloadable_link_<%- data.id %>_title" name="downloadable[link][<%- data.id %>][use_default_title]" value="1" /><label class="normal" for="downloadable_link_<%- data.id %>_title">Use Default Value</label>' : '' ?>'+
             '</td>'+
             <?php if ($block->getCanReadPrice() !== false) : ?>
-            '<td class="input-price">'+
-                '<input type="text" id="downloadable_link_<%- data.id %>_price_value" class="input-text validate-number link-prices<?php if ($block->getCanEditPrice() === false) : ?> disabled<?php endif; ?>" name="downloadable[link][<%- data.id %>][price]" value="<%- data.price %>"<?php if ($block->getCanEditPrice() === false) : ?> disabled="disabled"<?php endif; ?> /> ' +
+            '<td class="input-price col-price">'+
+                '<input type="text" id="downloadable_link_<%- data.id %>_price_value" class="input-text admin__control-text validate-number link-prices<?php if ($block->getCanEditPrice() === false) : ?> disabled<?php endif; ?>" name="downloadable[link][<%- data.id %>][price]" value="<%- data.price %>"<?php if ($block->getCanEditPrice() === false) : ?> disabled="disabled"<?php endif; ?> /> ' +
                 '<label>[<?php echo $block->getBaseCurrencyCode($_product->getStoreId()) ?>]</label>' +
                 <?php if ($_product->getStoreId() && $block->getIsPriceWebsiteScope()) : ?>
                 '<br /><input type="checkbox" id="downloadable_link_<%- data.id %>_price" name="downloadable[link][<%- data.id %>][use_default_price]" value="1"<?php if ($block->getCanEditPrice() === false) : ?> disabled="disabled"<?php endif; ?> /> <label for="downloadable_link_<%- data.id %>_price">Use Default Value</label>' +
@@ -99,16 +102,16 @@ require([
             '<input type="hidden" id="downloadable_link_<%- data.id %>_price" name="downloadable[link][<%- data.id %>][use_default_price]" value="1" />' +
             <?php endif; ?>
             <?php endif; ?>
-            '<td><input type="text" id="downloadable_link_<%- data.id %>_downloads" name="downloadable[link][<%- data.id %>][number_of_downloads]" class="input-text downloads" value="<%- data.number_of_downloads %>" />'+
+            '<td class="col-limit"><input type="text" id="downloadable_link_<%- data.id %>_downloads" name="downloadable[link][<%- data.id %>][number_of_downloads]" class="input-text admin__control-text downloads" value="<%- data.number_of_downloads %>" />'+
             '<p><input type="checkbox" class="checkbox" id="downloadable_link_<%- data.id %>_is_unlimited" name="downloadable[link][<%- data.id %>][is_unlimited]" value="1" <%- data.is_unlimited %> /> <label for="downloadable_link_<%- data.id %>_is_unlimited">Unlimited</label></p></td>'+
-            '<td>'+
+            '<td class="col-share">'+
                 '<select id="downloadable_link _<%- data.id %>_shareable" name="downloadable[link][<%- data.id %>][is_shareable]">'+
                     '<option value="1">Yes</option>'+
                     '<option value="0">No</option>'+
                     '<option value="2" selected="selected">Use config</option>'+
                 '</select>'+
             '</td>'+
-            '<td>'+
+            '<td class="col-file">'+
                 '<div class="files">'+
                     '<div class="row">'+
                         '<label for="downloadable_link_<%- data.id %>_sample_file_type"><input type="radio" class="radio" id="downloadable_link_<%- data.id %>_sample_file_type" name="downloadable[link][<%- data.id %>][sample][type]" value="file"<%- data.sample_file_checked %> /> File:</label>'+
@@ -127,14 +130,14 @@ require([
                         '</div>'+
                     '</div>'+
                     '<div class="row">'+
-                        '<label for="downloadable_link_<%- data.id %>_sample_url_type"><input type="radio" class="radio" id="downloadable_link_<%- data.id %>_sample_url_type" name="downloadable[link][<%- data.id %>][sample][type]" value="url"<%- data.sample_url_checked %> /> URL:</label><input type="text" class="input-text validate-downloadable-url validate-url" name="downloadable[link][<%- data.id %>][sample][url]" value="<%- data.sample_url %>" />'+
+                        '<label for="downloadable_link_<%- data.id %>_sample_url_type"><input type="radio" class="radio" id="downloadable_link_<%- data.id %>_sample_url_type" name="downloadable[link][<%- data.id %>][sample][type]" value="url"<%- data.sample_url_checked %> /> URL:</label><input type="text" class="input-text admin__control-text validate-downloadable-url validate-url" name="downloadable[link][<%- data.id %>][sample][url]" value="<%- data.sample_url %>" />'+
                     '</div>'+
                     '<div>'+
                         '<span id="downloadable_link_<%- data.id %>_sample_container"></span>'+
                     '</div>'+
                 '</div>'+
             '</td>'+
-            '<td>'+
+            '<td class="col-file">'+
                 '<div class="files">'+
                     '<div class="row">'+
                         '<label for="downloadable_link_<%- data.id %>_file_type"><input type="radio" class="radio validate-one-required-by-name" id="downloadable_link_<%- data.id %>_file_type" name="downloadable[link][<%- data.id %>][type]" value="file"<%- data.file_checked %> /> File:</label>'+
@@ -153,16 +156,16 @@ require([
                         '</div>'+
                     '</div>'+
                     '<div class="row">'+
-                        '<label for="downloadable_link_<%- data.id %>_url_type"><input type="radio" class="radio validate-one-required-by-name" id="downloadable_link_<%- data.id %>_url_type" name="downloadable[link][<%- data.id %>][type]" value="url"<%- data.url_checked %> /> URL:</label><input type="text" class="validate-downloadable-url validate-url input-text" name="downloadable[link][<%- data.id %>][link_url]" value="<%- data.link_url %>" />'+
+                        '<label for="downloadable_link_<%- data.id %>_url_type"><input type="radio" class="radio validate-one-required-by-name" id="downloadable_link_<%- data.id %>_url_type" name="downloadable[link][<%- data.id %>][type]" value="url"<%- data.url_checked %> /> URL:</label><input type="text" class="validate-downloadable-url validate-url input-text admin__control-text" name="downloadable[link][<%- data.id %>][link_url]" value="<%- data.link_url %>" />'+
                     '</div>'+
                     '<div>'+
                         '<span id="downloadable_link_<%- data.id %>_link_container"></span>'+
                     '</div>'+
                 '</div>'+
             '</td>'+
-            '<td><input type="text" name="downloadable[link][<%- data.id %>][sort_order]" value="<%- data.sort_order %>" class="input-text sort" /></td>'+
-            '<td class="col-delete">'+
-                '<button id="downloadable_link_<%- data.id %>_delete_button" type="button" class="action- scalable delete delete-link-item"><span><span><span><?php echo __('Delete'); ?></span></span></span></button>'+
+            '<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>'+
             '</td>'+
         '</tr>';
 
@@ -309,7 +312,7 @@ require([
                 }
             },
             bindRemoveButtons : function(){
-                var buttons = $$('tbody#link_items_body .delete-link-item');
+                var buttons = $$('tbody#link_items_body .action-remove');
                 for(var i=0;i<buttons.length;i++){
                     if(!$(buttons[i]).binded && !$(buttons[i]).hasClassName('disabled')){
                         $(buttons[i]).binded = true;
@@ -351,7 +354,7 @@ require([
                             if ($(id + ' .progressbar-container').length) {
                                 $(id + ' .progressbar-container').parent().remove();
                             }
-                            
+
                             fileSize = typeof file.size == "undefined" ?
                                 $.mage.__('We could not detect a size.') :
                                 byteConvert(file.size);
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 525009f591747a531c55553aeb251e81cad8d6b4..85b099dd18a06cddb89a558f594cf399b3d4b7f3 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
@@ -15,40 +15,47 @@
 $_product = $block->getProduct();
 $block->getConfigJson();
 ?>
-<div class="form-inline">
-    <div class="field">
-        <label class="label" for="name"><span><?php echo __('Title')?></span></label>
-        <div class="control">
-            <input type="text" class="input-text" name="product[samples_title]" value="<?php echo $block->getSamplesTitle() ?>" <?php echo($_product->getStoreId() && $block->getUsedDefault()) ? 'disabled="disabled"' : '' ?>>
-            <?php if ($_product->getStoreId()): ?>
-                <input id="sample_title_default" type="checkbox" name="use_default[]" value="samples_title" onclick="toggleValueElements(this, this.parentNode.parentNode)" <?php echo $block->getUsedDefault() ? 'checked="checked"' : '' ?> />
-                <label class="normal" for="sample_title_default">Use Default Value</label>
-            <?php endif; ?>
+<div class="admin__scope">
+    <fieldset class="admin__fieldset  downloadable-form">
+        <div class="admin__field"<?php echo !$block->isSingleStoreMode() ? ' data-config-scope="' . __('[STORE VIEW]') . '"' : ''; ?>>
+            <label class="admin__field-label" for="downloadable_samples_title"><span><?php echo __('Title')?></span></label>
+            <div class="admin__field-control">
+                <input type="text" class="admin__control-text" id="downloadable_samples_title" name="product[samples_title]" value="<?php echo $block->getSamplesTitle() ?>" <?php echo($_product->getStoreId() && $block->getUsedDefault()) ? 'disabled="disabled"' : '' ?>>
+                <?php if ($_product->getStoreId()): ?>
+                    <div class="admin__field admin__field-option">
+                        <input id="sample_title_default" class="admin__control-checkbox" type="checkbox" name="use_default[]" value="samples_title" onclick="toggleValueElements(this, this.parentNode.parentNode)" <?php echo $block->getUsedDefault() ? 'checked="checked"' : '' ?> />
+                        <label class="admin__field-label" for="sample_title_default"><span>Use Default Value</span></label>
+                    </div>
+                <?php endif; ?>
+            </div>
         </div>
-        <div class="field-service">
-            <?php echo !$block->isSingleStoreMode() ? __('[STORE VIEW]') : ''; ?>
+        <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">
+                        <thead>
+                            <tr>
+                                <th class="_required col-title"><span><?php echo __('Title') ?></span></th>
+                                <th class="col-file"><span><?php echo __('File') ?></span></th>
+                                <th class="col-sort"><span><?php echo __('Sort Order') ?></span></th>
+                                <th class="col-actions">&nbsp;</th>
+                            </tr>
+                        </thead>
+                        <tfoot>
+                            <tr>
+                                <td colspan="4" class="col-actions"><?php echo $block->getAddButtonHtml() ?></td>
+                            </tr>
+                        </tfoot>
+                        <tbody id="sample_items_body">
+                        </tbody>
+                    </table>
+                </div>
+                <div class="admin__field-note">
+                    <span><?php echo __('Alphanumeric, dash and underscore characters are recommended for filenames. Improper characters are replaced with \'_\'.')?></span>
+                </div>
+            </div>
         </div>
-    </div>
-
-    <table cellspacing="0" class="data-table">
-        <thead>
-            <tr>
-                <th><?php echo __('Title') ?> <span class="required">*</span></th>
-                <th><?php echo __('File') ?></th>
-                <th><?php echo __('Sort Order') ?></th>
-                <th class="col-delete">&nbsp;</th>
-            </tr>
-        </thead>
-        <tfoot>
-            <tr>
-                <td colspan="4" class="col-actions-add"><?php echo $block->getAddButtonHtml() ?></td>
-            </tr>
-        </tfoot>
-        <tbody id="sample_items_body">
-        </tbody>
-    </table>
-
-    <div><small><?php echo __('Alphanumeric, dash and underscore characters are recommended for filenames. Improper characters are replaced with \'_\'.')?></small></div>
+    </fieldset>
 </div>
 <script>
 require([
@@ -60,13 +67,13 @@ require([
 ], function (jQuery, registry, mageTemplate) {
     registry.get('downloadable', function (Downloadable) {
         var sampleTemplate = '<tr>'+
-                            '<td>'+
+                            '<td class="col-title">'+
                                 '<input type="hidden" class="__delete__" name="downloadable[sample][<%- data.id %>][is_delete]" value="" />'+
                                 '<input type="hidden" name="downloadable[sample][<%- data.id %>][sample_id]" value="<%- data.sample_id %>" />'+
-                                '<input type="text" class="required-entry input-text" name="downloadable[sample][<%- data.id %>][title]" value="<%- data.title %>" />'+
+                                '<input type="text" class="required-entry input-text admin__control-text" name="downloadable[sample][<%- data.id %>][title]" value="<%- data.title %>" />'+
                                 '<?php echo $_product->getStoreId() ? '<br /><input type="checkbox" id="downloadable_sample_<%- data.id %>_title" name="downloadable[sample][<%- data.id %>][use_default_title]" value="1" /><label class="normal" for="downloadable_sample_<%- data.id %>_title">Use Default Value</label>' : '' ?>'+
                             '</td>'+
-                            '<td>'+
+                            '<td class="col-file">'+
                                 '<div class="files-wide">'+
                                     '<div class="row">'+
                                         '<label for="downloadable_sample_<%- data.id %>_file_type"><input type="radio" class="radio validate-one-required-by-name" id="downloadable_sample_<%- data.id %>_file_type" name="downloadable[sample][<%- data.id %>][type]" value="file"<%- data.file_checked %> /> File:</label>'+
@@ -87,7 +94,7 @@ require([
                                         '</div>'+
                                     '</div>'+
                                     '<div class="row">'+
-                                        '<label for="downloadable_sample_<%- data.id %>_url_type"><input type="radio" class="radio validate-one-required-by-name" id="downloadable_sample_<%- data.id %>_url_type" name="downloadable[sample][<%- data.id %>][type]" value="url"<%- data.url_checked %> /> URL:</label> <input type="text" class="validate-downloadable-url validate-url input-text" name="downloadable[sample][<%- data.id %>][sample_url]" value="<%- data.sample_url %>" />'+
+                                        '<label for="downloadable_sample_<%- data.id %>_url_type"><input type="radio" class="radio validate-one-required-by-name" id="downloadable_sample_<%- data.id %>_url_type" name="downloadable[sample][<%- data.id %>][type]" value="url"<%- data.url_checked %> /> URL:</label> <input type="text" class="validate-downloadable-url validate-url input-text admin__control-text" name="downloadable[sample][<%- data.id %>][sample_url]" value="<%- data.sample_url %>" />'+
                                     '</div>'+
                                     '<div>'+
                                         '<span id="downloadable_sample_<%- data.id %>_container"></span>'+
@@ -95,9 +102,9 @@ require([
                                 '</div>'+
 
                             '</td>'+
-                            '<td><input type="text" name="downloadable[sample][<%- data.id %>][sort_order]" value="<%- data.sort_order %>" class="input-text sort" /></td>'+
-                            '<td class="col-delete">'+
-                                '<button type="button" class="action- scalable delete icon-btn delete-sample-item"><span>Delete</span></button>'+
+                            '<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>'+
                             '</td>'+
                         '</tr>';
         sampleItems = {
@@ -178,7 +185,7 @@ require([
                 }
             },
             bindRemoveButtons: function() {
-                var buttons = $$('tbody#sample_items_body .delete-sample-item');
+                var buttons = $$('tbody#sample_items_body .action-remove');
                 for(var i=0;i<buttons.length;i++){
                     if(!$(buttons[i]).binded){
                         $(buttons[i]).binded = true;
diff --git a/app/code/Magento/Eav/composer.json b/app/code/Magento/Eav/composer.json
index 68d77c9d3a8ca314c5c4d98e04ac1d0f1d476e3e..837f27f1db1cd0fec7b61a883878092b47ff7ae7 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-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-catalog": "0.74.0-beta1",
-        "magento/module-config": "0.74.0-beta1",
-        "magento/module-media-storage": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/module-config": "0.74.0-beta2",
+        "magento/module-media-storage": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Email/Model/Template.php b/app/code/Magento/Email/Model/Template.php
index 5a331546d5831ca7bfafa0a00b84a85b342c5c91..8287fa82aca1e61954395a4611c788bc18c9410b 100644
--- a/app/code/Magento/Email/Model/Template.php
+++ b/app/code/Magento/Email/Model/Template.php
@@ -8,6 +8,7 @@ namespace Magento\Email\Model;
 use Magento\Email\Model\Template\Filter;
 use Magento\Framework\App\Filesystem\DirectoryList;
 use Magento\Framework\Filter\Template as FilterTemplate;
+use Magento\Store\Model\ScopeInterface;
 use Magento\Store\Model\StoreManagerInterface;
 
 /**
@@ -213,7 +214,7 @@ class Template extends \Magento\Email\Model\AbstractTemplate implements \Magento
         $store = $this->_storeManager->getStore($store);
         $fileName = $this->_scopeConfig->getValue(
             self::XML_PATH_DESIGN_EMAIL_LOGO,
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
+            ScopeInterface::SCOPE_STORE,
             $store
         );
         if ($fileName) {
@@ -252,7 +253,7 @@ class Template extends \Magento\Email\Model\AbstractTemplate implements \Magento
         $store = $this->_storeManager->getStore($store);
         $alt = $this->_scopeConfig->getValue(
             self::XML_PATH_DESIGN_EMAIL_LOGO_ALT,
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
+            ScopeInterface::SCOPE_STORE,
             $store
         );
         if ($alt) {
@@ -379,7 +380,7 @@ class Template extends \Magento\Email\Model\AbstractTemplate implements \Magento
     /**
      * Return true if this template can be used for sending queue as main template
      *
-     * @return boolean
+     * @return bool
      */
     public function isValidForSend()
     {
@@ -480,6 +481,7 @@ class Template extends \Magento\Email\Model\AbstractTemplate implements \Magento
      * Get exception, generated during send() method
      *
      * @return \Exception|null
+     * @codeCoverageIgnore
      */
     public function getSendingException()
     {
@@ -520,6 +522,7 @@ class Template extends \Magento\Email\Model\AbstractTemplate implements \Magento
      *
      * @param string|array $bcc
      * @return $this
+     * @codeCoverageIgnore
      */
     public function addBcc($bcc)
     {
@@ -532,6 +535,7 @@ class Template extends \Magento\Email\Model\AbstractTemplate implements \Magento
      *
      * @param string $email
      * @return $this
+     * @codeCoverageIgnore
      */
     public function setReturnPath($email)
     {
@@ -544,6 +548,7 @@ class Template extends \Magento\Email\Model\AbstractTemplate implements \Magento
      *
      * @param string $email
      * @return $this
+     * @codeCoverageIgnore
      */
     public function setReplyTo($email)
     {
diff --git a/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/Edit/FormTest.php b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/Edit/FormTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..c5d1fefa9c28797f686e8247f61d1e696fbf3454
--- /dev/null
+++ b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/Edit/FormTest.php
@@ -0,0 +1,103 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Email\Test\Unit\Block\Adminhtml\Template\Edit;
+
+/**
+ * @covers \Magento\Email\Block\Adminhtml\Template\Edit\Form
+ */
+class FormTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\Email\Block\Adminhtml\Template\Edit\Form */
+    protected $form;
+
+    /** @var \Magento\Framework\Registry|\PHPUnit_Framework_MockObject_MockObject */
+    protected $registryMock;
+
+    /** @var \Magento\Email\Model\Source\Variables|\PHPUnit_Framework_MockObject_MockObject */
+    protected $variablesMock;
+
+    /** @var \Magento\Variable\Model\VariableFactory|\PHPUnit_Framework_MockObject_MockObject */
+    protected $variableFactoryMock;
+
+    /** @var \Magento\Variable\Model\Variable|\PHPUnit_Framework_MockObject_MockObject */
+    protected $variableMock;
+
+    /** @var \Magento\Email\Model\Template|\PHPUnit_Framework_MockObject_MockObject */
+    protected $templateMock;
+
+    public function setUp()
+    {
+        $this->registryMock = $this->getMockBuilder('Magento\Framework\Registry')
+            ->disableOriginalConstructor()
+            ->setMethods(['registry'])
+            ->getMock();
+        $this->variablesMock = $this->getMockBuilder('Magento\Email\Model\Source\Variables')
+            ->disableOriginalConstructor()
+            ->setMethods(['toOptionArray'])
+            ->getMock();
+        $this->variableFactoryMock = $this->getMockBuilder('Magento\Variable\Model\VariableFactory')
+            ->disableOriginalConstructor()
+            ->setMethods(['create'])
+            ->getMock();
+        $this->variableMock = $this->getMockBuilder('Magento\Variable\Model\Variable')
+            ->disableOriginalConstructor()
+            ->setMethods(['getVariablesOptionArray'])
+            ->getMock();
+        $this->templateMock = $this->getMockBuilder('Magento\Email\Model\Template')
+            ->disableOriginalConstructor()
+            ->setMethods(['getId', 'getVariablesOptionArray'])
+            ->getMock();
+        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $this->form = $objectManager->getObject(
+            'Magento\Email\Block\Adminhtml\Template\Edit\Form',
+            [
+                'registry' => $this->registryMock,
+                'variableFactory' => $this->variableFactoryMock,
+                'variables' => $this->variablesMock
+            ]
+        );
+    }
+
+    /**
+     * @covers \Magento\Email\Block\Adminhtml\Template\Edit\Form::getVariables
+     */
+    public function testGetVariables()
+    {
+        $this->variablesMock->expects($this->once())
+            ->method('toOptionArray')
+            ->willReturn(['var1', 'var2', 'var3']);
+        $this->variableFactoryMock->expects($this->once())
+            ->method('create')
+            ->willReturn($this->variableMock);
+        $this->variableMock->expects($this->once())
+            ->method('getVariablesOptionArray')
+            ->willReturn(['custom var 1', 'custom var 2']);
+        $this->registryMock->expects($this->once())
+            ->method('registry')
+            ->willReturn($this->templateMock);
+        $this->templateMock->expects($this->once())
+            ->method('getId')
+            ->willReturn(1);
+        $this->templateMock->expects($this->once())
+            ->method('getVariablesOptionArray')
+            ->willReturn(['template var 1', 'template var 2']);
+        $this->assertEquals(
+            [['var1', 'var2', 'var3'], ['custom var 1', 'custom var 2'], ['template var 1', 'template var 2']],
+            $this->form->getVariables()
+        );
+    }
+
+    /**
+     * @covers \Magento\Email\Block\Adminhtml\Template\Edit\Form::getEmailTemplate
+     */
+    public function testGetEmailTemplate()
+    {
+        $this->registryMock->expects($this->once())
+            ->method('registry')
+            ->with('current_email_template');
+        $this->form->getEmailTemplate();
+    }
+}
diff --git a/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/Grid/Renderer/ActionTest.php b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/Grid/Renderer/ActionTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..fc41f9ff4aaf2b88e3227ac0f0ab9bb4f876a1c8
--- /dev/null
+++ b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/Grid/Renderer/ActionTest.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Email\Test\Unit\Block\Adminhtml\Template\Grid\Renderer;
+
+/**
+ * @covers Magento\Email\Block\Adminhtml\Template\Grid\Renderer\Action
+ */
+class ActionTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Email\Block\Adminhtml\Template\Grid\Renderer\Action
+     */
+    protected $action;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $columnMock;
+
+    protected function setUp()
+    {
+        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $this->columnMock = $this->getMockBuilder('Magento\Backend\Block\Widget\Grid\Column')
+            ->disableOriginalConstructor()
+            ->setMethods(['setActions', 'getActions'])
+            ->getMock();
+        $this->action = $objectManager->getObject('Magento\Email\Block\Adminhtml\Template\Grid\Renderer\Action');
+    }
+
+    /**
+     * @covers \Magento\Email\Block\Adminhtml\Template\Grid\Renderer\Action::render
+     */
+    public function testRenderNoActions()
+    {
+        $this->columnMock->expects($this->once())
+            ->method('setActions');
+        $this->columnMock->expects($this->once())
+            ->method('getActions')
+            ->willReturn('');
+        $this->action->setColumn($this->columnMock);
+        $row = new \Magento\Framework\Object();
+        $this->assertEquals('&nbsp;', $this->action->render($row));
+    }
+
+    /**
+     * @covers \Magento\Email\Block\Adminhtml\Template\Grid\Renderer\Action::render
+     */
+    public function testRender()
+    {
+        $this->columnMock->expects($this->once())
+            ->method('setActions');
+        $this->columnMock->expects($this->once())
+            ->method('getActions')
+            ->willReturn(['url', 'popup', 'caption']);
+        $this->action->setColumn($this->columnMock);
+        $row = new \Magento\Framework\Object();
+        $row->setId(1);
+        $this->assertContains('action-select', $this->action->render($row));
+    }
+}
diff --git a/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/Grid/Renderer/SenderTest.php b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/Grid/Renderer/SenderTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..572b341759f50c4a7a92daf40444bdd028a05078
--- /dev/null
+++ b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/Grid/Renderer/SenderTest.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Email\Test\Unit\Block\Adminhtml\Template\Grid\Renderer;
+
+/**
+ * @covers Magento\Email\Block\Adminhtml\Template\Grid\Renderer\Sender
+ */
+class SenderTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Email\Block\Adminhtml\Template\Grid\Renderer\Sender
+     */
+    protected $sender;
+
+    protected function setUp()
+    {
+        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $this->sender = $objectManager->getObject('Magento\Email\Block\Adminhtml\Template\Grid\Renderer\Sender');
+    }
+
+    /**
+     * @covers \Magento\Email\Block\Adminhtml\Template\Grid\Renderer\Sender::render
+     */
+    public function testRenderName()
+    {
+        $row = new \Magento\Framework\Object();
+        $row->setTemplateSenderName('Sender Name');
+        $this->assertEquals('Sender Name ', $this->sender->render($row));
+    }
+
+    /**
+     * @covers \Magento\Email\Block\Adminhtml\Template\Grid\Renderer\Sender::render
+     */
+    public function testRenderEmail()
+    {
+        $row = new \Magento\Framework\Object();
+        $row->setTemplateSenderEmail('Sender Email');
+        $this->assertEquals('[Sender Email]', $this->sender->render($row));
+    }
+
+    /**
+     * @covers \Magento\Email\Block\Adminhtml\Template\Grid\Renderer\Sender::render
+     */
+    public function testRenderNameAndEmail()
+    {
+        $row = new \Magento\Framework\Object();
+        $row->setTemplateSenderName('Sender Name');
+        $row->setTemplateSenderEmail('Sender Email');
+        $this->assertEquals('Sender Name [Sender Email]', $this->sender->render($row));
+    }
+
+    /**
+     * @covers \Magento\Email\Block\Adminhtml\Template\Grid\Renderer\Sender::render
+     */
+    public function testRenderEmpty()
+    {
+        $row = new \Magento\Framework\Object();
+        $this->assertEquals('---', $this->sender->render($row));
+    }
+}
diff --git a/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/Grid/Renderer/TypeTest.php b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/Grid/Renderer/TypeTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..0e91708653a13afadd0af9a44dc282e5a0b83210
--- /dev/null
+++ b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/Grid/Renderer/TypeTest.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Email\Test\Unit\Block\Adminhtml\Template\Grid\Renderer;
+
+/**
+ * @covers Magento\Email\Block\Adminhtml\Template\Grid\Renderer\Type
+ */
+class TypeTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Email\Block\Adminhtml\Template\Grid\Renderer\Type
+     */
+    protected $type;
+
+    protected function setUp()
+    {
+        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $this->type = $objectManager->getObject('Magento\Email\Block\Adminhtml\Template\Grid\Renderer\Type');
+    }
+
+    /**
+     * @covers \Magento\Email\Block\Adminhtml\Template\Grid\Renderer\Type::render
+     */
+    public function testRenderHtml()
+    {
+        $row = new \Magento\Framework\Object();
+        $row->setTemplateType(\Magento\Framework\App\TemplateTypesInterface::TYPE_HTML);
+        $this->assertEquals('HTML', $this->type->render($row));
+    }
+
+    /**
+     * @covers \Magento\Email\Block\Adminhtml\Template\Grid\Renderer\Type::render
+     */
+    public function testRenderText()
+    {
+        $row = new \Magento\Framework\Object();
+        $row->setTemplateType(\Magento\Framework\App\TemplateTypesInterface::TYPE_TEXT);
+        $this->assertEquals('Text', $this->type->render($row));
+    }
+
+    /**
+     * @covers \Magento\Email\Block\Adminhtml\Template\Grid\Renderer\Type::render
+     */
+    public function testRenderUnknown()
+    {
+        $row = new \Magento\Framework\Object();
+        $row->setTemplateType('xx');
+        $this->assertEquals('Unknown', $this->type->render($row));
+    }
+}
diff --git a/app/code/Magento/Email/Test/Unit/Block/Adminhtml/TemplateTest.php b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/TemplateTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..57cb9a6392f52fa592190c66b367c7af2f24c862
--- /dev/null
+++ b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/TemplateTest.php
@@ -0,0 +1,121 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Email\Test\Unit\Block\Adminhtml;
+
+/**
+ * @covers Magento\Email\Block\Adminhtml\Template
+ */
+class TemplateTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\Email\Block\Adminhtml\Template */
+    protected $template;
+
+    /** @var \Magento\Backend\Block\Template\Context */
+    protected $context;
+
+    /** @var \Magento\Framework\UrlInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $urlBuilderMock;
+
+    /** @var \Magento\Backend\Block\Widget\Button\ItemFactory|\PHPUnit_Framework_MockObject_MockObject */
+    protected $itemFactoryMock;
+
+    /** @var \Magento\Backend\Block\Widget\Button\ButtonList */
+    protected $buttonList;
+
+    /** @var \Magento\Backend\Block\Widget\Button\Item|\PHPUnit_Framework_MockObject_MockObject */
+    protected $buttonMock;
+
+    /** @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager */
+    protected $objectManager;
+
+    protected function setUp()
+    {
+        $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $this->itemFactoryMock = $this->getMockBuilder('Magento\Backend\Block\Widget\Button\ItemFactory')
+            ->disableOriginalConstructor()
+            ->setMethods(['create'])
+            ->getMock();
+        $this->buttonMock = $this->getMockBuilder('Magento\Backend\Block\Widget\Button\Item')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->itemFactoryMock->expects($this->any())
+            ->method('create')
+            ->willReturn($this->buttonMock);
+        $this->buttonList = $this->objectManager->getObject(
+            'Magento\Backend\Block\Widget\Button\ButtonList',
+            [ 'itemFactory' => $this->itemFactoryMock]
+        );
+        $this->urlBuilderMock = $this->getMockForAbstractClass(
+            'Magento\Framework\UrlInterface',
+            [],
+            '',
+            false,
+            true,
+            true,
+            ['getUrl']
+        );
+        $this->context = $this->objectManager->getObject(
+            'Magento\Backend\Block\Template\Context',
+            [
+                'urlBuilder' => $this->urlBuilderMock
+            ]
+        );
+        $this->template = $this->objectManager->getObject(
+            'Magento\Email\Block\Adminhtml\Template',
+            [
+                'context' => $this->context,
+                'buttonList' => $this->buttonList
+            ]
+        );
+    }
+
+    public function testAddButton()
+    {
+        $this->template->addButton('1', ['title' => 'My Button']);
+        $buttons = $this->buttonList->getItems()[0];
+        $this->assertContains('1', array_keys($buttons));
+    }
+
+    public function testUpdateButton()
+    {
+        $this->testAddButton();
+        $this->buttonMock->expects($this->once())
+            ->method('setData')
+            ->with('title', 'Updated Button')
+            ->willReturnSelf();
+        $result = $this->template->updateButton('1', 'title', 'Updated Button');
+        $this->assertSame($this->template, $result);
+    }
+
+    public function testRemoveButton()
+    {
+        $this->testAddButton();
+        $this->template->removeButton('1');
+        $buttons = $this->buttonList->getItems()[0];
+        $this->assertNotContains('1', array_keys($buttons));
+    }
+
+    public function testGetCreateUrl()
+    {
+        $this->urlBuilderMock->expects($this->once())
+            ->method('getUrl')
+            ->with('adminhtml/*/new', []);
+        $this->template->getCreateUrl();
+    }
+
+    public function testGetHeaderText()
+    {
+        $this->assertEquals('Transactional Emails', $this->template->getHeaderText());
+    }
+
+    public function testCanRender()
+    {
+        $this->buttonMock->expects($this->once())
+            ->method('isDeleted')
+            ->willReturn(false);
+        $this->assertTrue($this->template->canRender($this->buttonMock));
+    }
+}
diff --git a/app/code/Magento/Email/Test/Unit/Controller/Adminhtml/Email/Template/EditTest.php b/app/code/Magento/Email/Test/Unit/Controller/Adminhtml/Email/Template/EditTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..905318c274a3901b8f43cfc3f8afed87b4e04bdc
--- /dev/null
+++ b/app/code/Magento/Email/Test/Unit/Controller/Adminhtml/Email/Template/EditTest.php
@@ -0,0 +1,259 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Email\Test\Unit\Controller\Adminhtml\Email\Template;
+
+/**
+ * @covers \Magento\Email\Controller\Adminhtml\Email\Template\Edit
+ */
+class EditTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Email\Controller\Adminhtml\Email\Template\Edit
+     */
+    protected $editController;
+
+    /**
+     * @var \Magento\Framework\Registry|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $registryMock;
+
+    /**
+     * @var \Magento\Backend\App\Action\Context
+     */
+    protected $context;
+
+    /**
+     * @var \Magento\Framework\App\Request|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $requestMock;
+
+    /**
+     * @var \Magento\Framework\App\View|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $viewMock;
+
+    /**
+     * @var \Magento\Framework\View\Layout|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $layoutMock;
+
+    /**
+     * @var \Magento\Backend\Block\Menu|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $menuBlockMock;
+
+    /**
+     * @var \Magento\Backend\Block\Widget\Breadcrumbs|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $breadcrumbsBlockMock;
+
+    /**
+     * @var \Magento\Backend\Block\Widget\Breadcrumbs|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $editBlockMock;
+
+    /**
+     * @var \Magento\Framework\View\Result\Page|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $resultPageMock;
+
+    /**
+     * @var \Magento\Framework\View\Page\Config|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $pageConfigMock;
+
+    /**
+     * @var \Magento\Framework\View\Page\Title|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $pageTitleMock;
+
+    /**
+     * @return void
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     */
+    protected function setUp()
+    {
+        $this->registryMock = $this->getMockBuilder('Magento\Framework\Registry')
+            ->disableOriginalConstructor()
+            ->setMethods(['registry', 'register'])
+            ->getMock();
+        $this->requestMock = $this->getMockBuilder('Magento\Framework\App\Request\Http')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->viewMock = $this->getMockBuilder('Magento\Framework\App\View')
+            ->disableOriginalConstructor()
+            ->setMethods(['loadLayout', 'getLayout', 'getPage', 'renderLayout'])
+            ->getMock();
+        $this->layoutMock = $this->getMockBuilder('Magento\Framework\View\Layout')
+            ->disableOriginalConstructor()
+            ->setMethods(['getBlock', 'createBlock', 'setChild'])
+            ->getMock();
+        $this->menuBlockMock = $this->getMockBuilder('\Magento\Backend\Block\Menu')
+            ->disableOriginalConstructor()
+            ->setMethods(['setActive', 'getMenuModel', 'getParentItems'])
+            ->getMock();
+        $this->breadcrumbsBlockMock = $this->getMockBuilder('\Magento\Backend\Block\Widget\Breadcrumbs')
+            ->disableOriginalConstructor()
+            ->setMethods(['addLink'])
+            ->getMock();
+        $this->editBlockMock = $this->getMockBuilder('\Magento\Backend\Block\Widget\Breadcrumbs')
+            ->disableOriginalConstructor()
+            ->setMethods(['setEditMode'])
+            ->getMock();
+        $this->resultPageMock = $this->getMockBuilder('Magento\Framework\View\Result\Page')
+            ->disableOriginalConstructor()
+            ->setMethods(['setActiveMenu', 'getConfig', 'addBreadcrumb'])
+            ->getMock();
+        $this->pageConfigMock = $this->getMockBuilder('Magento\Framework\View\Page\Config')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->pageTitleMock = $this->getMockBuilder('Magento\Framework\View\Page\Title')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->viewMock->expects($this->atLeastOnce())
+            ->method('getLayout')
+            ->willReturn($this->layoutMock);
+        $this->layoutMock->expects($this->any())
+            ->method('getBlock')
+            ->willReturnMap(
+                [
+                    ['menu', $this->menuBlockMock],
+                    ['breadcrumbs', $this->breadcrumbsBlockMock],
+                    ['edit', $this->editBlockMock]
+                ]
+            );
+        $this->menuBlockMock->expects($this->any())
+            ->method('getMenuModel')
+            ->will($this->returnSelf());
+        $this->menuBlockMock->expects($this->any())
+            ->method('getParentItems')
+            ->will($this->returnValue([]));
+        $this->viewMock->expects($this->any())
+            ->method('getPage')
+            ->willReturn($this->resultPageMock);
+        $this->resultPageMock->expects($this->any())
+            ->method('getConfig')
+            ->willReturn($this->pageConfigMock);
+        $this->pageConfigMock->expects($this->any())
+            ->method('getTitle')
+            ->willReturn($this->pageTitleMock);
+        $this->layoutMock->expects($this->once())
+            ->method('createBlock')
+            ->with('Magento\Email\Block\Adminhtml\Template\Edit', 'template_edit', [])
+            ->willReturn($this->editBlockMock);
+        $this->editBlockMock->expects($this->once())
+            ->method('setEditMode')
+            ->willReturnSelf();
+
+        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $templateMock = $this->getMockBuilder('Magento\Email\Model\Template')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $templateMock->expects($this->once())
+            ->method('getId')
+            ->willReturn(1);
+        $templateMock->expects($this->any())
+            ->method('getTemplateCode')
+            ->willReturn('My Template');
+        $objectManagerMock = $this->getMockBuilder('Magento\Framework\App\ObjectManager')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $objectManagerMock->expects($this->once())
+            ->method('create')
+            ->with('Magento\Email\Model\BackendTemplate')
+            ->willReturn($templateMock);
+        $this->context = $objectManager->getObject(
+            'Magento\Backend\App\Action\Context',
+            [
+                'request' => $this->requestMock,
+                'objectManager' => $objectManagerMock,
+                'view' => $this->viewMock
+            ]
+        );
+        $this->editController = $objectManager->getObject(
+            'Magento\Email\Controller\Adminhtml\Email\Template\Edit',
+            [
+                'context' => $this->context,
+                'coreRegistry' => $this->registryMock
+            ]
+        );
+    }
+
+    /**
+     * @covers \Magento\Email\Controller\Adminhtml\Email\Template\Edit::execute
+     */
+    public function testExecuteNewTemplate()
+    {
+        $this->requestMock->expects($this->any())
+            ->method('getParam')
+            ->with('id')
+            ->willReturn(0);
+        $this->registryMock->expects($this->atLeastOnce())
+            ->method('registry')
+            ->willReturnMap(
+                [
+                    ['email_template', true],
+                    ['current_email_template', true]
+                ]
+            );
+        $this->pageTitleMock->expects($this->any())
+            ->method('prepend')
+            ->willReturnMap(
+                [
+                    ['Email Templates', $this->returnSelf()],
+                    ['New Template', $this->returnSelf()]
+                ]
+            );
+        $this->breadcrumbsBlockMock->expects($this->any())
+            ->method('addLink')
+            ->willReturnMap(
+                [
+                    ['Transactional Emails', 'Transactional Emails', null, $this->returnSelf()],
+                    ['New Template', 'New System Template', null, $this->returnSelf()]
+                ]
+            );
+
+        $this->assertNull($this->editController->execute());
+    }
+
+    /**
+     * @covers \Magento\Email\Controller\Adminhtml\Email\Template\Edit::execute
+     */
+    public function testExecuteEdit()
+    {
+        $this->requestMock->expects($this->any())
+            ->method('getParam')
+            ->with('id')
+            ->willReturn(1);
+        $this->registryMock->expects($this->atLeastOnce())
+            ->method('registry')
+            ->willReturnMap(
+                [
+                    ['email_template', false],
+                    ['current_email_template', false]
+                ]
+            );
+        $this->pageTitleMock->expects($this->any())
+            ->method('prepend')
+            ->willReturnMap(
+                [
+                    ['Email Templates', $this->returnSelf()],
+                    ['My Template', $this->returnSelf()]
+                ]
+            );
+        $this->breadcrumbsBlockMock->expects($this->any())
+            ->method('addLink')
+            ->willReturnMap(
+                [
+                    ['Transactional Emails', 'Transactional Emails', null, $this->returnSelf()],
+                    ['Edit Template', 'Edit System Template', null, $this->returnSelf()]
+                ]
+            );
+
+        $this->assertNull($this->editController->execute());
+    }
+}
diff --git a/app/code/Magento/Email/Test/Unit/Controller/Adminhtml/Email/Template/IndexTest.php b/app/code/Magento/Email/Test/Unit/Controller/Adminhtml/Email/Template/IndexTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..c5ada6573f6b86c0c52a99a850944c56aacfc26b
--- /dev/null
+++ b/app/code/Magento/Email/Test/Unit/Controller/Adminhtml/Email/Template/IndexTest.php
@@ -0,0 +1,192 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Email\Test\Unit\Controller\Adminhtml\Email\Template;
+
+/**
+ * @covers \Magento\Email\Controller\Adminhtml\Email\Template\Index
+ */
+class IndexTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Email\Controller\Adminhtml\Email\Template\Index
+     */
+    protected $indexController;
+
+    /**
+     * @var \Magento\Framework\Registry|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $registryMock;
+
+    /**
+     * @var \Magento\Backend\App\Action\Context
+     */
+    protected $context;
+
+    /**
+     * @var \Magento\Framework\App\Request|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $requestMock;
+
+    /**
+     * @var \Magento\Framework\App\View|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $viewMock;
+
+    /**
+     * @var \Magento\Framework\View\Layout|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $layoutMock;
+
+    /**
+     * @var \Magento\Backend\Block\Menu|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $menuBlockMock;
+
+    /**
+     * @var \Magento\Backend\Block\Widget\Breadcrumbs|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $breadcrumbsBlockMock;
+
+    /**
+     * @var \Magento\Framework\View\Result\Page|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $resultPageMock;
+
+    /**
+     * @var \Magento\Framework\View\Page\Config|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $pageConfigMock;
+
+    /**
+     * @var \Magento\Framework\View\Page\Title|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $pageTitleMock;
+
+    protected function setUp()
+    {
+        $this->registryMock = $this->getMockBuilder('Magento\Framework\Registry')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->requestMock = $this->getMockBuilder('Magento\Framework\App\Request\Http')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->viewMock = $this->getMockBuilder('Magento\Framework\App\View')
+            ->disableOriginalConstructor()
+            ->setMethods(['loadLayout', 'getLayout', 'getPage', 'renderLayout'])
+            ->getMock();
+        $this->layoutMock = $this->getMockBuilder('Magento\Framework\View\Layout')
+            ->disableOriginalConstructor()
+            ->setMethods(['getBlock'])
+            ->getMock();
+        $this->menuBlockMock = $this->getMockBuilder('\Magento\Backend\Block\Menu')
+            ->disableOriginalConstructor()
+            ->setMethods(['setActive', 'getMenuModel', 'getParentItems'])
+            ->getMock();
+        $this->breadcrumbsBlockMock = $this->getMockBuilder('\Magento\Backend\Block\Widget\Breadcrumbs')
+            ->disableOriginalConstructor()
+            ->setMethods(['addLink'])
+            ->getMock();
+        $this->resultPageMock = $this->getMockBuilder('Magento\Framework\View\Result\Page')
+            ->disableOriginalConstructor()
+            ->setMethods(['setActiveMenu', 'getConfig', 'addBreadcrumb'])
+            ->getMock();
+        $this->pageConfigMock = $this->getMockBuilder('Magento\Framework\View\Page\Config')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->pageTitleMock = $this->getMockBuilder('Magento\Framework\View\Page\Title')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $this->context = $objectManager->getObject(
+            'Magento\Backend\App\Action\Context',
+            [
+                'request' => $this->requestMock,
+                'view' => $this->viewMock
+            ]
+        );
+        $this->indexController = $objectManager->getObject(
+            'Magento\Email\Controller\Adminhtml\Email\Template\Index',
+            [
+                'context' => $this->context,
+                'coreRegistry' => $this->registryMock
+            ]
+        );
+    }
+
+    /**
+     * @covers \Magento\Email\Controller\Adminhtml\Email\Template\Index::execute
+     */
+    public function testExecute()
+    {
+        $this->prepareExecute();
+
+        $this->viewMock->expects($this->atLeastOnce())
+            ->method('getLayout')
+            ->willReturn($this->layoutMock);
+        $this->layoutMock->expects($this->at(0))
+            ->method('getBlock')
+            ->with('menu')
+            ->will($this->returnValue($this->menuBlockMock));
+        $this->menuBlockMock->expects($this->any())
+            ->method('getMenuModel')
+            ->will($this->returnSelf());
+        $this->menuBlockMock->expects($this->any())
+            ->method('getParentItems')
+            ->will($this->returnValue([]));
+        $this->viewMock->expects($this->once())
+            ->method('getPage')
+            ->willReturn($this->resultPageMock);
+        $this->resultPageMock->expects($this->once())
+            ->method('getConfig')
+            ->willReturn($this->pageConfigMock);
+        $this->pageConfigMock->expects($this->once())
+            ->method('getTitle')
+            ->willReturn($this->pageTitleMock);
+        $this->pageTitleMock->expects($this->once())
+            ->method('prepend')
+            ->with('Email Templates');
+        $this->layoutMock->expects($this->at(1))
+            ->method('getBlock')
+            ->with('breadcrumbs')
+            ->will($this->returnValue($this->breadcrumbsBlockMock));
+        $this->breadcrumbsBlockMock->expects($this->any())
+            ->method('addLink')
+            ->willReturnSelf();
+
+        $this->assertNull($this->indexController->execute());
+    }
+
+    /**
+     * @covers \Magento\Email\Controller\Adminhtml\Email\Template\Index::execute
+     */
+    public function testExecuteAjax()
+    {
+        $this->prepareExecute(true);
+        $indexController = $this->getMockBuilder('Magento\Email\Controller\Adminhtml\Email\Template\Index')
+            ->setMethods(['getRequest', '_forward'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $indexController->expects($this->once())
+            ->method('getRequest')
+            ->will($this->returnValue($this->requestMock));
+        $indexController->expects($this->once())
+            ->method('_forward')
+            ->with('grid');
+        $this->assertNull($indexController->execute());
+    }
+
+    /**
+     * @param bool $ajax
+     */
+    protected function prepareExecute($ajax = false)
+    {
+        $this->requestMock->expects($this->once())
+            ->method('getQuery')
+            ->with('ajax')
+            ->willReturn($ajax);
+    }
+}
diff --git a/app/code/Magento/Email/Test/Unit/Model/Source/VariablesTest.php b/app/code/Magento/Email/Test/Unit/Model/Source/VariablesTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..e74ee0d625c59904e80c1e974f5edff2314be4c4
--- /dev/null
+++ b/app/code/Magento/Email/Test/Unit/Model/Source/VariablesTest.php
@@ -0,0 +1,90 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Email\Test\Unit\Model\Source;
+
+use Magento\Store\Model\Store;
+
+/**
+ * Unit test for Magento\Email\Model\Source\Variables
+ */
+class VariablesTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * Variables model
+     *
+     * @var \Magento\Email\Model\Source\Variables
+     */
+    protected $model;
+
+    /**
+     * Config variables
+     *
+     * @var array
+     */
+    protected $configVariables;
+
+    protected function setup()
+    {
+        $helper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $this->model = $helper->getObject('Magento\Email\Model\Source\Variables');
+        $this->configVariables = [
+            [
+                'value' => Store::XML_PATH_UNSECURE_BASE_URL,
+                'label' => __('Base Unsecure URL'),
+            ],
+            ['value' => Store::XML_PATH_SECURE_BASE_URL, 'label' => __('Base Secure URL')],
+            ['value' => 'trans_email/ident_general/name', 'label' => __('General Contact Name')],
+            ['value' => 'trans_email/ident_general/email', 'label' => __('General Contact Email')],
+            ['value' => 'trans_email/ident_sales/name', 'label' => __('Sales Representative Contact Name')],
+            ['value' => 'trans_email/ident_sales/email', 'label' => __('Sales Representative Contact Email')],
+            ['value' => 'trans_email/ident_custom1/name', 'label' => __('Custom1 Contact Name')],
+            ['value' => 'trans_email/ident_custom1/email', 'label' => __('Custom1 Contact Email')],
+            ['value' => 'trans_email/ident_custom2/name', 'label' => __('Custom2 Contact Name')],
+            ['value' => 'trans_email/ident_custom2/email', 'label' => __('Custom2 Contact Email')],
+            ['value' => 'general/store_information/name', 'label' => __('Store Name')],
+            ['value' => 'general/store_information/phone', 'label' => __('Store Phone Number')],
+            ['value' => 'general/store_information/country_id', 'label' => __('Country')],
+            ['value' => 'general/store_information/region_id', 'label' => __('Region/State')],
+            ['value' => 'general/store_information/postcode', 'label' => __('Zip/Postal Code')],
+            ['value' => 'general/store_information/city', 'label' => __('City')],
+            ['value' => 'general/store_information/street_line1', 'label' => __('Street Address 1')],
+            ['value' => 'general/store_information/street_line2', 'label' => __('Street Address 2')],
+        ];
+    }
+
+    public function testToOptionArrayWithoutGroup()
+    {
+        $optionArray = $this->model->toOptionArray();
+        $this->assertEquals(count($this->configVariables), count($optionArray));
+
+        $index = 0;
+        foreach ($optionArray as $variable) {
+            $expectedValue = '{{config path="' . $this->configVariables[$index]['value'] . '"}}';
+            $expectedLabel = $this->configVariables[$index]['label'];
+            $this->assertEquals($expectedValue, $variable['value']);
+            $this->assertEquals($expectedLabel, $variable['label']->getText());
+            $index++;
+        }
+    }
+
+    public function testToOptionArrayWithGroup()
+    {
+        $optionArray = $this->model->toOptionArray(true);
+        $this->assertEquals('Store Contact Information', $optionArray['label']->getText());
+
+        $optionArrayValues = $optionArray['value'];
+        $this->assertEquals(count($this->configVariables), count($optionArrayValues));
+
+        $index = 0;
+        foreach ($optionArrayValues as $variable) {
+            $expectedValue = '{{config path="' . $this->configVariables[$index]['value'] . '"}}';
+            $expectedLabel = $this->configVariables[$index]['label'];
+            $this->assertEquals($expectedValue, $variable['value']);
+            $this->assertEquals($expectedLabel, $variable['label']->getText());
+            $index++;
+        }
+    }
+}
diff --git a/app/code/Magento/Email/Test/Unit/Model/TemplateTest.php b/app/code/Magento/Email/Test/Unit/Model/TemplateTest.php
index 304621aa78b5ee06d108e5a8ddb4f83c448e2ef1..c18cab16cf5844c798af57c0bc12b19711802c76 100644
--- a/app/code/Magento/Email/Test/Unit/Model/TemplateTest.php
+++ b/app/code/Magento/Email/Test/Unit/Model/TemplateTest.php
@@ -5,8 +5,737 @@
  */
 namespace Magento\Email\Test\Unit\Model;
 
+use Magento\Email\Model\Template\Filter;
+use Magento\Framework\App\Filesystem\DirectoryList;
+use Magento\Framework\Filter\Template as FilterTemplate;
+
+/**
+ * Covers \Magento\Email\Model\Template
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
 class TemplateTest extends \PHPUnit_Framework_TestCase
 {
+    /**
+     * @var \Magento\Framework\Model\Context|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $context;
+
+    /**
+     * @var \Magento\Framework\View\DesignInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $design;
+
+    /**
+     * @var \Magento\Framework\Registry|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $registry;
+
+    /**
+     * @var \Magento\Store\Model\App\Emulation|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $appEmulation;
+
+    /**
+     * @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $storeManager;
+
+    /**
+     * @var \Magento\Framework\Filesystem|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $filesystem;
+
+    /**
+     * @var \Magento\Framework\View\Asset\Repository|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $assetRepo;
+
+    /**
+     * @var \Magento\Framework\View\FileSystem|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $viewFileSystem;
+
+    /**
+     * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $scopeConfig;
+
+    /**
+     * @var \Magento\Email\Model\Template\FilterFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $emailFilterFactory;
+
+    /**
+     * @var \Magento\Email\Model\Template\Config|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $emailConfig;
+
+    public function setUp()
+    {
+        $this->context = $this->getMockBuilder('Magento\Framework\Model\Context')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->design = $this->getMockBuilder('Magento\Framework\View\DesignInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->registry = $this->getMockBuilder('Magento\Framework\Registry')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->appEmulation = $this->getMockBuilder('Magento\Store\Model\App\Emulation')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->storeManager = $this->getMockBuilder('Magento\Store\Model\StoreManagerInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->filesystem = $this->getMockBuilder('Magento\Framework\Filesystem')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->assetRepo = $this->getMockBuilder('Magento\Framework\View\Asset\Repository')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->viewFileSystem = $this->getMockBuilder('Magento\Framework\View\FileSystem')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->scopeConfig = $this->getMockBuilder('Magento\Framework\App\Config\ScopeConfigInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->emailFilterFactory = $this->getMockBuilder('Magento\Email\Model\Template\FilterFactory')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->emailConfig = $this->getMockBuilder('Magento\Email\Model\Template\Config')
+            ->disableOriginalConstructor()
+            ->getMock();
+    }
+
+    /**
+     * Return the model under test with additional methods mocked.
+     *
+     * @param $mockedMethods array
+     * @return \Magento\Email\Model\Template|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected function getModelMock(array $mockedMethods = [])
+    {
+        return $this->getMockBuilder('Magento\Email\Model\Template')
+            ->setMethods(array_merge($mockedMethods, ['__wakeup', '__sleep', '_init']))
+            ->setConstructorArgs(
+                [
+                    $this->context,
+                    $this->design,
+                    $this->registry,
+                    $this->appEmulation,
+                    $this->storeManager,
+                    $this->filesystem,
+                    $this->assetRepo,
+                    $this->viewFileSystem,
+                    $this->scopeConfig,
+                    $this->emailFilterFactory,
+                    $this->emailConfig
+                ]
+            )
+            ->getMock();
+    }
+
+    public function testGetDefaultEmailLogo()
+    {
+        $model = $this->getModelMock();
+        $value = 'urlWithParamsValue';
+        $this->assetRepo->method('getUrlWithParams')
+            ->with('Magento_Email::logo_email.png', ['area' => \Magento\Framework\App\Area::AREA_FRONTEND])
+            ->will($this->returnValue($value));
+        $this->assertEquals($value, $model->getDefaultEmailLogo());
+    }
+
+    public function testSetAndGetTemplateFilter()
+    {
+        $model = $this->getModelMock();
+        $filterTemplate = $this->getMockBuilder('Magento\Framework\Filter\Template')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $model->setTemplateFilter($filterTemplate);
+        $this->assertSame($filterTemplate, $model->getTemplateFilter());
+    }
+
+    public function testGetTemplateFilterWithEmptyValue()
+    {
+        $filterTemplate = $this->getMockBuilder('Magento\Framework\Filter\Template')
+            ->setMethods(['setUseAbsoluteLinks', 'setStoreId'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $filterTemplate->expects($this->once())
+            ->method('setUseAbsoluteLinks')
+            ->will($this->returnSelf());
+        $filterTemplate->expects($this->once())
+            ->method('setStoreId')
+            ->will($this->returnSelf());
+        $this->emailFilterFactory->method('create')
+            ->will($this->returnValue($filterTemplate));
+        $designConfig = $this->getMockBuilder('Magento\Framework\Object')
+            ->setMethods(['getStore'])
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $model = $this->getModelMock(['getUseAbsoluteLinks', 'getDesignConfig']);
+        $model->expects($this->once())
+            ->method('getDesignConfig')
+            ->will($this->returnValue($designConfig));
+
+        $this->assertSame($filterTemplate, $model->getTemplateFilter());
+    }
+
+    /**
+     * @param $templateType string
+     * @param $templateText string
+     * @param $parsedTemplateText string
+     * @param $expectedTemplateSubject string|null
+     * @param $expectedOrigTemplateVariables array|null
+     * @param $expectedTemplateStyles string|null
+     * @dataProvider loadDefaultDataProvider
+     */
+    public function testLoadDefault(
+        $templateType,
+        $templateText,
+        $parsedTemplateText,
+        $expectedTemplateSubject,
+        $expectedOrigTemplateVariables,
+        $expectedTemplateStyles
+    ) {
+        $model = $this->getModelMock();
+
+        $templateId = 'templateId';
+
+        $templateFile = 'templateFile';
+        $this->emailConfig->expects($this->once())
+            ->method('getTemplateFilename')
+            ->with($templateId)
+            ->will($this->returnValue($templateFile));
+        $this->emailConfig->expects($this->once())
+            ->method('getTemplateType')
+            ->with($templateId)
+            ->will($this->returnValue($templateType));
+
+        $modulesDir = $this->getMockBuilder('Magento\Framework\Filesystem\Directory\ReadInterface')
+            ->setMethods(['readFile', 'getRelativePath'])
+            ->getMockForAbstractClass();
+
+        $relativePath = 'relativePath';
+        $modulesDir->expects($this->once())
+            ->method('getRelativePath')
+            ->with($templateFile)
+            ->will($this->returnValue($relativePath));
+        $modulesDir->expects($this->once())
+            ->method('readFile')
+            ->will($this->returnValue($templateText));
+
+        $this->filesystem->expects($this->once())
+            ->method('getDirectoryRead')
+            ->with(\Magento\Framework\App\Filesystem\DirectoryList::MODULES)
+            ->will($this->returnValue($modulesDir));
+
+        $model->loadDefault($templateId);
+
+        if ($templateType === 'html') {
+            $this->assertEquals(\Magento\Email\Model\Template::TYPE_HTML, $model->getTemplateType());
+        } else {
+            $this->assertEquals(\Magento\Email\Model\Template::TYPE_TEXT, $model->getTemplateType());
+        }
+        $this->assertEquals($templateId, $model->getId());
+        $this->assertEquals($parsedTemplateText, $model->getTemplateText());
+        $this->assertEquals($expectedTemplateSubject, $model->getTemplateSubject());
+        $this->assertEquals($expectedOrigTemplateVariables, $model->getData('orig_template_variables'));
+        $this->assertEquals($expectedTemplateStyles, $model->getTemplateStyles());
+    }
+
+    public function loadDefaultDataProvider()
+    {
+        return [
+            'empty' => [
+                'templateType' => 'html',
+                'templateText' => '',
+                'parsedTemplateText' => '',
+                'expectedTemplateSubject' => null,
+                'expectedOrigTemplateVariables' => null,
+                'expectedTemplateStyles' => null,
+            ],
+            'copyright in Plain Text Removed' => [
+                'templateType' => 'text',
+                'templateText' => '<!-- Copyright © 2015 Magento. All rights reserved. -->',
+                'parsedTemplateText' => '',
+                'expectedTemplateSubject' => null,
+                'expectedOrigTemplateVariables' => null,
+                'expectedTemplateStyles' => null,
+            ],
+            'copyright in HTML Remains' => [
+                'templateType' => 'html',
+                'templateText' => '<!-- Copyright © 2015 Magento. All rights reserved. -->',
+                'parsedTemplateText' => '<!-- Copyright © 2015 Magento. All rights reserved. -->',
+                'expectedTemplateSubject' => null,
+                'expectedOrigTemplateVariables' => null,
+                'expectedTemplateStyles' => null,
+            ],
+            'subject set' => [
+                'templateType' => 'html',
+                'templateText' => '<!--@subject Email Subject @-->',
+                'parsedTemplateText' => '',
+                'expectedTemplateSubject' => 'Email Subject',
+                'expectedOrigTemplateVariables' => null,
+                'expectedTemplateStyles' => null,
+            ],
+            'orig_template_variables set' => [
+                'templateType' => 'html',
+                'templateText' => '<!--@vars {"store url=\"\"":"Store Url"} @-->Some Other Text',
+                'parsedTemplateText' => 'Some Other Text',
+                'expectedTemplateSubject' => null,
+                'expectedOrigTemplateVariables' => '{"store url=\"\"":"Store Url"}',
+                'expectedTemplateStyles' => null,
+            ],
+            'styles' => [
+                'templateType' => 'html',
+                'templateText' => '<!--@vars {"store url=\"\"":"Store Url"} @-->Some Other Text',
+                'parsedTemplateText' => 'Some Other Text',
+                'expectedTemplateSubject' => null,
+                'expectedOrigTemplateVariables' => '{"store url=\"\"":"Store Url"}',
+                'expectedTemplateStyles' => null,
+            ],
+        ];
+    }
+
+    public function testLoadByCode()
+    {
+        $templateCode = 'templateCode';
+        $templateData = ['templateData'];
+        $resource = $this->getMockBuilder('Magento\Email\Model\Resource\Template')
+            ->setMethods(['loadByCode'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $resource->expects($this->once())
+            ->method('loadByCode')
+            ->with($templateCode)
+            ->will($this->returnValue($templateData));
+        $model = $this->getModelMock(['addData', 'getResource']);
+        $model->expects($this->once())
+            ->method('getResource')
+            ->will($this->returnValue($resource));
+        $model->expects($this->once())
+            ->method('addData')
+            ->with($templateData);
+        $this->assertEquals($model, $model->loadByCode($templateCode));
+    }
+
+    public function testGetAndSetId()
+    {
+        $model = $this->getModelMock();
+        $templateId = 'templateId';
+        $this->assertEquals($model, $model->setId($templateId));
+        $this->assertEquals($templateId, $model->getId());
+    }
+
+    /**
+     * @param $isSMTPDisabled bool
+     * @param $senderName string
+     * @param $senderEmail string
+     * @param $templateSubject string
+     * @dataProvider isValidForSendDataProvider
+     */
+    public function testIsValidForSend($isSMTPDisabled, $senderName, $senderEmail, $templateSubject, $expectedValue)
+    {
+        $this->scopeConfig->expects($this->once())
+            ->method('isSetFlag')
+            ->with('system/smtp/disable', \Magento\Store\Model\ScopeInterface::SCOPE_STORE)
+            ->will($this->returnValue($isSMTPDisabled));
+        $model = $this->getModelMock(['getSenderName', 'getSenderEmail', 'getTemplateSubject']);
+        $model->expects($this->any())
+            ->method('getSenderName')
+            ->will($this->returnValue($senderName));
+        $model->expects($this->any())
+            ->method('getSenderEmail')
+            ->will($this->returnValue($senderEmail));
+        $model->expects($this->any())
+            ->method('getTemplateSubject')
+            ->will($this->returnValue($templateSubject));
+        $this->assertEquals($expectedValue, $model->isValidForSend());
+    }
+
+    public function isValidForSendDataProvider()
+    {
+        return [
+            'should be valid' => [
+                'isSMTPDisabled' => false,
+                'senderName' => 'sender name',
+                'senderEmail' => 'email@example.com',
+                'templateSubject' => 'template subject',
+                'expectedValue' => true
+            ],
+            'no smtp so not valid' => [
+                'isSMTPDisabled' => true,
+                'senderName' => 'sender name',
+                'senderEmail' => 'email@example.com',
+                'templateSubject' => 'template subject',
+                'expectedValue' => false
+            ],
+            'no sender name so not valid' => [
+                'isSMTPDisabled' => false,
+                'senderName' => '',
+                'senderEmail' => 'email@example.com',
+                'templateSubject' => 'template subject',
+                'expectedValue' => false
+            ],
+            'no sender email so not valid' => [
+                'isSMTPDisabled' => false,
+                'senderName' => 'sender name',
+                'senderEmail' => '',
+                'templateSubject' => 'template subject',
+                'expectedValue' => false
+            ],
+            'no subject so not valid' => [
+                'isSMTPDisabled' => false,
+                'senderName' => 'sender name',
+                'senderEmail' => 'email@example.com',
+                'templateSubject' => '',
+                'expectedValue' => false
+            ],
+        ];
+    }
+
+    /**
+     * @param $variables array
+     * @param $templateType string
+     * @param $storeId int
+     * @param $expectedVariables array
+     * @param $expectedResult string
+     * @dataProvider getProcessedTemplateProvider
+     */
+    public function testGetProcessedTemplate($variables, $templateType, $storeId, $expectedVariables, $expectedResult)
+    {
+        $filterTemplate = $this->getMockBuilder('Magento\Framework\Filter\Template')
+            ->setMethods([
+                'setUseSessionInUrl',
+                'setPlainTemplateMode',
+                'setVariables',
+                'setStoreId',
+                'filter',
+                'getStoreId',
+            ])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $filterTemplate->expects($this->once())
+            ->method('setUseSessionInUrl')
+            ->with(false)
+            ->will($this->returnSelf());
+        $filterTemplate->expects($this->once())
+            ->method('setPlainTemplateMode')
+            ->with($templateType === \Magento\Framework\App\TemplateTypesInterface::TYPE_TEXT)
+            ->will($this->returnSelf());
+        $filterTemplate->expects($this->any())
+            ->method('setStoreId')
+            ->will($this->returnSelf());
+        $filterTemplate->expects($this->any())
+            ->method('getStoreId')
+            ->will($this->returnValue($storeId));
+
+        $store = $this->getMockBuilder('Magento\Store\Model\Store')
+            ->setMethods(['getFrontendName'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $store->expects($this->any())
+            ->method('getFrontendName')
+            ->will($this->returnValue('frontendName'));
+        $this->storeManager->expects($this->any())
+            ->method('getStore')
+            ->will($this->returnValue($store));
+
+        $model = $this->getModelMock(['getDesignConfig', '_applyDesignConfig', 'getPreparedTemplateText']);
+        $model->setTemplateFilter($filterTemplate);
+        $model->setTemplateType($templateType);
+
+        $designConfig = $this->getMockBuilder('Magento\Framework\Object')
+            ->setMethods(['getStore'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $storeId = 'storeId';
+        $designConfig->expects($this->once())
+            ->method('getStore')
+            ->will($this->returnValue($storeId));
+        $model->expects($this->once())
+            ->method('getDesignConfig')
+            ->will($this->returnValue($designConfig));
+        $filterTemplate->expects($this->once())
+            ->method('setVariables')
+            ->with(array_merge([ 'this' => $model], $expectedVariables));
+
+        $preparedTemplateText = 'prepared text';
+        $model->expects($this->once())
+            ->method('getPreparedTemplateText')
+            ->will($this->returnValue($preparedTemplateText));
+        $filterTemplate->expects($this->once())
+            ->method('filter')
+            ->with($preparedTemplateText)
+            ->will($this->returnValue($expectedResult));
+
+        $this->assertEquals($expectedResult, $model->getProcessedTemplate($variables));
+    }
+
+    /**
+     * @return array
+     */
+    public function getProcessedTemplateProvider()
+    {
+        return [
+            'default' => [
+                'variables' => [],
+                'templateType' => \Magento\Framework\App\TemplateTypesInterface::TYPE_TEXT,
+                'storeId' => 1,
+                'expectedVariables' => [
+                    'logo_url' => null,
+                    'logo_alt' => 'frontendName',
+                ],
+                'expectedResult' => 'expected result',
+            ],
+            'logo variables set' => [
+                'variables' => [
+                    'logo_url' => 'http://example.com/logo',
+                    'logo_alt' => 'Logo Alt',
+                ],
+                'templateType' => \Magento\Framework\App\TemplateTypesInterface::TYPE_HTML,
+                'storeId' => 1,
+                'expectedVariables' => [
+                    'logo_url' => 'http://example.com/logo',
+                    'logo_alt' => 'Logo Alt',
+                ],
+                'expectedResult' => 'expected result',
+            ],
+        ];
+    }
+
+    /**
+     * @param $templateType string
+     * @param $templateStyles string
+     * @param $templateText string
+     * @param $expectedResult string
+     * @dataProvider getPreparedTemplateTextProvider
+     */
+    public function testGetPreparedTemplateText($templateType, $templateStyles, $templateText, $expectedResult)
+    {
+        $model = $this->getModelMock();
+        $model->setTemplateType($templateType);
+        $model->setTemplateStyles($templateStyles);
+        $model->setTemplateText($templateText);
+        $this->assertEquals($expectedResult, $model->getPreparedTemplateText());
+    }
+
+    public function getPreparedTemplateTextProvider()
+    {
+        return [
+            'plain text' => [
+                'templateType' => \Magento\Framework\App\TemplateTypesInterface::TYPE_TEXT,
+                'templateStyles' => '<style>',
+                'templateText' => 'template text',
+                'expectedResult' => 'template text',
+            ],
+            'html no style' => [
+                'templateType' => \Magento\Framework\App\TemplateTypesInterface::TYPE_HTML,
+                'templateStyles' => '',
+                'templateText' => 'template text',
+                'expectedResult' => 'template text',
+            ],
+            'html with style' => [
+                'templateType' => \Magento\Framework\App\TemplateTypesInterface::TYPE_HTML,
+                'templateStyles' => '.body { color: orange }',
+                'templateText' => 'template text',
+                'expectedResult' =>
+                    '<style type="text/css">' . "\n.body { color: orange }\n</style>\n" . 'template text',
+            ],
+        ];
+    }
+
+    public function testGetProcessedTemplateSubject()
+    {
+        $model = $this->getModelMock(['getTemplateFilter', 'getDesignConfig', '_applyDesignConfig']);
+
+        $templateSubject = 'templateSubject';
+        $model->setTemplateSubject($templateSubject);
+
+        $filterTemplate = $this->getMockBuilder('Magento\Framework\Filter\Template')
+            ->setMethods(['setVariables', 'setStoreId', 'filter'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $model->expects($this->once())
+            ->method('getTemplateFilter')
+            ->will($this->returnValue($filterTemplate));
+
+        $model->expects($this->once())
+            ->method('_applyDesignConfig');
+
+        $designConfig = $this->getMockBuilder('Magento\Framework\Object')
+            ->setMethods(['getStore'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $storeId = 'storeId';
+        $designConfig->expects($this->once())
+            ->method('getStore')
+            ->will($this->returnValue($storeId));
+        $model->expects($this->once())
+            ->method('getDesignConfig')
+            ->will($this->returnValue($designConfig));
+
+        $filterTemplate->expects($this->once())
+            ->method('setStoreId')
+            ->with($storeId)
+            ->will($this->returnSelf());
+        $expectedResult = 'expected';
+        $filterTemplate->expects($this->once())
+            ->method('filter')
+            ->with($templateSubject)
+            ->will($this->returnValue($expectedResult));
+
+        $variables = [ 'key' => 'value' ];
+        $filterTemplate->expects($this->once())
+            ->method('setVariables')
+            ->with(array_merge($variables, ['this' => $model]));
+        $this->assertEquals($expectedResult, $model->getProcessedTemplateSubject($variables));
+    }
+
+    /**
+     * @param $withGroup bool
+     * @param $templateVariables string
+     * @param $expectedResult array
+     * @dataProvider getVariablesOptionArrayDataProvider
+     */
+    public function testGetVariablesOptionArray($withGroup, $templateVariables, $expectedResult)
+    {
+        $model = $this->getModelMock();
+        $model->setData('orig_template_variables', $templateVariables);
+        $this->assertEquals($expectedResult, $model->getVariablesOptionArray($withGroup));
+    }
+
+    public function getVariablesOptionArrayDataProvider()
+    {
+        return [
+            'empty variables' => [
+                'withGroup' => false,
+                'templateVariables' => '',
+                'expectedResult' => [],
+            ],
+            'empty variables with grouped option' => [
+                'withGroup' => true,
+                'templateVariables' => '',
+                'expectedResult' => [],
+            ],
+            'customer account new variables' => [
+                'withGroup' => false,
+                'templateVariables' => '{"store url=\"\"":"Store Url","var logo_url":"Email Logo Image Url",'
+                . '"escapehtml var=$customer.name":"Customer Name"}',
+                'expectedResult' => [
+                    [
+                        'value' => '{{store url=""}}',
+                        'label' => __('%1', 'Store Url'),
+                    ],
+                    [
+                        'value' => '{{var logo_url}}',
+                        'label' => __('%1', 'Email Logo Image Url'),
+                    ],
+                    [
+                        'value' => '{{escapehtml var=$customer.name}}',
+                        'label' => __('%1', 'Customer Name'),
+                    ],
+                ],
+            ],
+            'customer account new variables with grouped option' => [
+                'withGroup' => true,
+                'templateVariables' => '{"store url=\"\"":"Store Url","var logo_url":"Email Logo Image Url",'
+                . '"escapehtml var=$customer.name":"Customer Name"}',
+                'expectedResult' => [
+                    'label' => __('Template Variables'),
+                    'value' => [
+                        [
+                            'value' => '{{store url=""}}',
+                            'label' => __('%1', 'Store Url'),
+                        ],
+                        [
+                            'value' => '{{var logo_url}}',
+                            'label' => __('%1', 'Email Logo Image Url'),
+                        ],
+                        [
+                            'value' => '{{escapehtml var=$customer.name}}',
+                            'label' => __('%1', 'Customer Name'),
+                        ],
+                    ],
+                ],
+            ],
+        ];
+    }
+
+    /**
+     * @param $templateId string|int
+     * @param $expectedResult string
+     * @dataProvider processTemplateVariable
+     */
+    public function testProcessTemplate($templateId, $expectedResult)
+    {
+        $model = $this->getModelMock([
+            'load',
+            'loadDefault',
+            'getProcessedTemplate'
+        ]);
+        $model->setId($templateId);
+        if (is_numeric($templateId)) {
+            $model->expects($this->once())
+                ->method('load')
+                ->with($templateId);
+        } else {
+            $model->expects($this->once())
+                ->method('loadDefault')
+                ->with($templateId);
+        }
+
+        $vars = [ 'key' => 'value' ];
+        $model->setVars($vars);
+        $model->expects($this->once())
+            ->method('getProcessedTemplate')
+            ->with($vars, true)
+            ->will($this->returnValue($expectedResult));
+
+        $this->assertEquals($expectedResult, $model->processTemplate());
+        $this->assertTrue($model->getUseAbsoluteLinks());
+    }
+
+    public function processTemplateVariable()
+    {
+        return [
+            'numeric id' => [
+                'templateId' => 1,
+                'expectedResult' => 'expected result',
+            ],
+            'string id' => [
+                'templateId' => 'my id',
+                'expectedResult' => 'expected result',
+            ],
+        ];
+    }
+
+    public function testGetSubject()
+    {
+        $variables = [ 'key' => 'value' ];
+        $model = $this->getModelMock(['getProcessedTemplateSubject']);
+        $model->setVars($variables);
+        $expectedResult = 'result';
+        $model->expects($this->once())
+            ->method('getProcessedTemplateSubject')
+            ->with($variables)
+            ->will($this->returnValue($expectedResult));
+        $this->assertEquals($expectedResult, $model->getSubject());
+    }
+
+    public function testSetOptions()
+    {
+        $options = ['someOption' => 'someValue'];
+        $model = $this->getModelMock(['setDesignConfig']);
+        $model->expects($this->once())
+            ->method('setDesignConfig')
+            ->with($options);
+        $model->setOptions($options);
+    }
+
     /**
      * @dataProvider getTypeDataProvider
      * @param string $templateType
diff --git a/app/code/Magento/Email/composer.json b/app/code/Magento/Email/composer.json
index bf8f13e936765f2463b88d78cd116045af005df0..1ea2d97faf7463293d39d9e65617cfa53ae03886 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-beta1",
-        "magento/module-store": "0.74.0-beta1",
-        "magento/module-cms": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-variable": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-config": "0.74.0-beta2",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-cms": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-variable": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Fedex/Setup/InstallData.php b/app/code/Magento/Fedex/Setup/InstallData.php
index ce35f99800209d55db02447bcdec8f61c0a19bbe..55363c9acc31db62d062092e70aff7541e946ef1 100755
--- a/app/code/Magento/Fedex/Setup/InstallData.php
+++ b/app/code/Magento/Fedex/Setup/InstallData.php
@@ -96,7 +96,7 @@ class InstallData implements InstallDataInterface
                         $mapNew[] = $shippingMethod;
                     }
                 }
-                $mapNew = implode($mapNew, ',');
+                $mapNew = implode(',', $mapNew);
             } else {
                 continue;
             }
diff --git a/app/code/Magento/Fedex/composer.json b/app/code/Magento/Fedex/composer.json
index 39dea42bc6425365ab31299c40337bf852d7d535..090e04498b0459ffd3621b67917a16f83004e0e6 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-beta1",
-        "magento/module-shipping": "0.74.0-beta1",
-        "magento/module-directory": "0.74.0-beta1",
-        "magento/module-catalog": "0.74.0-beta1",
-        "magento/module-sales": "0.74.0-beta1",
-        "magento/module-catalog-inventory": "0.74.0-beta1",
-        "magento/module-quote": "0.74.0-beta1",
-        "magento/module-config": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-shipping": "0.74.0-beta2",
+        "magento/module-directory": "0.74.0-beta2",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/module-sales": "0.74.0-beta2",
+        "magento/module-catalog-inventory": "0.74.0-beta2",
+        "magento/module-quote": "0.74.0-beta2",
+        "magento/module-config": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "lib-libxml": "*",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/GiftMessage/Api/CartRepositoryInterface.php b/app/code/Magento/GiftMessage/Api/CartRepositoryInterface.php
index 62a7916c14ca9479e2a9feefa458aa2c8aacf5ed..7e34c18ed0d6531fef0ce82b093e9b0551aa549f 100644
--- a/app/code/Magento/GiftMessage/Api/CartRepositoryInterface.php
+++ b/app/code/Magento/GiftMessage/Api/CartRepositoryInterface.php
@@ -8,7 +8,7 @@ namespace Magento\GiftMessage\Api;
 interface CartRepositoryInterface
 {
     /**
-     * Returns the gift message for a specified order.
+     * Return the gift message for a specified order.
      *
      * @param int $cartId The shopping cart ID.
      * @return \Magento\GiftMessage\Api\Data\MessageInterface Gift message.
@@ -16,7 +16,7 @@ interface CartRepositoryInterface
     public function get($cartId);
 
     /**
-     * Sets the gift message for an entire order.
+     * Set the gift message for an entire order.
      *
      * @param int $cartId The cart ID.
      * @param \Magento\GiftMessage\Api\Data\MessageInterface $giftMessage The gift message.
diff --git a/app/code/Magento/GiftMessage/Api/Data/MessageInterface.php b/app/code/Magento/GiftMessage/Api/Data/MessageInterface.php
index a044e7c0ab0c72253dc3b375c1ed2677fb47c389..5faf04f77045c257707bc84fd3e9466380aa6349 100644
--- a/app/code/Magento/GiftMessage/Api/Data/MessageInterface.php
+++ b/app/code/Magento/GiftMessage/Api/Data/MessageInterface.php
@@ -18,14 +18,14 @@ interface MessageInterface extends \Magento\Framework\Api\ExtensibleDataInterfac
     /**#@-*/
 
     /**
-     * Returns the gift message ID.
+     * Return the gift message ID.
      *
      * @return int|null Gift message ID. Otherwise, null.
      */
     public function getGiftMessageId();
 
     /**
-     * Sets the gift message ID.
+     * Set the gift message ID.
      *
      * @param int|null $id
      * @return $this
@@ -33,14 +33,14 @@ interface MessageInterface extends \Magento\Framework\Api\ExtensibleDataInterfac
     public function setGiftMessageId($id);
 
     /**
-     * Returns the customer ID.
+     * Return the customer ID.
      *
      * @return int|null Customer ID. Otherwise, null.
      */
     public function getCustomerId();
 
     /**
-     * Sets the customer ID.
+     * Set the customer ID.
      *
      * @param int|null $id
      * @return $this
@@ -48,14 +48,14 @@ interface MessageInterface extends \Magento\Framework\Api\ExtensibleDataInterfac
     public function setCustomerId($id);
 
     /**
-     * Returns the sender name.
+     * Return the sender name.
      *
      * @return string Sender name.
      */
     public function getSender();
 
     /**
-     * Sets the sender name.
+     * Set the sender name.
      *
      * @param string $sender
      * @return $this
@@ -63,14 +63,14 @@ interface MessageInterface extends \Magento\Framework\Api\ExtensibleDataInterfac
     public function setSender($sender);
 
     /**
-     * Returns the recipient name.
+     * Return the recipient name.
      *
      * @return string Recipient name.
      */
     public function getRecipient();
 
     /**
-     * Gets the recipient name.
+     * Get the recipient name.
      *
      * @param string $recipient
      * @return $this
@@ -78,14 +78,14 @@ interface MessageInterface extends \Magento\Framework\Api\ExtensibleDataInterfac
     public function setRecipient($recipient);
 
     /**
-     * Returns the message text.
+     * Return the message text.
      *
      * @return string Message text.
      */
     public function getMessage();
 
     /**
-     * Sets the message text.
+     * Set the message text.
      *
      * @param string $message
      * @return $this
diff --git a/app/code/Magento/GiftMessage/Api/ItemRepositoryInterface.php b/app/code/Magento/GiftMessage/Api/ItemRepositoryInterface.php
index f0141740b3ed9b34f40822415c3d301e16e27876..3e2f771fad1337908d2fa1759d8760911c7b0bf7 100644
--- a/app/code/Magento/GiftMessage/Api/ItemRepositoryInterface.php
+++ b/app/code/Magento/GiftMessage/Api/ItemRepositoryInterface.php
@@ -8,7 +8,7 @@ namespace Magento\GiftMessage\Api;
 interface ItemRepositoryInterface
 {
     /**
-     * Returns the gift message for a specified item in a specified shopping cart.
+     * Return the gift message for a specified item in a specified shopping cart.
      *
      * @param int $cartId The shopping cart ID.
      * @param int $itemId The item ID.
@@ -18,7 +18,7 @@ interface ItemRepositoryInterface
     public function get($cartId, $itemId);
 
     /**
-     * Sets the gift message for a specified item in a specified shopping cart.
+     * Set the gift message for a specified item in a specified shopping cart.
      *
      * @param int $cartId The cart ID.
      * @param \Magento\GiftMessage\Api\Data\MessageInterface $giftMessage The gift message.
diff --git a/app/code/Magento/GiftMessage/Api/OrderItemRepositoryInterface.php b/app/code/Magento/GiftMessage/Api/OrderItemRepositoryInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..4b94af3ce5f6155fb451021ed6ae1b581b9fbf8f
--- /dev/null
+++ b/app/code/Magento/GiftMessage/Api/OrderItemRepositoryInterface.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\GiftMessage\Api;
+
+interface OrderItemRepositoryInterface
+{
+    /**
+     * Return the gift message for a specified item in a specified order.
+     *
+     * @param int $orderId The order ID.
+     * @param int $orderItemId The item ID.
+     * @return \Magento\GiftMessage\Api\Data\MessageInterface Gift message.
+     * @throws \Magento\Framework\Exception\NoSuchEntityException
+     */
+    public function get($orderId, $orderItemId);
+
+    /**
+     * Set the gift message for a specified item in a specified order.
+     *
+     * @param int $orderId The order ID.
+     * @param int $orderItemId The item ID.
+     * @param \Magento\GiftMessage\Api\Data\MessageInterface $giftMessage The gift message.
+     * @return bool
+     * @throws \Magento\Framework\Exception\NoSuchEntityException
+     * @throws \Magento\Framework\Exception\State\InvalidTransitionException
+     * @throws \Magento\Framework\Exception\CouldNotSaveException
+     */
+    public function save($orderId, $orderItemId, \Magento\GiftMessage\Api\Data\MessageInterface $giftMessage);
+}
diff --git a/app/code/Magento/GiftMessage/Api/OrderRepositoryInterface.php b/app/code/Magento/GiftMessage/Api/OrderRepositoryInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..28f5b54dde526722c322f5c319cfb8c48b1c943e
--- /dev/null
+++ b/app/code/Magento/GiftMessage/Api/OrderRepositoryInterface.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\GiftMessage\Api;
+
+interface OrderRepositoryInterface
+{
+    /**
+     * Return the gift message for a specified order.
+     *
+     * @param int $orderId The order ID.
+     * @return \Magento\GiftMessage\Api\Data\MessageInterface Gift message.
+     * @throws \Magento\Framework\Exception\NoSuchEntityException
+     */
+    public function get($orderId);
+
+    /**
+     * Set the gift message for an entire order.
+     *
+     * @param int $orderId The order ID.
+     * @param \Magento\GiftMessage\Api\Data\MessageInterface $giftMessage The gift message.
+     * @return bool
+     * @throws \Magento\Framework\Exception\NoSuchEntityException
+     * @throws \Magento\Framework\Exception\InputException
+     * @throws \Magento\Framework\Exception\CouldNotSaveException
+     * @throws \Magento\Framework\Exception\State\InvalidTransitionException
+     */
+    public function save($orderId, \Magento\GiftMessage\Api\Data\MessageInterface $giftMessage);
+}
diff --git a/app/code/Magento/GiftMessage/Block/Adminhtml/Sales/Order/Create/Form.php b/app/code/Magento/GiftMessage/Block/Adminhtml/Sales/Order/Create/Form.php
index 44933c3de7c0ce179be214e10f64ec62bc047491..c5d2d46cccfb1f1904b25be12d0a83610de04f2b 100644
--- a/app/code/Magento/GiftMessage/Block/Adminhtml/Sales/Order/Create/Form.php
+++ b/app/code/Magento/GiftMessage/Block/Adminhtml/Sales/Order/Create/Form.php
@@ -47,6 +47,6 @@ class Form extends \Magento\Backend\Block\Template
     public function canDisplayGiftmessageForm()
     {
         $quote = $this->_sessionQuote->getQuote();
-        return $this->_messageHelper->getIsMessagesAvailable('items', $quote, $quote->getStore());
+        return $this->_messageHelper->isMessagesAllowed('items', $quote, $quote->getStore());
     }
 }
diff --git a/app/code/Magento/GiftMessage/Block/Adminhtml/Sales/Order/Create/Items.php b/app/code/Magento/GiftMessage/Block/Adminhtml/Sales/Order/Create/Items.php
index ebd3613070da152027828aa917a87d1514f9e2a5..f343fce19c7d8d64243d6806bb1bb42784af755e 100644
--- a/app/code/Magento/GiftMessage/Block/Adminhtml/Sales/Order/Create/Items.php
+++ b/app/code/Magento/GiftMessage/Block/Adminhtml/Sales/Order/Create/Items.php
@@ -52,7 +52,7 @@ class Items extends \Magento\Backend\Block\Template
         if (!$item) {
             return false;
         }
-        return $this->_messageHelper->getIsMessagesAvailable('item', $item, $item->getStoreId());
+        return $this->_messageHelper->isMessagesAllowed('item', $item, $item->getStoreId());
     }
 
     /**
diff --git a/app/code/Magento/GiftMessage/Block/Message/Inline.php b/app/code/Magento/GiftMessage/Block/Message/Inline.php
index 71edfa4fe880d23684edf68185276ec1c6d2677f..4a7640f3aa7814cbdfb04a47430d3905d7236065 100644
--- a/app/code/Magento/GiftMessage/Block/Message/Inline.php
+++ b/app/code/Magento/GiftMessage/Block/Message/Inline.php
@@ -317,7 +317,7 @@ class Inline extends \Magento\Framework\View\Element\Template
      */
     public function isMessagesAvailable()
     {
-        return $this->_giftMessageMessage->isMessagesAvailable('quote', $this->getEntity());
+        return $this->_giftMessageMessage->isMessagesAllowed('quote', $this->getEntity());
     }
 
     /**
@@ -329,7 +329,7 @@ class Inline extends \Magento\Framework\View\Element\Template
     public function isItemMessagesAvailable($item)
     {
         $type = substr($this->getType(), 0, 5) == 'multi' ? 'address_item' : 'item';
-        return $this->_giftMessageMessage->isMessagesAvailable($type, $item);
+        return $this->_giftMessageMessage->isMessagesAllowed($type, $item);
     }
 
     /**
diff --git a/app/code/Magento/GiftMessage/Helper/Message.php b/app/code/Magento/GiftMessage/Helper/Message.php
index a54b8c5db8c53d005aa7c6968e8ac4c4767d3594..e2ab3e3eefa6fcce05032ef3437ee17b771616b4 100644
--- a/app/code/Magento/GiftMessage/Helper/Message.php
+++ b/app/code/Magento/GiftMessage/Helper/Message.php
@@ -109,7 +109,7 @@ class Message extends \Magento\Framework\App\Helper\AbstractHelper
      */
     public function getInline($type, \Magento\Framework\Object $entity, $dontDisplayContainer = false)
     {
-        if (!$this->skipPage($type) && !$this->isMessagesAvailable($type, $entity)) {
+        if (!$this->skipPage($type) && !$this->isMessagesAllowed($type, $entity)) {
             return '';
         }
         return $this->_layoutFactory->create()->createBlock('Magento\GiftMessage\Block\Message\Inline')
@@ -129,7 +129,7 @@ class Message extends \Magento\Framework\App\Helper\AbstractHelper
     }
 
     /**
-     * Check availability of giftmessages for specified entity.
+     * Check if giftmessages is allowed for specified entity.
      *
      * @param string $type
      * @param \Magento\Framework\Object $entity
@@ -137,12 +137,16 @@ class Message extends \Magento\Framework\App\Helper\AbstractHelper
      * @return bool|string|null
      * @SuppressWarnings(PHPMD.CyclomaticComplexity)
      */
-    public function isMessagesAvailable($type, \Magento\Framework\Object $entity, $store = null)
+    public function isMessagesAllowed($type, \Magento\Framework\Object $entity, $store = null)
     {
         if ($type == 'items') {
             $items = $entity->getAllItems();
             if (!is_array($items) || empty($items)) {
-                return $this->scopeConfig->getValue(self::XPATH_CONFIG_GIFT_MESSAGE_ALLOW_ITEMS, \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $store);
+                return $this->scopeConfig->getValue(
+                    self::XPATH_CONFIG_GIFT_MESSAGE_ALLOW_ITEMS,
+                    \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
+                    $store
+                );
             }
             if ($entity instanceof \Magento\Quote\Model\Quote) {
                 $_type = $entity->getIsMultiShipping() ? 'address_item' : 'item';
@@ -153,7 +157,7 @@ class Message extends \Magento\Framework\App\Helper\AbstractHelper
                 if ($item->getParentItem()) {
                     continue;
                 }
-                if ($this->isMessagesAvailable($_type, $item, $store)) {
+                if ($this->isMessagesAllowed($_type, $item, $store)) {
                     return true;
                 }
             }
@@ -177,7 +181,11 @@ class Message extends \Magento\Framework\App\Helper\AbstractHelper
                 $store
             );
         } else {
-            return $this->scopeConfig->getValue(self::XPATH_CONFIG_GIFT_MESSAGE_ALLOW_ORDER, \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $store);
+            return $this->scopeConfig->getValue(
+                self::XPATH_CONFIG_GIFT_MESSAGE_ALLOW_ORDER,
+                \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
+                $store
+            );
         }
         return false;
     }
@@ -191,7 +199,10 @@ class Message extends \Magento\Framework\App\Helper\AbstractHelper
      */
     protected function _getDependenceFromStoreConfig($productGiftMessageAllow, $store = null)
     {
-        $result = $this->scopeConfig->getValue(self::XPATH_CONFIG_GIFT_MESSAGE_ALLOW_ITEMS, \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $store);
+        $result = $this->scopeConfig->getValue(
+            self::XPATH_CONFIG_GIFT_MESSAGE_ALLOW_ITEMS,
+            \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $store
+        );
         if ($productGiftMessageAllow === '' || is_null($productGiftMessageAllow)) {
             return $result;
         } else {
@@ -199,19 +210,6 @@ class Message extends \Magento\Framework\App\Helper\AbstractHelper
         }
     }
 
-    /**
-     * Alias for isMessagesAvailable(...)
-     *
-     * @param string $type
-     * @param \Magento\Framework\Object $entity
-     * @param \Magento\Store\Model\Store|int|null $store
-     * @return bool|null|string
-     */
-    public function getIsMessagesAvailable($type, \Magento\Framework\Object $entity, $store = null)
-    {
-        return $this->isMessagesAvailable($type, $entity, $store);
-    }
-
     /**
      * Retrieve escaped and preformated gift message text for specified entity
      *
@@ -293,7 +291,7 @@ class Message extends \Magento\Framework\App\Helper\AbstractHelper
     public function getAvailableForQuoteItems($quote, $store = null)
     {
         foreach ($quote->getAllItems() as $item) {
-            if ($this->isMessagesAvailable('item', $item, $store)) {
+            if ($this->isMessagesAllowed('item', $item, $store)) {
                 return true;
             }
         }
@@ -311,7 +309,7 @@ class Message extends \Magento\Framework\App\Helper\AbstractHelper
     public function getAvailableForAddressItems($items, $store = null)
     {
         foreach ($items as $item) {
-            if ($this->isMessagesAvailable('address_item', $item, $store)) {
+            if ($this->isMessagesAllowed('address_item', $item, $store)) {
                 return true;
             }
         }
diff --git a/app/code/Magento/GiftMessage/Model/CartRepository.php b/app/code/Magento/GiftMessage/Model/CartRepository.php
index bb1b66db7d20d0f5b42e2321eaf354030e4661f9..4fe6b988236c6258fc0d7f7068a72f803468debb 100644
--- a/app/code/Magento/GiftMessage/Model/CartRepository.php
+++ b/app/code/Magento/GiftMessage/Model/CartRepository.php
@@ -107,7 +107,7 @@ class CartRepository implements \Magento\GiftMessage\Api\CartRepositoryInterface
         if ($quote->isVirtual()) {
             throw new InvalidTransitionException(__('Gift Messages is not applicable for virtual products'));
         }
-        if (!$this->helper->getIsMessagesAvailable('quote', $quote, $this->storeManager->getStore())) {
+        if (!$this->helper->isMessagesAllowed('quote', $quote, $this->storeManager->getStore())) {
             throw new CouldNotSaveException(__('Gift Message is not available'));
         }
         $this->giftMessageManager->setMessage($quote, 'quote', $giftMessage);
diff --git a/app/code/Magento/GiftMessage/Model/ItemRepository.php b/app/code/Magento/GiftMessage/Model/ItemRepository.php
index 16d442a769240fef8fb93ced6c29ea8fc479d022..d7220d2516f7a2b934d9365a83c481f13249b1c2 100644
--- a/app/code/Magento/GiftMessage/Model/ItemRepository.php
+++ b/app/code/Magento/GiftMessage/Model/ItemRepository.php
@@ -121,7 +121,7 @@ class ItemRepository implements \Magento\GiftMessage\Api\ItemRepositoryInterface
         if ($item->getIsVirtual()) {
             throw new InvalidTransitionException(__('Gift Messages is not applicable for virtual products'));
         }
-        if (!$this->helper->getIsMessagesAvailable('items', $quote, $this->storeManager->getStore())) {
+        if (!$this->helper->isMessagesAllowed('items', $quote, $this->storeManager->getStore())) {
             throw new CouldNotSaveException(__('Gift Message is not available'));
         }
         $this->giftMessageManager->setMessage($quote, 'quote_item', $giftMessage, $itemId);
diff --git a/app/code/Magento/GiftMessage/Model/Observer.php b/app/code/Magento/GiftMessage/Model/Observer.php
index 696b4f38f5f6ae96d869838106d96d524bafeb81..342bc8cb133106011900935328a3d356036a47c4 100644
--- a/app/code/Magento/GiftMessage/Model/Observer.php
+++ b/app/code/Magento/GiftMessage/Model/Observer.php
@@ -74,7 +74,7 @@ class Observer extends \Magento\Framework\Object
             return $this;
         }
 
-        if (!$this->_giftMessageMessage->isMessagesAvailable('order', $order, $order->getStore())) {
+        if (!$this->_giftMessageMessage->isMessagesAllowed('order', $order, $order->getStore())) {
             return $this;
         }
         $giftMessageId = $order->getGiftMessageId();
@@ -102,7 +102,7 @@ class Observer extends \Magento\Framework\Object
             return $this;
         }
 
-        $isAvailable = $this->_giftMessageMessage->isMessagesAvailable(
+        $isAvailable = $this->_giftMessageMessage->isMessagesAllowed(
             'order_item',
             $orderItem,
             $orderItem->getStoreId()
diff --git a/app/code/Magento/GiftMessage/Model/OrderItemRepository.php b/app/code/Magento/GiftMessage/Model/OrderItemRepository.php
new file mode 100644
index 0000000000000000000000000000000000000000..4c71f599f0b1fe88dba1c1a4948c1b7db8db07a4
--- /dev/null
+++ b/app/code/Magento/GiftMessage/Model/OrderItemRepository.php
@@ -0,0 +1,155 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\GiftMessage\Model;
+
+use Magento\Framework\Exception\CouldNotSaveException;
+use Magento\Framework\Exception\NoSuchEntityException;
+use Magento\Framework\Exception\State\InvalidTransitionException;
+
+/**
+ * Order item gift message repository object.
+ */
+class OrderItemRepository implements \Magento\GiftMessage\Api\OrderItemRepositoryInterface
+{
+    /**
+     * Order factory.
+     *
+     * @var \Magento\Sales\Model\OrderFactory
+     */
+    protected $orderFactory;
+
+    /**
+     * Store manager interface.
+     *
+     * @var \Magento\Store\Model\StoreManagerInterface
+     */
+    protected $storeManager;
+
+    /**
+     * Gift message save model.
+     *
+     * @var \Magento\GiftMessage\Model\Save
+     */
+    protected $giftMessageSaveModel;
+
+    /**
+     * Message helper.
+     *
+     * @var \Magento\GiftMessage\Helper\Message
+     */
+    protected $helper;
+
+    /**
+     * Message factory.
+     *
+     * @var \Magento\GiftMessage\Model\MessageFactory
+     */
+    protected $messageFactory;
+
+    /**
+     * @param \Magento\Sales\Model\OrderFactory $orderFactory
+     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
+     * @param \Magento\GiftMessage\Model\Save $giftMessageSaveModel
+     * @param \Magento\GiftMessage\Helper\Message $helper
+     * @param MessageFactory $messageFactory
+     */
+    public function __construct(
+        \Magento\Sales\Model\OrderFactory $orderFactory,
+        \Magento\Store\Model\StoreManagerInterface $storeManager,
+        \Magento\GiftMessage\Model\Save $giftMessageSaveModel,
+        \Magento\GiftMessage\Helper\Message $helper,
+        \Magento\GiftMessage\Model\MessageFactory $messageFactory
+    ) {
+        $this->orderFactory = $orderFactory;
+        $this->giftMessageSaveModel = $giftMessageSaveModel;
+        $this->storeManager = $storeManager;
+        $this->helper = $helper;
+        $this->messageFactory = $messageFactory;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function get($orderId, $orderItemId)
+    {
+        /** @var \Magento\Sales\Api\Data\OrderItemInterface $orderItem */
+        if (!$orderItem = $this->getItemById($orderId, $orderItemId)) {
+            throw new NoSuchEntityException(__('There is no item with provided id in the order'));
+        };
+
+        if (!$this->helper->isMessagesAllowed('order_item', $orderItem, $this->storeManager->getStore())) {
+            throw new NoSuchEntityException(
+                __('There is no item with provided id in the order or gift message isn\'t allowed')
+            );
+        }
+
+        $messageId = $orderItem->getGiftMessageId();
+        if (!$messageId) {
+            throw new NoSuchEntityException(__('There is no item with provided id in the order'));
+        }
+
+        return $this->messageFactory->create()->load($messageId);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function save($orderId, $orderItemId, \Magento\GiftMessage\Api\Data\MessageInterface $giftMessage)
+    {
+        /** @var \Magento\Sales\Api\Data\OrderInterface $order */
+        $order = $this->orderFactory->create()->load($orderId);
+
+        /** @var \Magento\Sales\Api\Data\OrderItemInterface $orderItem */
+        if (!$orderItem = $this->getItemById($orderId, $orderItemId)) {
+            throw new NoSuchEntityException(__('There is no item with provided id in the order'));
+        };
+
+        if ($order->getIsVirtual()) {
+            throw new InvalidTransitionException(__('Gift Messages is not applicable for virtual products'));
+        }
+        if (!$this->helper->isMessagesAllowed('order_item', $orderItem, $this->storeManager->getStore())) {
+            throw new CouldNotSaveException(__('Gift Message is not available'));
+        }
+
+        $message = [];
+        $message[$orderItemId] = [
+            'type' => 'order_item',
+            'sender' => $giftMessage->getSender(),
+            'recipient' => $giftMessage->getRecipient(),
+            'message' => $giftMessage->getMessage(),
+        ];
+
+        $this->giftMessageSaveModel->setGiftmessages($message);
+        try {
+            $this->giftMessageSaveModel->saveAllInOrder();
+        } catch (\Exception $e) {
+            throw new CouldNotSaveException(__('Could not add gift message to order: "%1"', $e->getMessage()), $e);
+        }
+        return true;
+    }
+
+    /**
+     * Get order item by id
+     *
+     * @param int $orderId
+     * @param int $orderItemId
+     * @return \Magento\Sales\Api\Data\OrderItemInterface|bool
+     */
+    protected function getItemById($orderId, $orderItemId)
+    {
+        /** @var \Magento\Sales\Api\Data\OrderInterface $order */
+        $order = $this->orderFactory->create()->load($orderId);
+        /** @var \Magento\Sales\Api\Data\OrderItemInterface $item */
+        foreach ($order->getItems() as $item) {
+            if ($item->getItemId() === $orderItemId) {
+                return $item;
+            }
+        }
+        return false;
+    }
+}
diff --git a/app/code/Magento/GiftMessage/Model/OrderRepository.php b/app/code/Magento/GiftMessage/Model/OrderRepository.php
new file mode 100644
index 0000000000000000000000000000000000000000..5bbff94c44bf9cb0d26b84683964dfc051ed1a17
--- /dev/null
+++ b/app/code/Magento/GiftMessage/Model/OrderRepository.php
@@ -0,0 +1,137 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\GiftMessage\Model;
+
+use Magento\Framework\Exception\CouldNotSaveException;
+use Magento\Framework\Exception\InputException;
+use Magento\Framework\Exception\State\InvalidTransitionException;
+use Magento\Framework\Exception\NoSuchEntityException;
+
+/**
+ * Order gift message repository object.
+ */
+class OrderRepository implements \Magento\GiftMessage\Api\OrderRepositoryInterface
+{
+    /**
+     * Order factory.
+     *
+     * @var \Magento\Sales\Model\OrderFactory
+     */
+    protected $orderFactory;
+
+    /**
+     * Store manager interface.
+     *
+     * @var \Magento\Store\Model\StoreManagerInterface
+     */
+    protected $storeManager;
+
+    /**
+     * Gift message save model.
+     *
+     * @var \Magento\GiftMessage\Model\Save
+     */
+    protected $giftMessageSaveModel;
+
+    /**
+     * Message helper.
+     *
+     * @var \Magento\GiftMessage\Helper\Message
+     */
+    protected $helper;
+
+    /**
+     * Message factory.
+     *
+     * @var \Magento\GiftMessage\Model\MessageFactory
+     */
+    protected $messageFactory;
+
+    /**
+     * @param \Magento\Sales\Model\OrderFactory $orderFactory
+     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
+     * @param \Magento\GiftMessage\Model\Save $giftMessageSaveModel
+     * @param \Magento\GiftMessage\Helper\Message $helper
+     * @param MessageFactory $messageFactory
+     */
+    public function __construct(
+        \Magento\Sales\Model\OrderFactory $orderFactory,
+        \Magento\Store\Model\StoreManagerInterface $storeManager,
+        \Magento\GiftMessage\Model\Save $giftMessageSaveModel,
+        \Magento\GiftMessage\Helper\Message $helper,
+        \Magento\GiftMessage\Model\MessageFactory $messageFactory
+    ) {
+        $this->orderFactory = $orderFactory;
+        $this->giftMessageSaveModel = $giftMessageSaveModel;
+        $this->storeManager = $storeManager;
+        $this->helper = $helper;
+        $this->messageFactory = $messageFactory;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function get($orderId)
+    {
+        /** @var \Magento\Sales\Api\Data\OrderInterface $order */
+        $order = $this->orderFactory->create()->load($orderId);
+
+        if (!$this->helper->isMessagesAllowed('order', $order, $this->storeManager->getStore())) {
+            throw new NoSuchEntityException(
+                __('There is no order with provided id or gift message isn\'t allowed')
+            );
+        }
+
+        $messageId = $order->getGiftMessageId();
+        if (!$messageId) {
+            throw new NoSuchEntityException(__('There is no item with provided id in the order'));
+        }
+
+        return $this->messageFactory->create()->load($messageId);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function save($orderId, \Magento\GiftMessage\Api\Data\MessageInterface $giftMessage)
+    {
+        /** @var \Magento\Sales\Api\Data\OrderInterface $order */
+        $order = $this->orderFactory->create()->load($orderId);
+        if (!$order->getEntityId()) {
+            throw new NoSuchEntityException(__('There is no order with provided id'));
+        };
+
+        if (0 == $order->getTotalItemCount()) {
+            throw new InputException(__('Gift Messages is not applicable for empty order'));
+        }
+
+        if ($order->getIsVirtual()) {
+            throw new InvalidTransitionException(__('Gift Messages is not applicable for virtual products'));
+        }
+        if (!$this->helper->isMessagesAllowed('order', $order, $this->storeManager->getStore())) {
+            throw new CouldNotSaveException(__('Gift Message is not available'));
+        }
+
+        $message = [];
+        $message[$orderId] = [
+            'type' => 'order',
+            $giftMessage::CUSTOMER_ID => $giftMessage->getCustomerId(),
+            $giftMessage::SENDER => $giftMessage->getSender(),
+            $giftMessage::RECIPIENT => $giftMessage->getRecipient(),
+            $giftMessage::MESSAGE => $giftMessage->getMessage(),
+        ];
+
+        $this->giftMessageSaveModel->setGiftmessages($message);
+        try {
+            $this->giftMessageSaveModel->saveAllInOrder();
+        } catch (\Exception $e) {
+            throw new CouldNotSaveException(__('Could not add gift message to order: "%1"', $e->getMessage()), $e);
+        }
+        return true;
+    }
+}
diff --git a/app/code/Magento/GiftMessage/Model/Plugin/OrderGet.php b/app/code/Magento/GiftMessage/Model/Plugin/OrderGet.php
new file mode 100644
index 0000000000000000000000000000000000000000..c63a726d8e8449e3ebe709aac5828803a12961de
--- /dev/null
+++ b/app/code/Magento/GiftMessage/Model/Plugin/OrderGet.php
@@ -0,0 +1,129 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\GiftMessage\Model\Plugin;
+
+use Magento\Framework\Exception\NoSuchEntityException;
+
+class OrderGet
+{
+    /** @var \Magento\GiftMessage\Api\OrderRepositoryInterface */
+    protected $giftMessageOrderRepository;
+
+    /** @var \Magento\GiftMessage\Api\OrderItemRepositoryInterface */
+    protected $giftMessageOrderItemRepository;
+
+    /** @var \Magento\Sales\Api\Data\OrderExtensionFactory */
+    protected $orderExtensionFactory;
+
+    /** @var \Magento\Sales\Api\Data\OrderItemExtensionFactory */
+    protected $orderItemExtensionFactory;
+
+    /**
+     * Init plugin
+     *
+     * @param \Magento\GiftMessage\Api\OrderRepositoryInterface $giftMessageOrderRepository
+     * @param \Magento\GiftMessage\Api\OrderItemRepositoryInterface $giftMessageOrderItemRepository
+     * @param \Magento\Sales\Api\Data\OrderExtensionFactory $orderExtensionFactory
+     * @param \Magento\Sales\Api\Data\OrderItemExtensionFactory $orderItemExtensionFactory
+     */
+    public function __construct(
+        \Magento\GiftMessage\Api\OrderRepositoryInterface $giftMessageOrderRepository,
+        \Magento\GiftMessage\Api\OrderItemRepositoryInterface $giftMessageOrderItemRepository,
+        \Magento\Sales\Api\Data\OrderExtensionFactory $orderExtensionFactory,
+        \Magento\Sales\Api\Data\OrderItemExtensionFactory $orderItemExtensionFactory
+    ) {
+        $this->giftMessageOrderRepository = $giftMessageOrderRepository;
+        $this->giftMessageOrderItemRepository = $giftMessageOrderItemRepository;
+        $this->orderExtensionFactory = $orderExtensionFactory;
+        $this->orderItemExtensionFactory = $orderItemExtensionFactory;
+    }
+
+    /**
+     * Get gift message
+     *
+     * @param \Magento\Sales\Api\OrderRepositoryInterface $subject
+     * @param callable $proceed
+     * @param int $orderId
+     * @return \Magento\Sales\Api\Data\OrderInterface
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function aroundGet(
+        \Magento\Sales\Api\OrderRepositoryInterface $subject,
+        \Closure $proceed,
+        $orderId
+    ) {
+        /** @var \Magento\Sales\Api\Data\OrderInterface $resultOrder */
+        $resultOrder = $proceed($orderId);
+
+        $resultOrder = $this->getOrderGiftMessage($resultOrder);
+        $resultOrder = $this->getOrderItemGiftMessage($resultOrder);
+
+        return $resultOrder;
+    }
+
+    /**
+     * Get gift message for order
+     *
+     * @param \Magento\Sales\Api\Data\OrderInterface $order
+     * @return \Magento\Sales\Api\Data\OrderInterface
+     */
+    protected function getOrderGiftMessage(\Magento\Sales\Api\Data\OrderInterface $order)
+    {
+        if ($order->getExtensionAttributes() && $order->getExtensionAttributes()->getGiftMessage()) {
+            return $order;
+        }
+
+        try {
+            /** @var \Magento\GiftMessage\Api\Data\MessageInterface $giftMessage */
+            $giftMessage = $this->giftMessageOrderRepository->get($order->getEntityId());
+        } catch (NoSuchEntityException $e) {
+            return $order;
+        }
+
+        /** @var \Magento\Sales\Api\Data\OrderExtension $orderExtension */
+        $orderExtension = $this->orderExtensionFactory->create();
+        $orderExtension->setGiftMessage($giftMessage);
+        $order->setExtensionAttributes($orderExtension);
+
+        return $order;
+    }
+
+    /**
+     * Get gift message for items of order
+     *
+     * @param \Magento\Sales\Api\Data\OrderInterface $order
+     * @return \Magento\Sales\Api\Data\OrderInterface
+     */
+    protected function getOrderItemGiftMessage(\Magento\Sales\Api\Data\OrderInterface $order)
+    {
+        if (null !== $order->getItems()) {
+            /** @var \Magento\Sales\Api\Data\OrderItemInterface $orderItem */
+            foreach ($order->getItems() as $orderItem) {
+                if ($orderItem->getExtensionAttributes() && $orderItem->getExtensionAttributes()->getGiftMessage()) {
+                    continue;
+                }
+
+                try {
+                    /* @var \Magento\GiftMessage\Api\Data\MessageInterface $giftMessage */
+                    $giftMessage = $this->giftMessageOrderItemRepository->get(
+                        $order->getEntityId(),
+                        $orderItem->getItemId()
+                    );
+                } catch (NoSuchEntityException $e) {
+                    continue;
+                }
+
+                /** @var \Magento\Sales\Api\Data\OrderItemExtension $orderItemExtension */
+                $orderItemExtension = $this->orderItemExtensionFactory->create();
+                $orderItemExtension->setGiftMessage($giftMessage);
+                $orderItem->setExtensionAttributes($orderItemExtension);
+            }
+        }
+        return $order;
+    }
+}
diff --git a/app/code/Magento/GiftMessage/Model/Plugin/OrderSave.php b/app/code/Magento/GiftMessage/Model/Plugin/OrderSave.php
new file mode 100644
index 0000000000000000000000000000000000000000..8acac4ecd67e230d8e0dc7c75ff7e0daee0301d9
--- /dev/null
+++ b/app/code/Magento/GiftMessage/Model/Plugin/OrderSave.php
@@ -0,0 +1,118 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\GiftMessage\Model\Plugin;
+
+use Magento\Framework\Exception\CouldNotSaveException;
+
+class OrderSave
+{
+    /** @var \Magento\GiftMessage\Api\OrderRepositoryInterface */
+    protected $giftMessageOrderRepository;
+
+    /** @var \Magento\GiftMessage\Api\OrderItemRepositoryInterface */
+    protected $giftMessageOrderItemRepository;
+
+    /**
+     * Init plugin
+     *
+     * @param \Magento\GiftMessage\Api\OrderRepositoryInterface $giftMessageOrderRepository
+     * @param \Magento\GiftMessage\Api\OrderItemRepositoryInterface $giftMessageOrderItemRepository
+     */
+    public function __construct(
+        \Magento\GiftMessage\Api\OrderRepositoryInterface $giftMessageOrderRepository,
+        \Magento\GiftMessage\Api\OrderItemRepositoryInterface $giftMessageOrderItemRepository
+    ) {
+        $this->giftMessageOrderRepository = $giftMessageOrderRepository;
+        $this->giftMessageOrderItemRepository = $giftMessageOrderItemRepository;
+    }
+
+    /**
+     * Save gift message
+     *
+     * @param \Magento\Sales\Api\OrderRepositoryInterface $subject
+     * @param callable $proceed
+     * @param \Magento\Sales\Api\Data\OrderInterface $order
+     * @return \Magento\Sales\Api\Data\OrderInterface
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function aroundSave(
+        \Magento\Sales\Api\OrderRepositoryInterface $subject,
+        \Closure $proceed,
+        \Magento\Sales\Api\Data\OrderInterface $order
+    ) {
+        /** @var \Magento\Sales\Api\Data\OrderInterface $resultOrder */
+        $resultOrder = $proceed($order);
+        $resultOrder = $this->saveOrderGiftMessage($resultOrder);
+        $resultOrder = $this->saveOrderItemGiftMessage($resultOrder);
+
+        return $resultOrder;
+    }
+
+    /**
+     * Save gift message for order
+     *
+     * @param \Magento\Sales\Api\Data\OrderInterface $order
+     * @return \Magento\Sales\Api\Data\OrderInterface
+     */
+    protected function saveOrderGiftMessage(\Magento\Sales\Api\Data\OrderInterface $order)
+    {
+        if (
+            null !== $order->getExtensionAttributes() &&
+            null !== $order->getExtensionAttributes()->getGiftMessage()
+        ) {
+            /* @var \Magento\GiftMessage\Api\Data\MessageInterface $giftMessage */
+            $giftMessage = $order->getExtensionAttributes()->getGiftMessage();
+            if (null !== $giftMessage) {
+                try {
+                    $this->giftMessageOrderRepository->save($order->getEntityId(), $giftMessage);
+                } catch (\Exception $e) {
+                    throw new CouldNotSaveException(
+                        __('Could not add gift message to order: "%1"', $e->getMessage()),
+                        $e
+                    );
+                }
+            }
+        }
+        return $order;
+    }
+
+    /**
+     * Save gift message for items of order
+     *
+     * @param \Magento\Sales\Api\Data\OrderInterface $order
+     * @return \Magento\Sales\Api\Data\OrderInterface
+     */
+    protected function saveOrderItemGiftMessage(\Magento\Sales\Api\Data\OrderInterface $order)
+    {
+        if (null !== $order->getItems()) {
+            /** @var \Magento\Sales\Api\Data\OrderItemInterface $orderItem */
+            foreach ($order->getItems() as $orderItem) {
+                if (
+                    null !== $orderItem->getExtensionAttributes() &&
+                    null !== $orderItem->getExtensionAttributes()->getGiftMessage()
+                ) {
+                    /* @var \Magento\GiftMessage\Api\Data\MessageInterface $giftMessage */
+                    $giftMessage = $orderItem->getExtensionAttributes()->getGiftMessage();
+                    try {
+                        $this->giftMessageOrderItemRepository->save(
+                            $order->getEntityId(),
+                            $orderItem->getItemId(),
+                            $giftMessage
+                        );
+                    } catch (\Exception $e) {
+                        throw new CouldNotSaveException(
+                            __('Could not add gift message to order\'s item: "%1"', $e->getMessage()),
+                            $e
+                        );
+                    }
+                }
+            }
+        }
+        return $order;
+    }
+}
diff --git a/app/code/Magento/GiftMessage/Model/Plugin/QuoteItem.php b/app/code/Magento/GiftMessage/Model/Plugin/QuoteItem.php
index f2538b84b6a2353b25108cb1ad2162ad0784519e..9889f7261d2310678930b16aced1e23bec09d08b 100644
--- a/app/code/Magento/GiftMessage/Model/Plugin/QuoteItem.php
+++ b/app/code/Magento/GiftMessage/Model/Plugin/QuoteItem.php
@@ -39,7 +39,7 @@ class QuoteItem
     ) {
         /** @var $orderItem Item */
         $orderItem = $proceed($item, $additional);
-        $isAvailable = $this->_helper->isMessagesAvailable('item', $item, $item->getStoreId());
+        $isAvailable = $this->_helper->isMessagesAllowed('item', $item, $item->getStoreId());
 
         $orderItem->setGiftMessageId($item->getGiftMessageId());
         $orderItem->setGiftMessageAvailable($isAvailable);
diff --git a/app/code/Magento/GiftMessage/Model/Save.php b/app/code/Magento/GiftMessage/Model/Save.php
index 131624415b58208aa61e1fce40f4e8e69cba396f..7841e2f37867c7395203ef3ec4d90f273a79e6b2 100644
--- a/app/code/Magento/GiftMessage/Model/Save.php
+++ b/app/code/Magento/GiftMessage/Model/Save.php
@@ -265,7 +265,7 @@ class Save extends \Magento\Framework\Object
      */
     public function isGiftMessagesAvailable($item)
     {
-        return $this->_giftMessageMessage->getIsMessagesAvailable('item', $item, $item->getStore());
+        return $this->_giftMessageMessage->isMessagesAllowed('item', $item, $item->getStore());
     }
 
     /**
diff --git a/app/code/Magento/GiftMessage/Test/Unit/Helper/MessageTest.php b/app/code/Magento/GiftMessage/Test/Unit/Helper/MessageTest.php
index 3821d4f05b760a9dc1d6542e08fbcdd10c4a9451..9b1748b1052c1a4cfbdcfb8dad31d19e62a3b78a 100644
--- a/app/code/Magento/GiftMessage/Test/Unit/Helper/MessageTest.php
+++ b/app/code/Magento/GiftMessage/Test/Unit/Helper/MessageTest.php
@@ -29,7 +29,7 @@ class MessageTest extends \PHPUnit_Framework_TestCase
     }
 
     /**
-     * Make sure that isMessagesAvailable is not called
+     * Make sure that isMessagesAllowed is not called
      */
     public function testGetInlineForCheckout()
     {
diff --git a/app/code/Magento/GiftMessage/Test/Unit/Model/CartRepositoryTest.php b/app/code/Magento/GiftMessage/Test/Unit/Model/CartRepositoryTest.php
index c510e993f35c3355f96eda09fa189a6fb5e56924..6974c1f131cda2f511408dde59205c496619a7a1 100644
--- a/app/code/Magento/GiftMessage/Test/Unit/Model/CartRepositoryTest.php
+++ b/app/code/Magento/GiftMessage/Test/Unit/Model/CartRepositoryTest.php
@@ -163,7 +163,6 @@ class CartRepositoryTest extends \PHPUnit_Framework_TestCase
     {
         $this->quoteMock->expects($this->once())->method('getItemsCount')->will($this->returnValue(1));
         $this->quoteMock->expects($this->once())->method('isVirtual')->will($this->returnValue(true));
-
         $this->cartRepository->save($this->cartId, $this->messageMock);
     }
 
@@ -173,7 +172,7 @@ class CartRepositoryTest extends \PHPUnit_Framework_TestCase
         $this->quoteMock->expects($this->once())->method('getItemsCount')->will($this->returnValue(1));
         $this->storeManagerMock->expects($this->once())->method('getStore')->will($this->returnValue($this->storeMock));
         $this->helperMock->expects($this->once())
-            ->method('getIsMessagesAvailable')
+            ->method('isMessagesAllowed')
             ->with('quote', $this->quoteMock, $this->storeMock)
             ->will($this->returnValue(true));
         $this->giftMessageManagerMock->expects($this->once())
diff --git a/app/code/Magento/GiftMessage/Test/Unit/Model/ItemRepositoryTest.php b/app/code/Magento/GiftMessage/Test/Unit/Model/ItemRepositoryTest.php
index a97f5f9bd380007f3a0e238a3d940cf1c30ba2d5..5caa71f1b2bd2a492dc92b99c63c92970169d1bf 100644
--- a/app/code/Magento/GiftMessage/Test/Unit/Model/ItemRepositoryTest.php
+++ b/app/code/Magento/GiftMessage/Test/Unit/Model/ItemRepositoryTest.php
@@ -211,7 +211,7 @@ class ItemRepositoryTest extends \PHPUnit_Framework_TestCase
         $quoteItem->expects($this->once())->method('getIsVirtual')->will($this->returnValue(0));
         $this->storeManagerMock->expects($this->once())->method('getStore')->will($this->returnValue($this->storeMock));
         $this->helperMock->expects($this->once())
-            ->method('getIsMessagesAvailable')
+            ->method('isMessagesAllowed')
             ->with('items', $this->quoteMock, $this->storeMock)
             ->will($this->returnValue(true));
         $this->giftMessageManagerMock->expects($this->once())
diff --git a/app/code/Magento/GiftMessage/Test/Unit/Model/Plugin/QuoteItemTest.php b/app/code/Magento/GiftMessage/Test/Unit/Model/Plugin/QuoteItemTest.php
index 61afb0c179fc69e84d8b16316dbd57ff5982a23d..b748345a177d1cf92bf81258c5b0c5bebdb1f329 100644
--- a/app/code/Magento/GiftMessage/Test/Unit/Model/Plugin/QuoteItemTest.php
+++ b/app/code/Magento/GiftMessage/Test/Unit/Model/Plugin/QuoteItemTest.php
@@ -60,7 +60,7 @@ class QuoteItemTest extends \PHPUnit_Framework_TestCase
         $this->subjectMock = $this->getMock('Magento\Quote\Model\Quote\Item\ToOrderItem', [], [], '', false);
         $this->helperMock = $this->getMock(
             'Magento\GiftMessage\Helper\Message',
-            ['setGiftMessageId', 'isMessagesAvailable'],
+            ['setGiftMessageId', 'isMessagesAllowed'],
             [],
             '',
             false
@@ -86,7 +86,7 @@ class QuoteItemTest extends \PHPUnit_Framework_TestCase
         $this->helperMock->expects(
             $this->once()
         )->method(
-            'isMessagesAvailable'
+            'isMessagesAllowed'
         )->with(
             'item',
             $this->quoteItemMock,
diff --git a/app/code/Magento/GiftMessage/composer.json b/app/code/Magento/GiftMessage/composer.json
index a63693d4131512cdb0481b073b7d0f1184852a2d..32828754a4c6050ddcb32c41fa72777194e61729 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-beta1",
-        "magento/module-catalog": "0.74.0-beta1",
-        "magento/module-checkout": "0.74.0-beta1",
-        "magento/module-multishipping": "0.74.0-beta1",
-        "magento/module-sales": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-customer": "0.74.0-beta1",
-        "magento/module-eav": "0.74.0-beta1",
-        "magento/module-quote": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/module-checkout": "0.74.0-beta2",
+        "magento/module-multishipping": "0.74.0-beta2",
+        "magento/module-sales": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-customer": "0.74.0-beta2",
+        "magento/module-eav": "0.74.0-beta2",
+        "magento/module-quote": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/GiftMessage/etc/adminhtml/di.xml b/app/code/Magento/GiftMessage/etc/adminhtml/di.xml
deleted file mode 100644
index 961c8c6ff61369d74a53d6a9a943c067933e6345..0000000000000000000000000000000000000000
--- a/app/code/Magento/GiftMessage/etc/adminhtml/di.xml
+++ /dev/null
@@ -1,13 +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/ObjectManager/etc/config.xsd">
-    <type name="Magento\GiftMessage\Model\Plugin\QuoteItem" shared="false" />
-    <type name="Magento\Quote\Model\Quote\Item\ToOrderItem">
-        <plugin name="gift_message_quote_item_conversion" type="Magento\GiftMessage\Model\Plugin\QuoteItem"/>
-    </type>
-</config>
diff --git a/app/code/Magento/GiftMessage/etc/data_object.xml b/app/code/Magento/GiftMessage/etc/data_object.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a1255cc8a161a5a8d28090697088a87ede8920e7
--- /dev/null
+++ b/app/code/Magento/GiftMessage/etc/data_object.xml
@@ -0,0 +1,15 @@
+<?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\Sales\Api\Data\OrderInterface">
+        <attribute code="gift_message" type="Magento\GiftMessage\Api\Data\MessageInterface" />
+    </custom_attributes>
+    <custom_attributes for="Magento\Sales\Api\Data\OrderItemInterface">
+        <attribute code="gift_message" type="Magento\GiftMessage\Api\Data\MessageInterface" />
+    </custom_attributes>
+</config>
diff --git a/app/code/Magento/GiftMessage/etc/di.xml b/app/code/Magento/GiftMessage/etc/di.xml
index 2c674334652effc113de85057424dc8be4f74d73..d8ea087e62d735c09063af6d8f3cf518179df33f 100644
--- a/app/code/Magento/GiftMessage/etc/di.xml
+++ b/app/code/Magento/GiftMessage/etc/di.xml
@@ -15,5 +15,15 @@
     </type>
     <preference for="Magento\GiftMessage\Api\CartRepositoryInterface" type="Magento\GiftMessage\Model\CartRepository"/>
     <preference for="Magento\GiftMessage\Api\ItemRepositoryInterface" type="Magento\GiftMessage\Model\ItemRepository"/>
+    <preference for="Magento\GiftMessage\Api\OrderRepositoryInterface" type="Magento\GiftMessage\Model\OrderRepository"/>
+    <preference for="Magento\GiftMessage\Api\OrderItemRepositoryInterface" type="Magento\GiftMessage\Model\OrderItemRepository"/>
     <preference for="Magento\GiftMessage\Api\Data\MessageInterface" type="Magento\GiftMessage\Model\Message"/>
+    <type name="Magento\GiftMessage\Model\Plugin\QuoteItem" shared="false" />
+    <type name="Magento\Quote\Model\Quote\Item\ToOrderItem">
+        <plugin name="gift_message_quote_item_conversion" type="Magento\GiftMessage\Model\Plugin\QuoteItem"/>
+    </type>
+    <type name="Magento\Sales\Api\OrderRepositoryInterface">
+        <plugin name="save_gift_message" type="Magento\GiftMessage\Model\Plugin\OrderSave"/>
+        <plugin name="get_gift_message" type="Magento\GiftMessage\Model\Plugin\OrderGet"/>
+    </type>
 </config>
diff --git a/app/code/Magento/GoogleAdwords/composer.json b/app/code/Magento/GoogleAdwords/composer.json
index dfdd67b7d169a12dc7507775559a32d52819a135..5910e7b7bd1c3e6ecf4ede31914c3b0742d2c8b8 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-beta1",
-        "magento/module-sales": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-sales": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/GoogleAnalytics/composer.json b/app/code/Magento/GoogleAnalytics/composer.json
index 9b0de3cf5ba2cfde61f55022eedbba4bb6397f6a..3df1f85b5e00267b40039d4eea1a7420f8b1c032 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-beta1",
-        "magento/module-sales": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
-        "magento/module-cookie": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-sales": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
+        "magento/module-cookie": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/GoogleOptimizer/composer.json b/app/code/Magento/GoogleOptimizer/composer.json
index bf30fc297c18a97ac57c2195c922bef52b1834f7..7d9229a0ae1edfb7bb880df7b31bd5e20e13563f 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-beta1",
-        "magento/module-google-analytics": "0.74.0-beta1",
-        "magento/module-catalog": "0.74.0-beta1",
-        "magento/module-cms": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-google-analytics": "0.74.0-beta2",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/module-cms": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/GoogleShopping/composer.json b/app/code/Magento/GoogleShopping/composer.json
index 0e87a23f1e6c976f0621cf7680bb03ec2678829d..d1c57e9befe38f5d1d813b751043ebedd83cd8cf 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-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-catalog": "0.74.0-beta1",
-        "magento/module-customer": "0.74.0-beta1",
-        "magento/module-directory": "0.74.0-beta1",
-        "magento/module-eav": "0.74.0-beta1",
-        "magento/module-tax": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/module-customer": "0.74.0-beta2",
+        "magento/module-directory": "0.74.0-beta2",
+        "magento/module-eav": "0.74.0-beta2",
+        "magento/module-tax": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/GroupedImportExport/composer.json b/app/code/Magento/GroupedImportExport/composer.json
index 4d0479944ea3bc8b3b98cce893d5c3f725f66b1a..5a287d286f7f3ba465d0ff7b3192be469a41e2af 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-beta1",
-        "magento/module-import-export": "0.74.0-beta1",
-        "magento/module-catalog-import-export": "0.74.0-beta1",
-        "magento/module-grouped-product": "0.74.0-beta1",
-        "magento/module-eav": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/module-import-export": "0.74.0-beta2",
+        "magento/module-catalog-import-export": "0.74.0-beta2",
+        "magento/module-grouped-product": "0.74.0-beta2",
+        "magento/module-eav": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "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 76330dcbf1fccb1f3726318d772a279f93fcb51c..d856527779116c8c6795c79d704fc90a892bfcd2 100644
--- a/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php
+++ b/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php
@@ -326,6 +326,32 @@ class Grouped extends \Magento\Catalog\Model\Product\Type\AbstractType
         return $this;
     }
 
+    /**
+     * @param \Magento\Framework\Object $buyRequest
+     * @param \Magento\Catalog\Model\Product $product
+     * @param bool $isStrictProcessMode
+     * @return array|string
+     */
+    protected function getProductInfo(\Magento\Framework\Object $buyRequest, $product, $isStrictProcessMode)
+    {
+        $productsInfo = $buyRequest->getSuperGroup() ?: [];
+        $associatedProducts = $this->getAssociatedProducts($product);
+
+        if (!is_array($productsInfo)) {
+            return __('Please specify the quantity of product(s).')->render();
+        }
+        foreach ($associatedProducts as $subProduct) {
+            if (!isset($productsInfo[$subProduct->getId()])) {
+                if ($isStrictProcessMode && !$subProduct->getQty()) {
+                    return __('Please specify the quantity of product(s).')->render();
+                }
+                $productsInfo[$subProduct->getId()] = intval($subProduct->getQty());
+            }
+        }
+
+        return $productsInfo;
+    }
+
     /**
      * Prepare product and its configuration to be added to some products list.
      * Perform standard preparation process and add logic specific to Grouped product type.
@@ -335,70 +361,66 @@ class Grouped extends \Magento\Catalog\Model\Product\Type\AbstractType
      * @param string $processMode
      * @return \Magento\Framework\Phrase|array|string
      * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+     * @SuppressWarnings(PHPMD.NPathComplexity)
      */
     protected function _prepareProduct(\Magento\Framework\Object $buyRequest, $product, $processMode)
     {
-        $productsInfo = $buyRequest->getSuperGroup();
+        $products = [];
+        $associatedProductsInfo = [];
         $isStrictProcessMode = $this->_isStrictProcessMode($processMode);
-
-        if (!$isStrictProcessMode || !empty($productsInfo) && is_array($productsInfo)) {
-            $products = [];
-            $associatedProductsInfo = [];
-            $associatedProducts = $this->getAssociatedProducts($product);
-            if ($associatedProducts || !$isStrictProcessMode) {
-                foreach ($associatedProducts as $subProduct) {
-                    $subProductId = $subProduct->getId();
-                    if (isset($productsInfo[$subProductId])) {
-                        $qty = $productsInfo[$subProductId];
-                        if (!empty($qty) && is_numeric($qty)) {
-                            $_result = $subProduct->getTypeInstance()->_prepareProduct(
-                                $buyRequest,
-                                $subProduct,
-                                $processMode
-                            );
-                            if (is_string($_result) && !is_array($_result)) {
-                                return $_result;
-                            }
-
-                            if (!isset($_result[0])) {
-                                return __('We cannot process the item.')->render();
-                            }
-
-                            if ($isStrictProcessMode) {
-                                $_result[0]->setCartQty($qty);
-                                $_result[0]->addCustomOption(
-                                    'info_buyRequest',
-                                    serialize(
-                                        [
-                                            'super_product_config' => [
-                                                'product_type' => self::TYPE_CODE,
-                                                'product_id' => $product->getId(),
-                                            ],
-                                        ]
-                                    )
-                                );
-                                $products[] = $_result[0];
-                            } else {
-                                $associatedProductsInfo[] = [$subProductId => $qty];
-                                $product->addCustomOption('associated_product_' . $subProductId, $qty);
-                            }
-                        }
-                    }
-                }
+        $productsInfo = $this->getProductInfo($buyRequest, $product, $isStrictProcessMode);
+        if (is_string($productsInfo)) {
+            return $productsInfo;
+        }
+        $associatedProducts = !$isStrictProcessMode || !empty($productsInfo)
+            ? $this->getAssociatedProducts($product)
+            : false;
+
+        foreach ($associatedProducts as $subProduct) {
+            $qty = $productsInfo[$subProduct->getId()];
+            if (!is_numeric($qty)) {
+                continue;
             }
 
-            if (!$isStrictProcessMode || count($associatedProductsInfo)) {
-                $product->addCustomOption('product_type', self::TYPE_CODE, $product);
-                $product->addCustomOption('info_buyRequest', serialize($buyRequest->getData()));
+            $_result = $subProduct->getTypeInstance()->_prepareProduct($buyRequest, $subProduct, $processMode);
 
-                $products[] = $product;
+            if (is_string($_result)) {
+                return $_result;
+            } elseif (!isset($_result[0])) {
+                return __('Cannot process the item.')->render();
             }
 
-            if (count($products)) {
-                return $products;
+            if ($isStrictProcessMode) {
+                $_result[0]->setCartQty($qty);
+                $_result[0]->addCustomOption(
+                    'info_buyRequest',
+                    serialize(
+                        [
+                            'super_product_config' => [
+                                'product_type' => self::TYPE_CODE,
+                                'product_id' => $product->getId(),
+                            ],
+                        ]
+                    )
+                );
+                $products[] = $_result[0];
+            } else {
+                $associatedProductsInfo[] = [$subProduct->getId() => $qty];
+                $product->addCustomOption('associated_product_' . $subProduct->getId(), $qty);
             }
         }
 
+        if (!$isStrictProcessMode || count($associatedProductsInfo)) {
+            $product->addCustomOption('product_type', self::TYPE_CODE, $product);
+            $product->addCustomOption('info_buyRequest', serialize($buyRequest->getData()));
+
+            $products[] = $product;
+        }
+
+        if (count($products)) {
+            return $products;
+        }
+
         return __('Please specify the quantity of product(s).')->render();
     }
 
diff --git a/app/code/Magento/GroupedProduct/Test/Unit/Model/Product/Type/GroupedTest.php b/app/code/Magento/GroupedProduct/Test/Unit/Model/Product/Type/GroupedTest.php
index 077fa278da47bd96b50fe8dce163fc0315fbd355..4cf5af00c029444d88bda643c4f61d6a62a174f9 100644
--- a/app/code/Magento/GroupedProduct/Test/Unit/Model/Product/Type/GroupedTest.php
+++ b/app/code/Magento/GroupedProduct/Test/Unit/Model/Product/Type/GroupedTest.php
@@ -300,20 +300,82 @@ class GroupedTest extends \PHPUnit_Framework_TestCase
 
     public function testPrepareForCartAdvancedEmpty()
     {
+        $this->product = $this->getMock('Magento\Catalog\Model\Product', [], [], '', false);
         $buyRequest = new \Magento\Framework\Object();
         $expectedMsg = "Please specify the quantity of product(s).";
 
-        $this->assertEquals(
-            $expectedMsg,
-            $this->_model->prepareForCartAdvanced($buyRequest, $this->product)
+        $productCollection = $this->getMock(
+            'Magento\Catalog\Model\Resource\Product\Link\Product\Collection',
+            [],
+            [],
+            '',
+            false
         );
+        $productCollection
+            ->expects($this->atLeastOnce())
+            ->method('setFlag')
+            ->willReturnSelf();
+        $productCollection
+            ->expects($this->atLeastOnce())
+            ->method('setIsStrongMode')
+            ->willReturnSelf();
+        $productCollection
+            ->expects($this->atLeastOnce())
+            ->method('setProduct');
+        $productCollection
+            ->expects($this->atLeastOnce())
+            ->method('addAttributeToSelect')
+            ->willReturnSelf();
+        $productCollection
+            ->expects($this->atLeastOnce())
+            ->method('addFilterByRequiredOptions')
+            ->willReturnSelf();
+        $productCollection
+            ->expects($this->atLeastOnce())
+            ->method('setPositionOrder')
+            ->willReturnSelf();
+        $productCollection
+            ->expects($this->atLeastOnce())
+            ->method('addStoreFilter')
+            ->willReturnSelf();
+        $productCollection
+            ->expects($this->atLeastOnce())
+            ->method('addAttributeToFilter')
+            ->willReturnSelf();
+        $items = [
+            $this->getMock('Magento\Catalog\Model\Product', [], [], '', false),
+            $this->getMock('Magento\Catalog\Model\Product', [], [], '', false)
+        ];
+        $productCollection
+            ->expects($this->atLeastOnce())
+            ->method('getIterator')
+            ->willReturn(new \ArrayIterator($items));
+
+        $link = $this->getMock('Magento\Catalog\Model\Product\Link', [], [], '', false);
+        $link
+            ->expects($this->any())
+            ->method('setLinkTypeId');
+        $link
+            ->expects($this->atLeastOnce())
+            ->method('getProductCollection')
+            ->willReturn($productCollection);
+
+        $this->product
+            ->expects($this->atLeastOnce())
+            ->method('getLinkInstance')
+            ->willReturn($link);
+
+        $this->product
+            ->expects($this->any())
+            ->method('getData')
+            ->willReturn($items);
 
-        $buyRequest->setSuperGroup([]);
         $this->assertEquals(
             $expectedMsg,
             $this->_model->prepareForCartAdvanced($buyRequest, $this->product)
         );
 
+
         $buyRequest->setSuperGroup(1);
         $this->assertEquals(
             $expectedMsg,
@@ -329,8 +391,14 @@ class GroupedTest extends \PHPUnit_Framework_TestCase
 
         $cached = true;
         $associatedProducts = [];
-        $this->product->expects($this->once())->method('hasData')->will($this->returnValue($cached));
-        $this->product->expects($this->once())->method('getData')->will($this->returnValue($associatedProducts));
+        $this->product
+            ->expects($this->atLeastOnce())
+            ->method('hasData')
+            ->will($this->returnValue($cached));
+        $this->product
+            ->expects($this->atLeastOnce())
+            ->method('getData')
+            ->will($this->returnValue($associatedProducts));
 
         $this->assertEquals(
             $expectedMsg,
@@ -345,8 +413,14 @@ class GroupedTest extends \PHPUnit_Framework_TestCase
 
         $cached = true;
         $associatedProducts = [];
-        $this->product->expects($this->once())->method('hasData')->will($this->returnValue($cached));
-        $this->product->expects($this->once())->method('getData')->will($this->returnValue($associatedProducts));
+        $this->product
+            ->expects($this->atLeastOnce())
+            ->method('hasData')
+            ->will($this->returnValue($cached));
+        $this->product
+            ->expects($this->atLeastOnce())
+            ->method('getData')
+            ->will($this->returnValue($associatedProducts));
 
         $this->assertEquals(
             [0 => $this->product],
@@ -358,7 +432,7 @@ class GroupedTest extends \PHPUnit_Framework_TestCase
     {
         $associatedProduct = $this->getMock('Magento\Catalog\Model\Product', [], [], '', false);
         $associatedId = 9384;
-        $associatedProduct->expects($this->once())->method('getId')->will($this->returnValue($associatedId));
+        $associatedProduct->expects($this->atLeastOnce())->method('getId')->will($this->returnValue($associatedId));
 
         $typeMock = $this->getMock(
             'Magento\Catalog\Model\Product\Type\AbstractType',
@@ -376,8 +450,14 @@ class GroupedTest extends \PHPUnit_Framework_TestCase
         $buyRequest->setSuperGroup([$associatedId => 1]);
 
         $cached = true;
-        $this->product->expects($this->once())->method('hasData')->will($this->returnValue($cached));
-        $this->product->expects($this->once())->method('getData')->will($this->returnValue([$associatedProduct]));
+        $this->product
+            ->expects($this->atLeastOnce())
+            ->method('hasData')
+            ->will($this->returnValue($cached));
+        $this->product
+            ->expects($this->atLeastOnce())
+            ->method('getData')
+            ->will($this->returnValue([$associatedProduct]));
 
         $this->assertEquals(
             $associatedPrepareResult,
@@ -387,10 +467,10 @@ class GroupedTest extends \PHPUnit_Framework_TestCase
 
     public function testPrepareForCartAdvancedWithProductsStrictFalseEmptyArrayResult()
     {
-        $expectedMsg = "We cannot process the item.";
+        $expectedMsg = "Cannot process the item.";
         $associatedProduct = $this->getMock('Magento\Catalog\Model\Product', [], [], '', false);
         $associatedId = 9384;
-        $associatedProduct->expects($this->once())->method('getId')->will($this->returnValue($associatedId));
+        $associatedProduct->expects($this->atLeastOnce())->method('getId')->will($this->returnValue($associatedId));
 
         $typeMock = $this->getMock(
             'Magento\Catalog\Model\Product\Type\AbstractType',
@@ -408,8 +488,14 @@ class GroupedTest extends \PHPUnit_Framework_TestCase
         $buyRequest->setSuperGroup([$associatedId => 1]);
 
         $cached = true;
-        $this->product->expects($this->once())->method('hasData')->will($this->returnValue($cached));
-        $this->product->expects($this->once())->method('getData')->will($this->returnValue([$associatedProduct]));
+        $this->product->
+        expects($this->atLeastOnce())
+            ->method('hasData')
+            ->will($this->returnValue($cached));
+        $this->product->
+        expects($this->atLeastOnce())
+            ->method('getData')
+            ->will($this->returnValue([$associatedProduct]));
 
         $this->assertEquals(
             $expectedMsg,
@@ -421,7 +507,7 @@ class GroupedTest extends \PHPUnit_Framework_TestCase
     {
         $associatedProduct = $this->getMock('Magento\Catalog\Model\Product', [], [], '', false);
         $associatedId = 9384;
-        $associatedProduct->expects($this->once())->method('getId')->will($this->returnValue($associatedId));
+        $associatedProduct->expects($this->atLeastOnce())->method('getId')->will($this->returnValue($associatedId));
 
         $typeMock = $this->getMock(
             'Magento\Catalog\Model\Product\Type\AbstractType',
@@ -439,8 +525,14 @@ class GroupedTest extends \PHPUnit_Framework_TestCase
         $buyRequest->setSuperGroup([$associatedId => 1]);
 
         $cached = true;
-        $this->product->expects($this->once())->method('hasData')->will($this->returnValue($cached));
-        $this->product->expects($this->once())->method('getData')->will($this->returnValue([$associatedProduct]));
+        $this->product
+            ->expects($this->atLeastOnce())
+            ->method('hasData')
+            ->will($this->returnValue($cached));
+        $this->product
+            ->expects($this->atLeastOnce())
+            ->method('getData')
+            ->will($this->returnValue([$associatedProduct]));
 
         $this->assertEquals(
             [$this->product],
@@ -452,7 +544,7 @@ class GroupedTest extends \PHPUnit_Framework_TestCase
     {
         $associatedProduct = $this->getMock('Magento\Catalog\Model\Product', [], [], '', false);
         $associatedId = 9384;
-        $associatedProduct->expects($this->once())->method('getId')->will($this->returnValue($associatedId));
+        $associatedProduct->expects($this->atLeastOnce())->method('getId')->will($this->returnValue($associatedId));
 
         $typeMock = $this->getMock(
             'Magento\Catalog\Model\Product\Type\AbstractType',
@@ -470,8 +562,14 @@ class GroupedTest extends \PHPUnit_Framework_TestCase
         $buyRequest->setSuperGroup([$associatedId => 1]);
 
         $cached = true;
-        $this->product->expects($this->once())->method('hasData')->will($this->returnValue($cached));
-        $this->product->expects($this->once())->method('getData')->will($this->returnValue([$associatedProduct]));
+        $this->product
+            ->expects($this->atLeastOnce())
+            ->method('hasData')
+            ->will($this->returnValue($cached));
+        $this->product
+            ->expects($this->atLeastOnce())
+            ->method('getData')
+            ->will($this->returnValue([$associatedProduct]));
 
         $this->assertEquals(
             $associatedPrepareResult,
diff --git a/app/code/Magento/GroupedProduct/composer.json b/app/code/Magento/GroupedProduct/composer.json
index ccf2adcab0a397ae21a800994d374e0caa1805a9..7d0848de8487442f4374094c8f1166dfafcaee0b 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-beta1",
-        "magento/module-catalog": "0.74.0-beta1",
-        "magento/module-catalog-inventory": "0.74.0-beta1",
-        "magento/module-sales": "0.74.0-beta1",
-        "magento/module-checkout": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-eav": "0.74.0-beta1",
-        "magento/module-customer": "0.74.0-beta1",
-        "magento/module-media-storage": "0.74.0-beta1",
-        "magento/module-msrp": "0.74.0-beta1",
-        "magento/module-quote": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/module-catalog-inventory": "0.74.0-beta2",
+        "magento/module-sales": "0.74.0-beta2",
+        "magento/module-checkout": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-eav": "0.74.0-beta2",
+        "magento/module-customer": "0.74.0-beta2",
+        "magento/module-media-storage": "0.74.0-beta2",
+        "magento/module-msrp": "0.74.0-beta2",
+        "magento/module-quote": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/ImportExport/composer.json b/app/code/Magento/ImportExport/composer.json
index eaaecbe071b0fb5f992db1889de661bb60cb8f33..0babfceb059a23506fb519fbc4fe9d095221eb44 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-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-eav": "0.74.0-beta1",
-        "magento/module-indexer": "0.74.0-beta1",
-        "magento/module-media-storage": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-eav": "0.74.0-beta2",
+        "magento/module-indexer": "0.74.0-beta2",
+        "magento/module-media-storage": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "ext-ctype": "*",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Indexer/composer.json b/app/code/Magento/Indexer/composer.json
index 31d4298885d34cf0ae7bcd3225dd0ba71eb4c191..29b3528dad550e62e60d931a2166f146d100f54f 100644
--- a/app/code/Magento/Indexer/composer.json
+++ b/app/code/Magento/Indexer/composer.json
@@ -3,13 +3,13 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-page-cache": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-page-cache": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Integration/composer.json b/app/code/Magento/Integration/composer.json
index 3a163437da5817ff3ba602c11bb398364c030198..70db5bfe2d95a86570d9ab2039d1c91229373435 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-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-customer": "0.74.0-beta1",
-        "magento/module-user": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
-        "magento/module-authorization": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-customer": "0.74.0-beta2",
+        "magento/module-user": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
+        "magento/module-authorization": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/LayeredNavigation/composer.json b/app/code/Magento/LayeredNavigation/composer.json
index 6ce4ba9dde72193798efbb730fafc2208ad76889..d0f240acf188433f974962216238443f4075689c 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-beta1",
-        "magento/module-catalog": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-config": "0.74.0-beta2",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Log/composer.json b/app/code/Magento/Log/composer.json
index 889b0c8bc36410ab007e4de7dfe7f14f1540939e..55ef40e0c62e08b89a1ab092e266a95993e212bb 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-beta1",
-        "magento/module-customer": "0.74.0-beta1",
-        "magento/module-eav": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-customer": "0.74.0-beta2",
+        "magento/module-eav": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/MediaStorage/composer.json b/app/code/Magento/MediaStorage/composer.json
index 051e531f2c7bfcb7bd1aa1141477d66a09b1505c..bddfdffd918bdb3462c7f604fa558076879079d2 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-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-config": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-config": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Msrp/composer.json b/app/code/Magento/Msrp/composer.json
index 003e4b9a9910ef6eaf7b1aa0f40303fd0328e621..27b2fad7748b152f986ffee32f54ff46472aecbf 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-beta1",
-        "magento/module-bundle": "0.74.0-beta1",
-        "magento/module-catalog": "0.74.0-beta1",
-        "magento/module-downloadable": "0.74.0-beta1",
-        "magento/module-eav": "0.74.0-beta1",
-        "magento/module-grouped-product": "0.74.0-beta1",
-        "magento/module-tax": "0.74.0-beta1",
-        "magento/module-quote": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-bundle": "0.74.0-beta2",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/module-downloadable": "0.74.0-beta2",
+        "magento/module-eav": "0.74.0-beta2",
+        "magento/module-grouped-product": "0.74.0-beta2",
+        "magento/module-tax": "0.74.0-beta2",
+        "magento/module-quote": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Multishipping/composer.json b/app/code/Magento/Multishipping/composer.json
index 0f052635d1a77f4b7ebedeeee5290907881d2316..437f0d8c722e7021258e8e6e0b92a60266836cdc 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-beta1",
-        "magento/module-checkout": "0.74.0-beta1",
-        "magento/module-sales": "0.74.0-beta1",
-        "magento/module-payment": "0.74.0-beta1",
-        "magento/module-tax": "0.74.0-beta1",
-        "magento/module-customer": "0.74.0-beta1",
-        "magento/module-theme": "0.74.0-beta1",
-        "magento/module-quote": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-checkout": "0.74.0-beta2",
+        "magento/module-sales": "0.74.0-beta2",
+        "magento/module-payment": "0.74.0-beta2",
+        "magento/module-tax": "0.74.0-beta2",
+        "magento/module-customer": "0.74.0-beta2",
+        "magento/module-theme": "0.74.0-beta2",
+        "magento/module-quote": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Newsletter/composer.json b/app/code/Magento/Newsletter/composer.json
index a68b7906027c84a47ebd74e70f09f2613e4f7057..460524e9b3689cdb22c9d4215a5d2826b13de4e2 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-beta1",
-        "magento/module-customer": "0.74.0-beta1",
-        "magento/module-widget": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-cms": "0.74.0-beta1",
-        "magento/module-email": "0.74.0-beta1",
-        "magento/module-cron": "0.74.0-beta1",
-        "magento/module-eav": "0.74.0-beta1",
-        "magento/module-require-js": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-customer": "0.74.0-beta2",
+        "magento/module-widget": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-cms": "0.74.0-beta2",
+        "magento/module-email": "0.74.0-beta2",
+        "magento/module-cron": "0.74.0-beta2",
+        "magento/module-eav": "0.74.0-beta2",
+        "magento/module-require-js": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/OfflinePayments/composer.json b/app/code/Magento/OfflinePayments/composer.json
index d7df360aa89dfd2ca358ced5c1cb7da97a33c91b..11f6f88c5c9a6d2cacb80f4308e13a8fabb4007c 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-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-payment": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/OfflineShipping/composer.json b/app/code/Magento/OfflineShipping/composer.json
index 8e0d5b7c01e48d18bdaeffa50a0ae4d41a2101ce..53659003e0037b744fb74c281efde0dcb4d3e8da 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-beta1",
-        "magento/module-store": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-shipping": "0.74.0-beta1",
-        "magento/module-catalog": "0.74.0-beta1",
-        "magento/module-sales": "0.74.0-beta1",
-        "magento/module-sales-rule": "0.74.0-beta1",
-        "magento/module-directory": "0.74.0-beta1",
-        "magento/module-checkout": "0.74.0-beta1",
-        "magento/module-quote": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-config": "0.74.0-beta2",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-shipping": "0.74.0-beta2",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/module-sales": "0.74.0-beta2",
+        "magento/module-sales-rule": "0.74.0-beta2",
+        "magento/module-directory": "0.74.0-beta2",
+        "magento/module-checkout": "0.74.0-beta2",
+        "magento/module-quote": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/PageCache/composer.json b/app/code/Magento/PageCache/composer.json
index 7176399192439e013fc28d958b519948121c73d1..bf42a2eeb57e54ed7caabde4b982abcfbf91fc2b 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-beta1",
-        "magento/module-store": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-config": "0.74.0-beta2",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/PageCache/etc/varnish3.vcl b/app/code/Magento/PageCache/etc/varnish3.vcl
index 7fa9a30ec9ac5acdce849c445abfd8efa8cf496f..0b6651fbc0cd4d66748e7d68b683dc823ff574d2 100644
--- a/app/code/Magento/PageCache/etc/varnish3.vcl
+++ b/app/code/Magento/PageCache/etc/varnish3.vcl
@@ -54,7 +54,7 @@ sub vcl_recv {
     std.collect(req.http.Cookie);
 
     # static files are always cacheable. remove SSL flag and cookie
-    if (req.url ~ "^/(pub/)?(media|static)/.*\.(png|jpg|jpeg|gif|css|js|swf|ico|woff|svg)$") {
+    if (req.url ~ "^/(pub/)?(media|static)/.*\.(ico|css|js|jpg|jpeg|png|gif|tiff|bmp|gz|tgz|bz2|tbz|mp3|ogg|svg|swf|woff|woff2|eot|ttf|otf)$") {
         unset req.http.Https;
         unset req.http.Cookie;
     }
@@ -96,7 +96,7 @@ sub vcl_fetch {
     # images, css and js are cacheable by default so we have to remove cookie also
     if (beresp.ttl > 0s && (req.request == "GET" || req.request == "HEAD")) {
         unset beresp.http.set-cookie;
-        if (req.url !~ "\.(css|js|jpg|png|gif|tiff|bmp|gz|tgz|bz2|tbz|mp3|ogg|svg|swf|woff)(\?|$)") {
+            if (req.url !~ "\.(ico|css|js|jpg|jpeg|png|gif|tiff|bmp|mp3|ogg|svg|swf|woff|woff2|eot|ttf|otf)(\?|$)") {
             set beresp.http.Pragma = "no-cache";
             set beresp.http.Expires = "-1";
             set beresp.http.Cache-Control = "no-store, no-cache, must-revalidate, max-age=0";
diff --git a/app/code/Magento/PageCache/etc/varnish4.vcl b/app/code/Magento/PageCache/etc/varnish4.vcl
index 5936fcd69255d03dbc70e6e34bf60282bda2dca5..0f3dddb893d95d123a74ef618183ddb6c9e8bbe0 100644
--- a/app/code/Magento/PageCache/etc/varnish4.vcl
+++ b/app/code/Magento/PageCache/etc/varnish4.vcl
@@ -47,7 +47,7 @@ sub vcl_recv {
     std.collect(req.http.Cookie);
 
     # static files are always cacheable. remove SSL flag and cookie
-    if (req.url ~ "^/(pub/)?(media|static)/.*\.(png|jpg|jpeg|gif|css|js|swf|ico|woff|svg)$") {
+        if (req.url ~ "^/(pub/)?(media|static)/.*\.(ico|css|js|jpg|jpeg|png|gif|tiff|bmp|mp3|ogg|svg|swf|woff|woff2|eot|ttf|otf)$") {
         unset req.http.Https;
         unset req.http.Cookie;
     }
@@ -90,7 +90,7 @@ sub vcl_backend_response {
     # images, css and js are cacheable by default so we have to remove cookie also
     if (beresp.ttl > 0s && (bereq.method == "GET" || bereq.method == "HEAD")) {
         unset beresp.http.set-cookie;
-        if (bereq.url !~ "\.(css|js|jpg|png|gif|tiff|bmp|gz|tgz|bz2|tbz|mp3|ogg|svg|swf|woff)(\?|$)") {
+        if (bereq.url !~ "\.(ico|css|js|jpg|jpeg|png|gif|tiff|bmp|gz|tgz|bz2|tbz|mp3|ogg|svg|swf|woff|woff2|eot|ttf|otf)(\?|$)") {
             set beresp.http.Pragma = "no-cache";
             set beresp.http.Expires = "-1";
             set beresp.http.Cache-Control = "no-store, no-cache, must-revalidate, max-age=0";
diff --git a/app/code/Magento/Payment/Block/Info/Cc.php b/app/code/Magento/Payment/Block/Info/Cc.php
index bd92161c86834c161277851a5895e8d86d9152a1..afc1d2ebd298a15703e5efa8460eafca07125194 100644
--- a/app/code/Magento/Payment/Block/Info/Cc.php
+++ b/app/code/Magento/Payment/Block/Info/Cc.php
@@ -78,7 +78,7 @@ class Cc extends \Magento\Payment\Block\Info
     public function getCcExpDate()
     {
         $date = new \DateTime('now', new \DateTimeZone($this->_localeDate->getConfigTimezone()));
-        $date->setDate($this->getInfo()->getCcExpYear(), $this->getInfo()->getCcExpMonth(), $date->format('d'));
+        $date->setDate($this->getInfo()->getCcExpYear(), $this->getInfo()->getCcExpMonth() + 1, 0);
         return $date;
     }
 
diff --git a/app/code/Magento/Payment/Test/Unit/Block/Info/CcTest.php b/app/code/Magento/Payment/Test/Unit/Block/Info/CcTest.php
index 98760f01eacc72e2c5536061b47d90dc130638dc..cbaca7b85a3d74acea510f7bfd3028de205a942a 100644
--- a/app/code/Magento/Payment/Test/Unit/Block/Info/CcTest.php
+++ b/app/code/Magento/Payment/Test/Unit/Block/Info/CcTest.php
@@ -132,14 +132,18 @@ class CcTest extends \PHPUnit_Framework_TestCase
     public function testGetCcExpDate($ccExpMonth, $ccExpYear)
     {
         $paymentInfo = $this->getMock('Magento\Payment\Model\Info', ['getCcExpMonth', 'getCcExpYear'], [], '', false);
-        $paymentInfo->expects($this->any())
+        $paymentInfo
+            ->expects($this->any())
             ->method('getCcExpMonth')
             ->will($this->returnValue($ccExpMonth));
-        $paymentInfo->expects($this->any())
-            ->method('getCcExpYear')->will($this->returnValue($ccExpYear));
+        $paymentInfo
+            ->expects($this->any())
+            ->method('getCcExpYear')
+            ->will($this->returnValue($ccExpYear));
         $this->model->setData('info', $paymentInfo);
 
-        $this->localeDate->expects($this->exactly(2))
+        $this->localeDate
+            ->expects($this->exactly(2))
             ->method('getConfigTimezone')
             ->willReturn('America/Los_Angeles');
 
diff --git a/app/code/Magento/Payment/composer.json b/app/code/Magento/Payment/composer.json
index ed4c8488d654f6a435fc44c2b2fc58e340a2c99b..e01a5f8c9d78683adacbc9ed92cec5d014258aea 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-beta1",
-        "magento/module-store": "0.74.0-beta1",
-        "magento/module-sales": "0.74.0-beta1",
-        "magento/module-centinel": "0.74.0-beta1",
-        "magento/module-checkout": "0.74.0-beta1",
-        "magento/module-quote": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-config": "0.74.0-beta2",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-sales": "0.74.0-beta2",
+        "magento/module-centinel": "0.74.0-beta2",
+        "magento/module-checkout": "0.74.0-beta2",
+        "magento/module-quote": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Payment/view/adminhtml/templates/info/default.phtml b/app/code/Magento/Payment/view/adminhtml/templates/info/default.phtml
index 48a8c0a91dbf4a4af37cb8d5f3586969e0782aa4..f2db06784d9fae66316ec9ca74e3619286202f03 100644
--- a/app/code/Magento/Payment/view/adminhtml/templates/info/default.phtml
+++ b/app/code/Magento/Payment/view/adminhtml/templates/info/default.phtml
@@ -19,7 +19,7 @@
 <?php foreach ($_specificInfo as $_label => $_value):?>
     <tr>
         <th><?php echo $block->escapeHtml($_label)?>:</th>
-        <td><?php echo nl2br(implode($block->getValueAsArray($_value, true), "\n"))?></td>
+        <td><?php echo nl2br(implode("\n", $block->getValueAsArray($_value, true)))?></td>
     </tr>
 <?php endforeach; ?>
 </table>
diff --git a/app/code/Magento/Payment/view/adminhtml/templates/info/pdf/default.phtml b/app/code/Magento/Payment/view/adminhtml/templates/info/pdf/default.phtml
index 89d131de11cf184b4bde0e52d914791872e289db..db51c499e2835fde214a1b75db2fbda6f9219104 100644
--- a/app/code/Magento/Payment/view/adminhtml/templates/info/pdf/default.phtml
+++ b/app/code/Magento/Payment/view/adminhtml/templates/info/pdf/default.phtml
@@ -16,8 +16,8 @@
 
 <?php if ($_specificInfo = $block->getSpecificInformation()):?>
 <?php foreach ($_specificInfo as $_label => $_value):?>
-<?php echo $_label ?>: <?php echo implode($block->getValueAsArray($_value), ' ')?>{{pdf_row_separator}}
+<?php echo $_label ?>: <?php echo implode(' ', $block->getValueAsArray($_value))?>{{pdf_row_separator}}
 <?php endforeach; ?>
 <?php endif;?>
 
-<?php echo implode($block->getChildPdfAsArray(), '{{pdf_row_separator}}') ?>
+<?php echo implode('{{pdf_row_separator}}', $block->getChildPdfAsArray()) ?>
diff --git a/app/code/Magento/Payment/view/frontend/templates/info/default.phtml b/app/code/Magento/Payment/view/frontend/templates/info/default.phtml
index cbd9eb6f607536e895b08c75ffc7a31e6773d0f5..ae2a9e0b712d7e1354961986d9bfa76efcb870e7 100644
--- a/app/code/Magento/Payment/view/frontend/templates/info/default.phtml
+++ b/app/code/Magento/Payment/view/frontend/templates/info/default.phtml
@@ -21,7 +21,7 @@
             <?php foreach ($_specificInfo as $_label => $_value):?>
                 <tr>
                     <th scope="row"><?php echo $block->escapeHtml($_label)?></th>
-                    <td><?php echo nl2br(implode($block->getValueAsArray($_value, true), "\n"))?></td>
+                    <td><?php echo nl2br(implode("\n", $block->getValueAsArray($_value, true)))?></td>
                 </tr>
             <?php endforeach; ?>
         </table>
diff --git a/app/code/Magento/Persistent/composer.json b/app/code/Magento/Persistent/composer.json
index 11767647b31449cc627a8372c3606319dea190b0..9c8da77db34ae907db6b54c55a6854a0639f87c0 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-beta1",
-        "magento/module-checkout": "0.74.0-beta1",
-        "magento/module-customer": "0.74.0-beta1",
-        "magento/module-cron": "0.74.0-beta1",
-        "magento/module-page-cache": "0.74.0-beta1",
-        "magento/module-quote": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-checkout": "0.74.0-beta2",
+        "magento/module-customer": "0.74.0-beta2",
+        "magento/module-cron": "0.74.0-beta2",
+        "magento/module-page-cache": "0.74.0-beta2",
+        "magento/module-quote": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/ProductAlert/composer.json b/app/code/Magento/ProductAlert/composer.json
index be38ece6573145e27a836b060d26807eac683370..26d2e7aec1ff07e2db2d5a71c5a1b72472c9eec0 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-beta1",
-        "magento/module-catalog": "0.74.0-beta1",
-        "magento/module-customer": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/module-customer": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Quote/composer.json b/app/code/Magento/Quote/composer.json
index afc1734fbd94cd125ff2cddcb2fee917123f0605..ae730104a913cb91e40c2fe35a4b6f0267d33c96 100644
--- a/app/code/Magento/Quote/composer.json
+++ b/app/code/Magento/Quote/composer.json
@@ -3,23 +3,23 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta1",
-        "magento/module-catalog": "0.74.0-beta1",
-        "magento/module-catalog-rule": "0.74.0-beta1",
-        "magento/module-customer": "0.74.0-beta1",
-        "magento/module-authorization": "0.74.0-beta1",
-        "magento/module-payment": "0.74.0-beta1",
-        "magento/module-sales": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-directory": "0.74.0-beta1",
-        "magento/module-eav": "0.74.0-beta1",
-        "magento/module-tax": "0.74.0-beta1",
-        "magento/module-catalog-inventory": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/module-catalog-rule": "0.74.0-beta2",
+        "magento/module-customer": "0.74.0-beta2",
+        "magento/module-authorization": "0.74.0-beta2",
+        "magento/module-payment": "0.74.0-beta2",
+        "magento/module-sales": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-directory": "0.74.0-beta2",
+        "magento/module-eav": "0.74.0-beta2",
+        "magento/module-tax": "0.74.0-beta2",
+        "magento/module-catalog-inventory": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Reports/composer.json b/app/code/Magento/Reports/composer.json
index c11dd26ace010719356a7de27f8059d7d96f8d53..3723ef185420c053d25c340c108fe4be6f96a52f 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-beta1",
-        "magento/module-store": "0.74.0-beta1",
-        "magento/module-eav": "0.74.0-beta1",
-        "magento/module-customer": "0.74.0-beta1",
-        "magento/module-catalog": "0.74.0-beta1",
-        "magento/module-sales": "0.74.0-beta1",
-        "magento/module-cms": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-widget": "0.74.0-beta1",
-        "magento/module-log": "0.74.0-beta1",
-        "magento/module-wishlist": "0.74.0-beta1",
-        "magento/module-review": "0.74.0-beta1",
-        "magento/module-catalog-inventory": "0.74.0-beta1",
-        "magento/module-tax": "0.74.0-beta1",
-        "magento/module-downloadable": "0.74.0-beta1",
-        "magento/module-sales-rule": "0.74.0-beta1",
-        "magento/module-quote": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-config": "0.74.0-beta2",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-eav": "0.74.0-beta2",
+        "magento/module-customer": "0.74.0-beta2",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/module-sales": "0.74.0-beta2",
+        "magento/module-cms": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-widget": "0.74.0-beta2",
+        "magento/module-log": "0.74.0-beta2",
+        "magento/module-wishlist": "0.74.0-beta2",
+        "magento/module-review": "0.74.0-beta2",
+        "magento/module-catalog-inventory": "0.74.0-beta2",
+        "magento/module-tax": "0.74.0-beta2",
+        "magento/module-downloadable": "0.74.0-beta2",
+        "magento/module-sales-rule": "0.74.0-beta2",
+        "magento/module-quote": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/RequireJs/composer.json b/app/code/Magento/RequireJs/composer.json
index 2475e1bae2fe98fa634e68912d9f55ebb07f9d0a..ea1e62c2a69b85d7204632e26c74ff33b8b6734e 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-beta1",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Review/composer.json b/app/code/Magento/Review/composer.json
index fe9732c3832fe5da41ac0dbe2ca73e37207e9e0d..b8ed58f3b392fc59bea283d23fdf2b890862ef96 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-beta1",
-        "magento/module-catalog": "0.74.0-beta1",
-        "magento/module-customer": "0.74.0-beta1",
-        "magento/module-eav": "0.74.0-beta1",
-        "magento/module-theme": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-newsletter": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
-        "magento/module-ui": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/module-customer": "0.74.0-beta2",
+        "magento/module-eav": "0.74.0-beta2",
+        "magento/module-theme": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-newsletter": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
+        "magento/module-ui": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "suggest": {
-        "magento/module-cookie": "0.74.0-beta1"
+        "magento/module-cookie": "0.74.0-beta2"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Rss/composer.json b/app/code/Magento/Rss/composer.json
index 57d61c78416508948b9db84bf98c21b072ef9c0f..8ffd701cc3c4258b28e307ddeab9d71c3575e5c7 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-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
-        "magento/module-customer": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
+        "magento/module-customer": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Rule/composer.json b/app/code/Magento/Rule/composer.json
index 1325db3409841ea31efe8eda0424cc1ac1e8c019..a6519c1785c7d7a6cf0337f11c27611e6dd88dea 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-beta1",
-        "magento/module-eav": "0.74.0-beta1",
-        "magento/module-catalog": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-eav": "0.74.0-beta2",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "lib-libxml": "*",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Giftmessage.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Giftmessage.php
index f5f53b3f736c8c754b79c56ac89a81ce005010bf..52cc36384d6367e90a2ffb300629f43b8fd993ca 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Giftmessage.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Giftmessage.php
@@ -84,7 +84,7 @@ class Giftmessage extends \Magento\Sales\Block\Adminhtml\Order\Create\AbstractCr
         foreach ($allItems as $item) {
             if ($this->_getGiftmessageSaveModel()->getIsAllowedQuoteItem(
                 $item
-            ) && $this->_messageHelper->getIsMessagesAvailable(
+            ) && $this->_messageHelper->isMessagesAllowed(
                 'item',
                 $item,
                 $this->getStore()
diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Items/Grid.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Items/Grid.php
index 86fcf0a4ee35338465e2da808978bb9d46128852..fe33696ba778625a5c27be6b4bf8b43f7fcfd75e 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Items/Grid.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Items/Grid.php
@@ -232,9 +232,9 @@ class Grid extends \Magento\Sales\Block\Adminhtml\Order\Create\AbstractCreate
     public function isGiftMessagesAvailable($item = null)
     {
         if ($item === null) {
-            return $this->_messageHelper->getIsMessagesAvailable('items', $this->getQuote(), $this->getStore());
+            return $this->_messageHelper->isMessagesAllowed('items', $this->getQuote(), $this->getStore());
         }
-        return $this->_messageHelper->getIsMessagesAvailable('item', $item, $this->getStore());
+        return $this->_messageHelper->isMessagesAllowed('item', $item, $this->getStore());
     }
 
     /**
diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/View/Giftmessage.php b/app/code/Magento/Sales/Block/Adminhtml/Order/View/Giftmessage.php
index 546a3e5682549e3431f7b0dbcac1df1631c32990..2f70036c540aa9eb25c9cabe74b542e91451aa81 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Order/View/Giftmessage.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Order/View/Giftmessage.php
@@ -290,7 +290,7 @@ class Giftmessage extends \Magento\Backend\Block\Widget
      */
     public function canDisplayGiftmessage()
     {
-        return $this->_messageHelper->getIsMessagesAvailable(
+        return $this->_messageHelper->isMessagesAllowed(
             'order',
             $this->getEntity(),
             $this->getEntity()->getStoreId()
diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/View/Items/Renderer/DefaultRenderer.php b/app/code/Magento/Sales/Block/Adminhtml/Order/View/Items/Renderer/DefaultRenderer.php
index 22ca91855bedc6b0d921ffb9afd26464a2ab990d..92cc81fa6f2a8c54deebcec06b1190d71a205308 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Order/View/Items/Renderer/DefaultRenderer.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Order/View/Items/Renderer/DefaultRenderer.php
@@ -220,7 +220,7 @@ class DefaultRenderer extends \Magento\Sales\Block\Adminhtml\Items\Renderer\Defa
      */
     public function canDisplayGiftmessage()
     {
-        return $this->_messageHelper->getIsMessagesAvailable(
+        return $this->_messageHelper->isMessagesAllowed(
             'order_item',
             $this->getItem(),
             $this->getItem()->getOrder()->getStoreId()
diff --git a/app/code/Magento/Sales/Block/Adminhtml/Reorder/Renderer/Action.php b/app/code/Magento/Sales/Block/Adminhtml/Reorder/Renderer/Action.php
index 2690ecac41192aaf8c3e9e7b5c218458cf22d5e2..0e664f928847f931615f4b0361d97755c77878c1 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Reorder/Renderer/Action.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Reorder/Renderer/Action.php
@@ -93,7 +93,7 @@ class Action extends \Magento\Backend\Block\Widget\Grid\Column\Renderer\Abstract
             $attributesObject->setData($action['@']);
             $html[] = '<a ' . $attributesObject->serialize() . '>' . $action['#'] . '</a>';
         }
-        return implode($html, '');
+        return implode('', $html);
     }
 
     /**
diff --git a/app/code/Magento/Sales/composer.json b/app/code/Magento/Sales/composer.json
index 422223e5139f617720e275ad5d5e0e50d2e5896a..31b8dbf81c00ce7e59155bcdfb5e8a1bf8edef0e 100644
--- a/app/code/Magento/Sales/composer.json
+++ b/app/code/Magento/Sales/composer.json
@@ -3,34 +3,34 @@
     "description": "N/A",
     "require": {
         "php": "~5.5.0|~5.6.0",
-        "magento/module-store": "0.74.0-beta1",
-        "magento/module-catalog": "0.74.0-beta1",
-        "magento/module-customer": "0.74.0-beta1",
-        "magento/module-authorization": "0.74.0-beta1",
-        "magento/module-payment": "0.74.0-beta1",
-        "magento/module-checkout": "0.74.0-beta1",
-        "magento/module-theme": "0.74.0-beta1",
-        "magento/module-sales-rule": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-widget": "0.74.0-beta1",
-        "magento/module-directory": "0.74.0-beta1",
-        "magento/module-eav": "0.74.0-beta1",
-        "magento/module-tax": "0.74.0-beta1",
-        "magento/module-gift-message": "0.74.0-beta1",
-        "magento/module-reports": "0.74.0-beta1",
-        "magento/module-catalog-inventory": "0.74.0-beta1",
-        "magento/module-wishlist": "0.74.0-beta1",
-        "magento/module-email": "0.74.0-beta1",
-        "magento/module-shipping": "0.74.0-beta1",
-        "magento/module-config": "0.74.0-beta1",
-        "magento/module-media-storage": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
-        "magento/module-ui": "0.74.0-beta1",
-        "magento/module-quote": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/module-customer": "0.74.0-beta2",
+        "magento/module-authorization": "0.74.0-beta2",
+        "magento/module-payment": "0.74.0-beta2",
+        "magento/module-checkout": "0.74.0-beta2",
+        "magento/module-theme": "0.74.0-beta2",
+        "magento/module-sales-rule": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-widget": "0.74.0-beta2",
+        "magento/module-directory": "0.74.0-beta2",
+        "magento/module-eav": "0.74.0-beta2",
+        "magento/module-tax": "0.74.0-beta2",
+        "magento/module-gift-message": "0.74.0-beta2",
+        "magento/module-reports": "0.74.0-beta2",
+        "magento/module-catalog-inventory": "0.74.0-beta2",
+        "magento/module-wishlist": "0.74.0-beta2",
+        "magento/module-email": "0.74.0-beta2",
+        "magento/module-shipping": "0.74.0-beta2",
+        "magento/module-config": "0.74.0-beta2",
+        "magento/module-media-storage": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
+        "magento/module-ui": "0.74.0-beta2",
+        "magento/module-quote": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/create/giftmessage.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/create/giftmessage.phtml
index 44b97e5d55ea6a7ffcd17a97a5e25ffd05cfc083..846caa0fd3951dd5d83be7d148a8ca942d1fd3ae 100644
--- a/app/code/Magento/Sales/view/adminhtml/templates/order/create/giftmessage.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/order/create/giftmessage.phtml
@@ -7,13 +7,13 @@
 // @codingStandardsIgnoreFile
 
 ?>
-<?php if ($this->helper('Magento\GiftMessage\Helper\Message')->getIsMessagesAvailable('main', $block->getQuote(), $block->getStoreId())): ?>
+<?php if ($this->helper('Magento\GiftMessage\Helper\Message')->isMessagesAllowed('main', $block->getQuote(), $block->getStoreId())): ?>
 <?php $_items = $block->getItems(); ?>
 <div id="order-giftmessage" class="giftmessage-order-create box-left">
     <fieldset>
         <legend><?php echo __('Gift Message for the Entire Order') ?></legend>
         <br />
-        <?php if ($this->helper('Magento\GiftMessage\Helper\Message')->getIsMessagesAvailable('main', $block->getQuote(), $block->getStoreId())): ?>
+        <?php if ($this->helper('Magento\GiftMessage\Helper\Message')->isMessagesAllowed('main', $block->getQuote(), $block->getStoreId())): ?>
             <div class="giftmessage-entire-order">
                 <p><?php echo __('If you don\'t want to leave a gift message for the entire order, leave this box blank.') ?></p>
                 <?php echo $block->getFormHtml($block->getQuote(), 'main') ?>
diff --git a/app/code/Magento/Sales/view/frontend/templates/email/items.phtml b/app/code/Magento/Sales/view/frontend/templates/email/items.phtml
index 2f57c23485c3d0ab4b97dd809315683c921f51cb..b8a15bcbb3707819001b5ab6016a5ba635b3dbe7 100644
--- a/app/code/Magento/Sales/view/frontend/templates/email/items.phtml
+++ b/app/code/Magento/Sales/view/frontend/templates/email/items.phtml
@@ -34,7 +34,7 @@
         <?php echo $block->getChildHtml('order_totals') ?>
     </tbody>
 </table>
-<?php if ($this->helper('Magento\GiftMessage\Helper\Message')->isMessagesAvailable('order', $_order, $_order->getStore()) && $_order->getGiftMessageId()): ?>
+<?php if ($this->helper('Magento\GiftMessage\Helper\Message')->isMessagesAllowed('order', $_order, $_order->getStore()) && $_order->getGiftMessageId()): ?>
     <?php $_giftMessage = $this->helper('Magento\GiftMessage\Helper\Message')->getGiftMessage($_order->getGiftMessageId()); ?>
     <?php if ($_giftMessage): ?>
 <br />
diff --git a/app/code/Magento/Sales/view/frontend/templates/order/items.phtml b/app/code/Magento/Sales/view/frontend/templates/order/items.phtml
index 166366a05d870573701a66f9951aa656bc4c4a8e..f5c27e01af6f791aa3c0cfb267142cc1441a8776 100644
--- a/app/code/Magento/Sales/view/frontend/templates/order/items.phtml
+++ b/app/code/Magento/Sales/view/frontend/templates/order/items.phtml
@@ -31,7 +31,7 @@
 } ?>
             <tbody>
                 <?php echo $block->getItemHtml($_item) ?>
-                <?php if ($this->helper('Magento\GiftMessage\Helper\Message')->getIsMessagesAvailable('order_item', $_item) && $_item->getGiftMessageId()): ?>
+                <?php if ($this->helper('Magento\GiftMessage\Helper\Message')->isMessagesAllowed('order_item', $_item) && $_item->getGiftMessageId()): ?>
                     <?php $_giftMessage = $this->helper('Magento\GiftMessage\Helper\Message')->getGiftMessageForEntity($_item); ?>
                     <tr>
                         <td class="col options" colspan="5">
diff --git a/app/code/Magento/Sales/view/frontend/templates/order/view.phtml b/app/code/Magento/Sales/view/frontend/templates/order/view.phtml
index 1106464712cfa2fbe9c9baf2cd684411c4682e76..64b84dacb490f9d1206af264e370052d3241c2c2 100644
--- a/app/code/Magento/Sales/view/frontend/templates/order/view.phtml
+++ b/app/code/Magento/Sales/view/frontend/templates/order/view.phtml
@@ -20,7 +20,7 @@
 
     <?php echo $block->getChildHtml('order_items') ?>
 
-    <?php if ($this->helper('Magento\GiftMessage\Helper\Message')->getIsMessagesAvailable('order', $_order) && $_order->getGiftMessageId()): ?>
+    <?php if ($this->helper('Magento\GiftMessage\Helper\Message')->isMessagesAllowed('order', $_order) && $_order->getGiftMessageId()): ?>
     <div class="block block-order-details-gift-message">
         <div class="block-title"><strong><?php echo __('Gift Message for This Order') ?></strong></div>
         <?php $_giftMessage = $this->helper('Magento\GiftMessage\Helper\Message')->getGiftMessageForEntity($_order); ?>
diff --git a/app/code/Magento/SalesRule/Model/Resource/Report/Collection.php b/app/code/Magento/SalesRule/Model/Resource/Report/Collection.php
index 96883618eeabdb6c71da9d0d444aff5d6d15f029..8fa981c6bee286253548a3dc7e55f75c74d0a8ba 100644
--- a/app/code/Magento/SalesRule/Model/Resource/Report/Collection.php
+++ b/app/code/Magento/SalesRule/Model/Resource/Report/Collection.php
@@ -170,7 +170,7 @@ class Collection extends \Magento\Sales\Model\Resource\Report\Collection\Abstrac
         }
 
         if (!empty($rulesFilterSqlParts)) {
-            $this->getSelect()->where(implode($rulesFilterSqlParts, ' OR '));
+            $this->getSelect()->where(implode(' OR ', $rulesFilterSqlParts));
         }
         return $this;
     }
diff --git a/app/code/Magento/SalesRule/composer.json b/app/code/Magento/SalesRule/composer.json
index 7b6dabaf938042fa2b51407057005cace699102d..e51f138d4a36c70bcfdda1c4bc5f7575a53c9bfb 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-beta1",
-        "magento/module-store": "0.74.0-beta1",
-        "magento/module-rule": "0.74.0-beta1",
-        "magento/module-catalog": "0.74.0-beta1",
-        "magento/module-sales": "0.74.0-beta1",
-        "magento/module-eav": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-customer": "0.74.0-beta1",
-        "magento/module-directory": "0.74.0-beta1",
-        "magento/module-shipping": "0.74.0-beta1",
-        "magento/module-payment": "0.74.0-beta1",
-        "magento/module-reports": "0.74.0-beta1",
-        "magento/module-catalog-rule": "0.74.0-beta1",
-        "magento/module-widget": "0.74.0-beta1",
-        "magento/module-quote": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-config": "0.74.0-beta2",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-rule": "0.74.0-beta2",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/module-sales": "0.74.0-beta2",
+        "magento/module-eav": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-customer": "0.74.0-beta2",
+        "magento/module-directory": "0.74.0-beta2",
+        "magento/module-shipping": "0.74.0-beta2",
+        "magento/module-payment": "0.74.0-beta2",
+        "magento/module-reports": "0.74.0-beta2",
+        "magento/module-catalog-rule": "0.74.0-beta2",
+        "magento/module-widget": "0.74.0-beta2",
+        "magento/module-quote": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Search/composer.json b/app/code/Magento/Search/composer.json
index 415447e9acbc405a7c005793b35d0e22a614f5f5..04db045d1fd36024eacc4f9f8d3abc4cfc815682 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-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-catalog-search": "0.74.0-beta1",
-        "magento/module-store": "0.74.0-beta1",
-        "magento/module-reports": "0.74.0-beta1",
+        "magento/framework": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-catalog-search": "0.74.0-beta2",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-reports": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Sendfriend/composer.json b/app/code/Magento/Sendfriend/composer.json
index 79ff1d7a327d2abc552ae245dab2ec19f579653f..17f3ff0c27f3cdb4208d4fc6bcfe9e97b57a2a68 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-beta1",
-        "magento/module-catalog": "0.74.0-beta1",
-        "magento/module-customer": "0.74.0-beta1",
-        "magento/module-theme": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/module-customer": "0.74.0-beta2",
+        "magento/module-theme": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Shipping/composer.json b/app/code/Magento/Shipping/composer.json
index 4b7d996aa9f690da7d3cc9e16022535c30e4810d..a20dd8cc86d23868eb2561b8d12302570fe0f54b 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-beta1",
-        "magento/module-catalog": "0.74.0-beta1",
-        "magento/module-sales": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-directory": "0.74.0-beta1",
-        "magento/module-contact": "0.74.0-beta1",
-        "magento/module-customer": "0.74.0-beta1",
-        "magento/module-payment": "0.74.0-beta1",
-        "magento/module-tax": "0.74.0-beta1",
-        "magento/module-catalog-inventory": "0.74.0-beta1",
-        "magento/module-quote": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/module-sales": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-directory": "0.74.0-beta2",
+        "magento/module-contact": "0.74.0-beta2",
+        "magento/module-customer": "0.74.0-beta2",
+        "magento/module-payment": "0.74.0-beta2",
+        "magento/module-tax": "0.74.0-beta2",
+        "magento/module-catalog-inventory": "0.74.0-beta2",
+        "magento/module-quote": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "ext-gd": "*",
         "magento/magento-composer-installer": "*"
     },
     "suggest": {
-        "magento/module-fedex": "0.74.0-beta1",
-        "magento/module-ups": "0.74.0-beta1"
+        "magento/module-fedex": "0.74.0-beta2",
+        "magento/module-ups": "0.74.0-beta2"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Sitemap/composer.json b/app/code/Magento/Sitemap/composer.json
index 12eb36220dca7a48017263c5cbec95585753bd00..8d0878ec176cf9f2e1430698ee9787e85d7c1b09 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-beta1",
-        "magento/module-catalog": "0.74.0-beta1",
-        "magento/module-eav": "0.74.0-beta1",
-        "magento/module-cms": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-catalog-url-rewrite": "0.74.0-beta1",
-        "magento/module-media-storage": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/module-eav": "0.74.0-beta2",
+        "magento/module-cms": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-catalog-url-rewrite": "0.74.0-beta2",
+        "magento/module-media-storage": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Store/composer.json b/app/code/Magento/Store/composer.json
index 23428c023c772aee7985533b95f22e38f7a75674..c8c35d4401a6e1b73cfc9803080327c9d510aad9 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-beta1",
-        "magento/module-ui": "0.74.0-beta1",
-        "magento/module-config": "0.74.0-beta1",
-        "magento/module-media-storage": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-directory": "0.74.0-beta2",
+        "magento/module-ui": "0.74.0-beta2",
+        "magento/module-config": "0.74.0-beta2",
+        "magento/module-media-storage": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Tax/composer.json b/app/code/Magento/Tax/composer.json
index aadd9667575528ba6c8ca55d3799b21cc02bfb4b..b5795c8cf572ce6e042b9c5303de88a3b3688edb 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-beta1",
-        "magento/module-store": "0.74.0-beta1",
-        "magento/module-catalog": "0.74.0-beta1",
-        "magento/module-customer": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-directory": "0.74.0-beta1",
-        "magento/module-checkout": "0.74.0-beta1",
-        "magento/module-shipping": "0.74.0-beta1",
-        "magento/module-eav": "0.74.0-beta1",
-        "magento/module-sales": "0.74.0-beta1",
-        "magento/module-reports": "0.74.0-beta1",
-        "magento/module-quote": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-config": "0.74.0-beta2",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/module-customer": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-directory": "0.74.0-beta2",
+        "magento/module-checkout": "0.74.0-beta2",
+        "magento/module-shipping": "0.74.0-beta2",
+        "magento/module-eav": "0.74.0-beta2",
+        "magento/module-sales": "0.74.0-beta2",
+        "magento/module-reports": "0.74.0-beta2",
+        "magento/module-quote": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/TaxImportExport/composer.json b/app/code/Magento/TaxImportExport/composer.json
index 5691c9d7310bbfd52bc0c717b997878258788548..8aedb28da45de8215cddff61e630a3e0be1d7224 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-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-directory": "0.74.0-beta1",
-        "magento/module-store": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-tax": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-directory": "0.74.0-beta2",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Theme/Block/Html/Topmenu.php b/app/code/Magento/Theme/Block/Html/Topmenu.php
index 5bd175abffc813c4117778c4420df3d3a509c452..177418d892ed452d2864c4327e4a837a62ba7b07 100644
--- a/app/code/Magento/Theme/Block/Html/Topmenu.php
+++ b/app/code/Magento/Theme/Block/Html/Topmenu.php
@@ -7,6 +7,9 @@ namespace Magento\Theme\Block\Html;
 
 use Magento\Framework\View\Block\IdentityInterface;
 use Magento\Framework\View\Element\Template;
+use Magento\Framework\Data\TreeFactory;
+use Magento\Framework\Data\Tree\Node;
+use Magento\Framework\Data\Tree\NodeFactory;
 
 /**
  * Html page top menu block
@@ -28,13 +31,32 @@ class Topmenu extends Template implements IdentityInterface
     protected $_menu;
 
     /**
-     * Init top menu tree structure
+     * Core registry
      *
-     * @return void
+     * @var Registry
      */
-    public function _construct()
-    {
-        $this->_menu = new \Magento\Framework\Data\Tree\Node([], 'root', new \Magento\Framework\Data\Tree());
+    protected $registry;
+
+    /**
+     * @param Template\Context $context
+     * @param NodeFactory $nodeFactory
+     * @param TreeFactory $treeFactory
+     * @param array $data
+     */
+    public function __construct(
+        Template\Context $context,
+        NodeFactory $nodeFactory,
+        TreeFactory $treeFactory,
+        array $data = []
+    ) {
+        parent::__construct($context, $data);
+        $this->_menu = $nodeFactory->create(
+            [
+                'data' => [],
+                'idField' => 'root',
+                'tree' => $treeFactory->create()
+            ]
+        );
     }
 
     /**
@@ -272,6 +294,8 @@ class Topmenu extends Template implements IdentityInterface
 
         if ($item->getIsActive()) {
             $classes[] = 'active';
+        } elseif ($item->getHasActive()) {
+            $classes[] = 'has-active';
         }
 
         if ($item->getIsLast()) {
diff --git a/app/code/Magento/Theme/Test/Unit/Block/Html/TopmenuTest.php b/app/code/Magento/Theme/Test/Unit/Block/Html/TopmenuTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..ab2afb8ef4ea906040c419e4e04522f28013c09d
--- /dev/null
+++ b/app/code/Magento/Theme/Test/Unit/Block/Html/TopmenuTest.php
@@ -0,0 +1,141 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Theme\Test\Unit\Block\Html;
+
+use Magento\Theme\Block\Html\Topmenu;
+use Magento\Framework\Registry;
+use Magento\Framework\View\Element\Template\Context;
+use Magento\Framework\Data\TreeFactory;
+use Magento\Framework\Data\Tree\NodeFactory;
+
+class TopmenuTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Registry|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $registry;
+
+    /**
+     * @var Context|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $context;
+
+    /**
+     * @var NodeFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $nodeFactory;
+
+    /**
+     * @var TreeFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $treeFactory;
+
+    /**
+     * @var \Magento\Catalog\Model\Category|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $category;
+
+    // @codingStandardsIgnoreStart
+
+    /** @var string  */
+    protected $htmlWithoutCategory = <<<HTML
+<li  class="level0 nav-1 first"><a href="http://magento2/category-0.html" ><span></span></a></li><li  class="level0 nav-2"><a href="http://magento2/category-1.html" ><span></span></a></li><li  class="level0 nav-3"><a href="http://magento2/category-2.html" ><span></span></a></li><li  class="level0 nav-4"><a href="http://magento2/category-3.html" ><span></span></a></li><li  class="level0 nav-5"><a href="http://magento2/category-4.html" ><span></span></a></li><li  class="level0 nav-6"><a href="http://magento2/category-5.html" ><span></span></a></li><li  class="level0 nav-7"><a href="http://magento2/category-6.html" ><span></span></a></li><li  class="level0 nav-8"><a href="http://magento2/category-7.html" ><span></span></a></li><li  class="level0 nav-9"><a href="http://magento2/category-8.html" ><span></span></a></li><li  class="level0 nav-10 last"><a href="http://magento2/category-9.html" ><span></span></a></li>
+HTML;
+
+    /** @var string  */
+    protected $htmlWithCategory = <<<HTML
+<li  class="level0 nav-1 first active"><a href="http://magento2/category-0.html" ><span></span></a></li><li  class="level0 nav-2"><a href="http://magento2/category-1.html" ><span></span></a></li><li  class="level0 nav-3"><a href="http://magento2/category-2.html" ><span></span></a></li><li  class="level0 nav-4"><a href="http://magento2/category-3.html" ><span></span></a></li><li  class="level0 nav-5"><a href="http://magento2/category-4.html" ><span></span></a></li><li  class="level0 nav-6"><a href="http://magento2/category-5.html" ><span></span></a></li><li  class="level0 nav-7"><a href="http://magento2/category-6.html" ><span></span></a></li><li  class="level0 nav-8"><a href="http://magento2/category-7.html" ><span></span></a></li><li  class="level0 nav-9"><a href="http://magento2/category-8.html" ><span></span></a></li><li  class="level0 nav-10 last"><a href="http://magento2/category-9.html" ><span></span></a></li>
+HTML;
+
+    // @codingStandardsIgnoreEnd
+
+    public function setUp()
+    {
+        $isCurrentItem = $this->getName() == 'testGetHtmlWithSelectedCategory' ? true : false;
+        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+
+        $this->context = $objectManager->getObject('Magento\Framework\View\Element\Template\Context');
+
+        $this->nodeFactory = $this->getMock('Magento\Framework\Data\Tree\NodeFactory', [], [], '', false);
+        $this->treeFactory = $this->getMock('Magento\Framework\Data\TreeFactory', [], [], '', false);
+
+        $tree = $this->getMock('Magento\Framework\Data\Tree', [], [], '', false);
+
+        $container = $this->getMock('Magento\Catalog\Model\Resource\Category\Tree', [], [], '', false);
+
+        $children = $this->getMock(
+            'Magento\Framework\Data\Tree\Node\Collection',
+            ['count'],
+            ['container' => $container]
+        );
+
+        for ($i = 0; $i < 10; $i++) {
+            $id = "category-node-$i";
+            $categoryNode = $this->getMock('Magento\Framework\Data\Tree\Node', ['getId', 'hasChildren'], [], '', false);
+            $categoryNode
+                ->expects($this->once())
+                ->method('getId')
+                ->willReturn($id);
+            $categoryNode
+                ->expects($this->atLeastOnce())
+                ->method('hasChildren')
+                ->willReturn(false);
+            $categoryNode->setData(
+                [
+                    'name' => "Category $i",
+                    'id' => $id,
+                    'url' => "http://magento2/category-$i.html",
+                    'is_active' => $i == 0 ? $isCurrentItem : false,
+                    'is_current_item' => $i == 0 ? $isCurrentItem : false,
+
+                ]
+            );
+            $children->add($categoryNode);
+        }
+
+        $children
+            ->expects($this->once())
+            ->method('count')
+            ->willReturn(10);
+
+        $node = $this->getMock('Magento\Framework\Data\Tree\Node', ['getChildren'], [], '', false);
+        $node
+            ->expects($this->once())
+            ->method('getChildren')
+            ->willReturn($children);
+        $node
+            ->expects($this->any())
+            ->method('__call')
+            ->with('getLevel', [])
+            ->willReturn(null);
+
+        $this->nodeFactory
+            ->expects($this->once())
+            ->method('create')
+            ->willReturn($node);
+
+        $this->treeFactory
+            ->expects($this->once())
+            ->method('create')
+            ->willReturn($tree);
+    }
+
+    protected function getTopmenu()
+    {
+        return new Topmenu($this->context, $this->nodeFactory, $this->treeFactory);
+    }
+
+    public function testGetHtmlWithoutSelectedCategory()
+    {
+        $this->assertEquals($this->htmlWithoutCategory, $this->getTopmenu()->getHtml());
+    }
+
+    public function testGetHtmlWithSelectedCategory()
+    {
+        $this->assertEquals($this->htmlWithCategory, $this->getTopmenu()->getHtml());
+    }
+}
diff --git a/app/code/Magento/Theme/composer.json b/app/code/Magento/Theme/composer.json
index 054b5be09cb89b6af480f563d49084c47d61356f..b26672d7ac1b1a7cd5b2d0705ba0a8e11b05962f 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-beta1",
-        "magento/module-customer": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-cms": "0.74.0-beta1",
-        "magento/module-eav": "0.74.0-beta1",
-        "magento/module-widget": "0.74.0-beta1",
-        "magento/module-config": "0.74.0-beta1",
-        "magento/module-media-storage": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
-        "magento/module-require-js": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-customer": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-cms": "0.74.0-beta2",
+        "magento/module-eav": "0.74.0-beta2",
+        "magento/module-widget": "0.74.0-beta2",
+        "magento/module-config": "0.74.0-beta2",
+        "magento/module-media-storage": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
+        "magento/module-require-js": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "suggest": {
-        "magento/module-translation": "0.74.0-beta1"
+        "magento/module-translation": "0.74.0-beta2"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Translation/composer.json b/app/code/Magento/Translation/composer.json
index 2b6b99c5a5b6684b0dd40ae7c719d2155a199496..70864da21f8b8c6a8e5a41858cada3c080ebd112 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-beta1",
-        "magento/module-developer": "0.74.0-beta1",
-        "magento/module-store": "0.74.0-beta1",
-        "magento/module-theme": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-developer": "0.74.0-beta2",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-theme": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Ui/Component/FilterPool.php b/app/code/Magento/Ui/Component/FilterPool.php
index 6c399f1860cf51a769a8662595ad31a62452e191..fae9e248d58ab64d3efd2c5355a4dd4b6517524d 100644
--- a/app/code/Magento/Ui/Component/FilterPool.php
+++ b/app/code/Magento/Ui/Component/FilterPool.php
@@ -144,7 +144,7 @@ class FilterPool extends AbstractView
             }
             $condition = $this->filterPoolProvider->getFilter($metaData[$field]['filter_type'])->getCondition($value);
             if ($condition !== null) {
-                $collection->addFilter($field, $field, $condition);
+                $collection->addFieldToFilter($field, $condition);
             }
         }
     }
diff --git a/app/code/Magento/Ui/Component/Listing.php b/app/code/Magento/Ui/Component/Listing.php
index 1cfbaa1acd6f32b74a42ed67eff1b24472b41e80..6d8437a886c5e531522c59fe1fae4e13f7461ab3 100644
--- a/app/code/Magento/Ui/Component/Listing.php
+++ b/app/code/Magento/Ui/Component/Listing.php
@@ -188,7 +188,7 @@ class Listing extends AbstractView
     public function getCollectionItems()
     {
         $items = [];
-        $collection = $this->getDataCollection()->getResultCollection();
+        $collection = $this->getDataCollection();
         foreach ($collection->getItems() as $item) {
             $actualFields = [];
             $itemsData = $this->getDataFromDataProvider($item->getData());
@@ -230,8 +230,8 @@ class Listing extends AbstractView
         );
         $this->renderContext->getStorage()->addGlobalData('dump', ['extenders' => []]);
 
-        $collection = $this->getDataCollection()->getResultCollection();
-        $totalCount = $collection->getTotalCount();
+        $collection = $this->getDataCollection();
+        $totalCount = $collection->count();
         $this->renderContext->getStorage()->addDataSource(
             $this->getName(),
             [
diff --git a/app/code/Magento/Ui/Component/Paging.php b/app/code/Magento/Ui/Component/Paging.php
index 9a8f0a5ddd9b4eaedf2f144b484298eed0d0e301..7c504b74ac8303fff539ffe9671af8a9c68039e7 100644
--- a/app/code/Magento/Ui/Component/Paging.php
+++ b/app/code/Magento/Ui/Component/Paging.php
@@ -37,7 +37,10 @@ class Paging extends AbstractView
         $offset = $this->renderContext->getRequestParam('page', $defaultPage);
         $defaultLimit = $this->config->getData('pageSize');
         $size = $this->renderContext->getRequestParam('limit', $defaultLimit);
-        $this->renderContext->getStorage()->getDataCollection($this->getParentName())->setLimit($offset, $size);
+        $this->renderContext->getStorage()
+            ->getDataCollection($this->getParentName())
+            ->setPageSize($size)
+            ->setCurPage($offset);
     }
 
     /**
diff --git a/app/code/Magento/Ui/Test/Unit/Component/PagingTest.php b/app/code/Magento/Ui/Test/Unit/Component/PagingTest.php
index 68af1081739d613c26815a54088cc6e55a6ed431..e8cd28a27665a09b164e93c2f76c58e72ffd1ed7 100644
--- a/app/code/Magento/Ui/Test/Unit/Component/PagingTest.php
+++ b/app/code/Magento/Ui/Test/Unit/Component/PagingTest.php
@@ -153,7 +153,7 @@ class PagingTest extends \PHPUnit_Framework_TestCase
             false,
             true,
             true,
-            ['setLimit']
+            ['setPageSize', 'setCurPage']
         );
 
         $this->renderContextMock->expects($this->any())->method('getStorage')->willReturn($storageMock);
@@ -173,8 +173,12 @@ class PagingTest extends \PHPUnit_Framework_TestCase
             );
 
         $dataCollectionMock->expects($this->any())
-            ->method('setLimit')
-            ->with($paramsPage, $paramsSize)
+            ->method('setPageSize')
+            ->with($paramsSize)
+            ->willReturnSelf();
+        $dataCollectionMock->expects($this->any())
+            ->method('setCurPage')
+            ->with($paramsPage)
             ->willReturnSelf();
 
         $this->assertNull($this->view->prepare());
diff --git a/app/code/Magento/Ui/composer.json b/app/code/Magento/Ui/composer.json
index b0982298f12b05511723d258d7c814e1a1dcb972..f87854f14f8ce4ad5f97595870996f5e3ae8105f 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-beta1",
-        "magento/framework": "0.74.0-beta1",
-        "magento/module-eav": "0.74.0-beta1",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
+        "magento/module-eav": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Ups/composer.json b/app/code/Magento/Ups/composer.json
index 3ade1437142271516c30b3e9e6bb535b66243fde..20f97b0f584c966aa380087464568b83b37d4634 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-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-sales": "0.74.0-beta1",
-        "magento/module-shipping": "0.74.0-beta1",
-        "magento/module-directory": "0.74.0-beta1",
-        "magento/module-catalog-inventory": "0.74.0-beta1",
-        "magento/module-quote": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-sales": "0.74.0-beta2",
+        "magento/module-shipping": "0.74.0-beta2",
+        "magento/module-directory": "0.74.0-beta2",
+        "magento/module-catalog-inventory": "0.74.0-beta2",
+        "magento/module-quote": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/UrlRewrite/composer.json b/app/code/Magento/UrlRewrite/composer.json
index 0f6cc4c40641bbbf39e21818263d2b6e59ce3c2d..5c1a1dd683191df1966b8a4097a6916f7e8bfe50 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-beta1",
-        "magento/module-store": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-catalog-url-rewrite": "0.74.0-beta1",
-        "magento/module-cms": "0.74.0-beta1",
-        "magento/module-cms-url-rewrite": "0.74.0-beta1",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-catalog-url-rewrite": "0.74.0-beta2",
+        "magento/module-cms": "0.74.0-beta2",
+        "magento/module-cms-url-rewrite": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/User/Controller/Adminhtml/User/Save.php b/app/code/Magento/User/Controller/Adminhtml/User/Save.php
index 204b188822dbf8935ba57ccdacd7d8438deaf8be..45a960f72e2d48d3accf7931163c206768cd4723 100644
--- a/app/code/Magento/User/Controller/Adminhtml/User/Save.php
+++ b/app/code/Magento/User/Controller/Adminhtml/User/Save.php
@@ -83,7 +83,7 @@ class Save extends \Magento\User\Controller\Adminhtml\User
     {
         $this->_getSession()->setUserData($data);
         $arguments = $model->getId() ? ['user_id' => $model->getId()] : [];
-        $arguments = array_merge($arguments, ['_current' => true]);
+        $arguments = array_merge($arguments, ['_current' => true, 'active_tab' => '']);
         $this->_redirect('adminhtml/*/edit', $arguments);
     }
 }
diff --git a/app/code/Magento/User/composer.json b/app/code/Magento/User/composer.json
index d38aaa90c87b16997210056787a35102cb2950f6..b594a2acc6525460f0961f3fad8ccf1c2c77f3c0 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-beta1",
-        "magento/module-authorization": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-integration": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-authorization": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-integration": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Usps/composer.json b/app/code/Magento/Usps/composer.json
index 68f18c23eb633ccde6f5164311a0780751b46aef..b98f0b6f9aff08165c319b08eea7597015ebb077 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-beta1",
-        "magento/module-shipping": "0.74.0-beta1",
-        "magento/module-directory": "0.74.0-beta1",
-        "magento/module-catalog": "0.74.0-beta1",
-        "magento/module-sales": "0.74.0-beta1",
-        "magento/module-catalog-inventory": "0.74.0-beta1",
-        "magento/module-quote": "0.74.0-beta1",
-        "magento/module-config": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-shipping": "0.74.0-beta2",
+        "magento/module-directory": "0.74.0-beta2",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/module-sales": "0.74.0-beta2",
+        "magento/module-catalog-inventory": "0.74.0-beta2",
+        "magento/module-quote": "0.74.0-beta2",
+        "magento/module-config": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "lib-libxml": "*",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Variable/composer.json b/app/code/Magento/Variable/composer.json
index 6d7b619e65727bd62962c50a4ca9ab2159acde5d..3ebd1161f56fe1553a95f86d78d95f41cb53a1bb 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-beta1",
-        "magento/module-email": "0.74.0-beta1",
-        "magento/module-store": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-email": "0.74.0-beta2",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Version/composer.json b/app/code/Magento/Version/composer.json
index 9b9831759083c9a51158378d524d2f5a07dd0769..790873f60c90f7a4ccdeb117ff9215e79d0c6b8a 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-beta1",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Webapi/composer.json b/app/code/Magento/Webapi/composer.json
index 0136c7bdf532b9264ec783b69f5e64a269f03cb9..737fbb38189e971ee9bc6d29040a741b1ad88c5e 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-beta1",
-        "magento/module-authorization": "0.74.0-beta1",
-        "magento/module-integration": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-authorization": "0.74.0-beta2",
+        "magento/module-integration": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "suggest": {
-        "magento/module-user": "0.74.0-beta1"
+        "magento/module-user": "0.74.0-beta2"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Weee/composer.json b/app/code/Magento/Weee/composer.json
index 8480dfcfa5fe338a9c6fdceeb566ecb024f8554f..25eedfda977a62a7110e0aa1a7193878f846bf34 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-beta1",
-        "magento/module-catalog": "0.74.0-beta1",
-        "magento/module-tax": "0.74.0-beta1",
-        "magento/module-sales": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-directory": "0.74.0-beta1",
-        "magento/module-eav": "0.74.0-beta1",
-        "magento/module-customer": "0.74.0-beta1",
-        "magento/module-quote": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/module-tax": "0.74.0-beta2",
+        "magento/module-sales": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-directory": "0.74.0-beta2",
+        "magento/module-eav": "0.74.0-beta2",
+        "magento/module-customer": "0.74.0-beta2",
+        "magento/module-quote": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Widget/composer.json b/app/code/Magento/Widget/composer.json
index 0aa395f85c8c85205b03bea4407a46211ae5801f..a1981449435f5125c48e5251ee76eeb14b77ac42 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-beta1",
-        "magento/module-cms": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-catalog": "0.74.0-beta1",
-        "magento/module-theme": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
-        "magento/module-variable": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-cms": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/module-theme": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
+        "magento/module-variable": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Wishlist/composer.json b/app/code/Magento/Wishlist/composer.json
index 004b28a9a14d3769dcf3dc22f7af500a5da4e2c6..567e48897c9d618d940785d8e587c734c49cdc44 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-beta1",
-        "magento/module-customer": "0.74.0-beta1",
-        "magento/module-catalog": "0.74.0-beta1",
-        "magento/module-checkout": "0.74.0-beta1",
-        "magento/module-theme": "0.74.0-beta1",
-        "magento/module-catalog-inventory": "0.74.0-beta1",
-        "magento/module-rss": "0.74.0-beta1",
-        "magento/module-backend": "0.74.0-beta1",
-        "magento/module-sales": "0.74.0-beta1",
-        "magento/module-grouped-product": "0.74.0-beta1",
-        "magento/framework": "0.74.0-beta1",
-        "magento/module-ui": "0.74.0-beta1",
+        "magento/module-store": "0.74.0-beta2",
+        "magento/module-customer": "0.74.0-beta2",
+        "magento/module-catalog": "0.74.0-beta2",
+        "magento/module-checkout": "0.74.0-beta2",
+        "magento/module-theme": "0.74.0-beta2",
+        "magento/module-catalog-inventory": "0.74.0-beta2",
+        "magento/module-rss": "0.74.0-beta2",
+        "magento/module-backend": "0.74.0-beta2",
+        "magento/module-sales": "0.74.0-beta2",
+        "magento/module-grouped-product": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
+        "magento/module-ui": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "suggest": {
-        "magento/module-configurable-product": "0.74.0-beta1",
-        "magento/module-downloadable": "0.74.0-beta1",
-        "magento/module-bundle": "0.74.0-beta1",
-        "magento/module-cookie": "0.74.0-beta1"
+        "magento/module-configurable-product": "0.74.0-beta2",
+        "magento/module-downloadable": "0.74.0-beta2",
+        "magento/module-bundle": "0.74.0-beta2",
+        "magento/module-cookie": "0.74.0-beta2"
     },
     "type": "magento2-module",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js b/app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js
index 733448e77319ba27a2481791aac0217e6846456f..420388ee1b869e529fae674dc50789bb6780b477 100644
--- a/app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js
+++ b/app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js
@@ -39,14 +39,18 @@ define([
                 dataOrigin = $.extend({}, dataOrigin, self._getElementData(element, 1));
                 if ($(element).is(':checked') || $(element).find(':checked').length) {
                     dataToAdd = $.extend({}, dataToAdd, self._getElementData(element));
+                } else {
+                    dataToAdd = dataOrigin;
                 }
             });
             $('[data-action="add-to-wishlist"]').each(function(index, element) {
                 var params = $(element).data('post');
                 if (!params)
                     params = {};
+
                 self._removeExcessiveData(params, dataOrigin, dataToAdd);
                 params.data = $.extend({}, params.data, dataToAdd, {'qty': $(self.options.qtyInfo).val()});
+
                 $(element).data('post', params);
             });
             event.stopPropagation();
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
new file mode 100644
index 0000000000000000000000000000000000000000..af531ff02ac2067b0fc1d51bab40c460070df5a3
--- /dev/null
+++ b/app/design/adminhtml/Magento/backend/Magento_Downloadable/web/css/source/_module.less
@@ -0,0 +1,81 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Variables
+//  _____________________________________________
+
+// @todo ui - rebuilt with common classes for table control and file upload ui component
+
+//
+//  File uploads dynamic control
+//  ---------------------------------------------
+
+.downloadable-form {
+    .col-price,
+    .col-limit,
+    .col-share,
+    .col-sort {
+        width: 1%;
+    }
+    .col-action {
+        width: 1px;
+    }
+    td {
+        &.col-limit {
+            white-space: nowrap;
+        }
+    }
+    .admin__control-table {
+        .admin__control-text {
+            margin-bottom: .5rem;
+            min-width: 6rem;
+        }
+    }
+    .files,
+    .files-wide {
+        .row {
+            margin: .7rem 0;
+            > .admin__control-text {
+                margin-top: .7rem;
+            }
+        }
+        .uploader {
+            margin: .5rem 0;
+        }
+        .fileinput-button {
+            color: @link__color;
+            cursor: pointer;
+            display: inline-block;
+            float: none;
+            margin: .5rem 0;
+            text-decoration: none;
+            &:hover {
+                color: @link__hover__color;
+                text-decoration: underline;
+            }
+        }
+
+    }
+    .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
+    .downloadable-form {
+        display: table-column;
+    }
+}
diff --git a/app/design/adminhtml/Magento/backend/composer.json b/app/design/adminhtml/Magento/backend/composer.json
index fedb7a45696e89600bf4546d45e39c86d5074af0..df9acf8487c6a4c48f51fd7237f17998a2af64bf 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-beta1",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-theme",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/design/adminhtml/Magento/backend/web/css/override.less b/app/design/adminhtml/Magento/backend/web/css/override.less
index 1b6b674ec910a5e84f7ef66f0e1b05e4fae9768b..173fee2cef2b7c89dbb57e20e388ee32706d9451 100644
--- a/app/design/adminhtml/Magento/backend/web/css/override.less
+++ b/app/design/adminhtml/Magento/backend/web/css/override.less
@@ -328,7 +328,7 @@ nav ol {
 .admin__control-file:active + .admin__control-file-label:before,
 .admin__control-file:focus + .admin__control-file-label:before,
 .admin__control-textarea:focus,
-.admin__control-addon [class*='admin__control-']:focus + label:before {
+.admin__control-addon [class*='admin__control-']:focus + [class*='admin__addon-']:before {
   border-color: #007bdb;
   box-shadow: none;
   outline: 0;
@@ -345,6 +345,7 @@ nav ol {
   opacity: .5;
   cursor: not-allowed;
 }
+.admin__fieldset > .admin__field.admin__field-wide[class] > .admin__field-control,
 .address-item-edit-content .admin__field[class] > .admin__field-control,
 .page-layout-admin-login .admin__field[class] > .admin__field-control {
   float: none;
@@ -352,6 +353,7 @@ nav ol {
   text-align: left;
   width: auto;
 }
+.admin__fieldset > .admin__field.admin__field-wide[class]:not(.admin__field-option) > .admin__field-label,
 .address-item-edit-content .admin__field[class]:not(.admin__field-option) > .admin__field-label,
 .page-layout-admin-login .admin__field[class]:not(.admin__field-option) > .admin__field-label {
   text-align: left;
@@ -361,20 +363,58 @@ nav ol {
   margin-bottom: 0.86rem;
   margin-top: -0.14rem;
 }
+.admin__fieldset > .admin__field.admin__field-wide[class]:not(.admin__field-option) > .admin__field-label:before,
 .address-item-edit-content .admin__field[class]:not(.admin__field-option) > .admin__field-label:before,
 .page-layout-admin-login .admin__field[class]:not(.admin__field-option) > .admin__field-label:before {
   display: none;
 }
+.admin__fieldset > .admin__field.admin__field-wide[class]:not(.admin__field-option)._required > .admin__field-label span,
 .address-item-edit-content .admin__field[class]:not(.admin__field-option)._required > .admin__field-label span,
 .page-layout-admin-login .admin__field[class]:not(.admin__field-option)._required > .admin__field-label span {
   padding-left: 1.5rem;
 }
+.admin__fieldset > .admin__field.admin__field-wide[class]:not(.admin__field-option)._required > .admin__field-label span:after,
 .address-item-edit-content .admin__field[class]:not(.admin__field-option)._required > .admin__field-label span:after,
 .page-layout-admin-login .admin__field[class]:not(.admin__field-option)._required > .admin__field-label span:after {
   left: 0;
   margin-left: 30px;
   top: .2rem;
 }
+.admin__control-table-wrapper {
+  max-width: 100%;
+  overflow-x: auto;
+  overflow-y: hidden;
+}
+.admin__control-table {
+  width: 100%;
+}
+.admin__control-table thead {
+  background: none;
+}
+.admin__control-table td,
+.admin__control-table th {
+  background: #efefef;
+  border: 0;
+  border-bottom: 1px solid #ffffff;
+  padding: 1.3rem 2.5rem 1.3rem 0;
+  text-align: left;
+}
+.admin__control-table td:first-child,
+.admin__control-table th:first-child {
+  padding-left: 1.5rem;
+}
+.admin__control-table th {
+  border: 0;
+  vertical-align: bottom;
+  color: #303030;
+  font-size: 1.4rem;
+  font-weight: 600;
+  padding-bottom: 0;
+}
+.admin__control-table th._required span:after {
+  color: #eb5202;
+  content: '*';
+}
 .admin__control-text {
   line-height: 3.3rem;
   width: 100%;
@@ -684,9 +724,11 @@ option:empty {
   color: #808080;
   content: attr(data-config-scope);
   display: inline-block;
-  position: absolute;
+  font-size: 1.2rem;
   left: ~" calc( (100%) * 0.7777777777777778 - 30px )";
+  line-height: 3.2rem;
   margin-left: 60px;
+  position: absolute;
   width: ~" calc( (100%) * 0.2222222222222222 - 30px )";
 }
 .admin__field-control .admin__field[data-config-scope]:nth-child(n+2):before {
@@ -3241,6 +3283,10 @@ fieldset[disabled] .admin__control-text + .ui-datepicker-trigger {
   font-size: 1.7rem;
   transition: color 0.1s linear;
 }
+.admin__menu .submenu-close:hover {
+  cursor: pointer;
+  text-decoration: none;
+}
 .admin__menu .submenu-close:hover:before {
   color: #ffffff;
 }
@@ -4277,6 +4323,108 @@ fieldset[disabled] .admin__control-text + .ui-datepicker-trigger {
   font-size: 2.4rem;
   font-weight: 600;
 }
+.downloadable-form .col-price,
+.downloadable-form .col-limit,
+.downloadable-form .col-share,
+.downloadable-form .col-sort {
+  width: 1%;
+}
+.downloadable-form .col-action {
+  width: 1px;
+}
+.downloadable-form td.col-limit {
+  white-space: nowrap;
+}
+.downloadable-form .admin__control-table .admin__control-text {
+  margin-bottom: .5rem;
+  min-width: 6rem;
+}
+.downloadable-form .files .row,
+.downloadable-form .files-wide .row {
+  margin: .7rem 0;
+}
+.downloadable-form .files .row > .admin__control-text,
+.downloadable-form .files-wide .row > .admin__control-text {
+  margin-top: .7rem;
+}
+.downloadable-form .files .uploader,
+.downloadable-form .files-wide .uploader {
+  margin: .5rem 0;
+}
+.downloadable-form .files .fileinput-button,
+.downloadable-form .files-wide .fileinput-button {
+  color: #007bdb;
+  cursor: pointer;
+  display: inline-block;
+  float: none;
+  margin: .5rem 0;
+  text-decoration: none;
+}
+.downloadable-form .files .fileinput-button:hover,
+.downloadable-form .files-wide .fileinput-button:hover {
+  color: #007bdb;
+  text-decoration: underline;
+}
+.downloadable-form .action-remove {
+  background-image: none;
+  background: none;
+  border: 0;
+  margin: 0;
+  padding: 0;
+  -moz-box-sizing: content-box;
+  box-shadow: none;
+  text-shadow: none;
+  line-height: inherit;
+  font-weight: 400;
+  display: inline-block;
+  text-decoration: none;
+  margin-top: .5rem;
+}
+.downloadable-form .action-remove:focus,
+.downloadable-form .action-remove:active {
+  background: none;
+  border: none;
+}
+.downloadable-form .action-remove:hover {
+  background: none;
+  border: none;
+}
+.downloadable-form .action-remove.disabled,
+.downloadable-form .action-remove[disabled],
+fieldset[disabled] .downloadable-form .action-remove {
+  cursor: not-allowed;
+  pointer-events: none;
+  opacity: 0.5;
+}
+.downloadable-form .action-remove > span {
+  border: 0;
+  clip: rect(0, 0, 0, 0);
+  height: 1px;
+  margin: -1px;
+  overflow: hidden;
+  padding: 0;
+  position: absolute;
+  width: 1px;
+}
+.downloadable-form .action-remove:after {
+  font-family: 'Admin Icons';
+  content: '\e630';
+  font-size: 1.8rem;
+  line-height: 16px;
+  color: #41362f;
+  overflow: hidden;
+  speak: none;
+  font-weight: normal;
+  -webkit-font-smoothing: antialiased;
+  display: inline-block;
+  vertical-align: middle;
+  text-align: center;
+}
+@-moz-document url-prefix() {
+  .downloadable-form {
+    display: table-column;
+  }
+}
 .admin__section-nav {
   padding-bottom: 51px;
 }
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
new file mode 100644
index 0000000000000000000000000000000000000000..50386e2ae44e46440fdb7fe4023e2efa3572e50b
--- /dev/null
+++ b/app/design/adminhtml/Magento/backend/web/css/source/forms/_control-table.less
@@ -0,0 +1,54 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Variables
+//  _____________________________________________
+
+// @todo ui - rebuilt dynamic table control
+
+//
+//  Table control
+//  ---------------------------------------------
+
+.admin__control-table-wrapper {
+    max-width: 100%;
+    overflow-x: auto;
+    overflow-y: hidden;
+}
+
+.admin__control-table {
+    width: 100%;
+    thead {
+        background: none;
+    }
+    td,
+    th {
+        background: @color-white-dark-smoke;
+        border: 0;
+        border-bottom: 1px solid @color-white;
+        padding: 1.3rem 2.5rem 1.3rem 0;
+        text-align: left;
+        &:first-child {
+            padding-left: 1.5rem;
+        }
+    }
+    th {
+        border: 0;
+        vertical-align: bottom;
+        color: @color-very-dark-gray-black;
+        font-size: @font-size__base;
+        font-weight: @font-weight__semibold;
+        padding-bottom: 0;
+        &._required {
+            span {
+                &:after {
+                    color: @field-label__required__color;
+                    content: '*';
+                }
+            }
+        }
+    }
+}
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 987d5f6f39f406ed9f1b5aa1c89be49566bf78b8..8618dc7b82dbffb6800f314e4f65687a91f1bd9b 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
@@ -4,6 +4,7 @@
 //  */
 
 @import (reference) '_extends.less';
+@import '_control-table.less';
 
 //
 //  Variables
@@ -288,7 +289,7 @@ option:empty {
         &[disabled] + [class*='admin__addon-']:before {
             &:extend(.__form-control-styles[disabled]);
         }
-        &:focus + label:before {
+        &:focus + [class*='admin__addon-']:before {
             &:extend(.__form-control-styles:focus);
         }
     }
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 d1a4f148c350ea82dece47f8ad6055f22dfb1bf2..c7218ab8e50904e566c03b6c9591e617c6a5da3f 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
@@ -39,6 +39,9 @@
         padding: 0;
         #mix-grid .row();
 
+        &.admin__field-wide {
+            .extend__field-rows();
+        }
         > .admin__field-control {
             #mix-grid .column(4,9);
         }
@@ -138,9 +141,11 @@
             color: @field-scope__color;
             content: attr(data-config-scope);
             display: inline-block;
-            position: absolute;
+            font-size: @font-size__s;
             left: @_length;
+            line-height: 3.2rem;
             margin-left: 2 * @temp_gutter;
+            position: absolute;
 
             & {
                 #mix-grid .return_length(2,9);
diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/_module.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/_module.less
index d4eee51f4323b613c79ad681dc0c5f1f7dd3ef86..9fd0cc27f492effdb869f17edc22b2f513cbf3de 100644
--- a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/_module.less
+++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/_module.less
@@ -153,6 +153,9 @@
             .fieldset > .field > .label {
                 font-weight: @font-weight__regular;
             }
+            .product-item-name {
+                margin: 0;
+            }
         }
         
         .data.table:extend(.abs-product-options-list all) {
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 0758cf95b23585ce288471dc71f6ad27a3ba9bb7..d8d0b25cb90f10fa092cc096fec35d72c733fce6 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
@@ -4,59 +4,82 @@
 //  */
 
 //
-//    Common
-//--------------------------------------
+//  Variables
+//  ---------------------------------------------
+
+@minicart__border-color: @color-gray80;
+@minicart__padding-horizontal: @indent__base;
+
+//
+//  Common
+//  ---------------------------------------------
 
 & when (@media-common = true) {
 
 //
-//    Minicart
-//--------------------------------------
+//  Minicart
+//  ---------------------------------------------
+
 .block-minicart {
     .items-total {
         float: left;
-        margin: 0 10px;
+        margin: 0 @indent__s;
+        .count {
+            font-weight: @font-weight__bold;
+        }
     }
     .subtotal {
-        margin: 0 10px;
+        margin: 0 @indent__s;
         text-align: right;
+        .label {
+            &:extend(.abs-colon all);
+        }
     }
     .amount {
-        .price-wrapper:first-child .price {
-            font-size: @font-size__l;
-            font-weight: @font-weight__bold;
+        .price-wrapper {
+            &:first-child {
+                .price {
+                    font-size: @font-size__l;
+                    font-weight: @font-weight__bold;
+                }
+            }
         }
     }
     .subtitle {
         display: none;
     }
-    .subtitle.empty {
-        display: block;
-        padding: 30px 0 20px;
-        text-align: center;
-        font-size: 14px;
+    .subtitle {
+        &.empty {
+            display: block;
+            padding: @indent__l 0 @indent__base;
+            text-align: center;
+            font-size: 14px;
+        }
     }
-    .empty.text {
-        text-align: center;
+    .text {
+        &.empty {
+            text-align: center;
+        }
     }
-    > .content > .actions {
-        margin-top: 15px;
-        text-align: center;
-        > .primary {
-            margin: 0 10px 15px;
-            .action.primary {
-                &:extend(.abs-button-l all);
-                display: block;
-                width: 100%;
-                margin-bottom: 15px;
-                &:last-child {
-                    margin-bottom: 0;
+    .block-content {
+        > .actions {
+            margin-top: 15px;
+            text-align: center;
+            > .primary {
+                margin: 0 @indent__s 15px;
+                .action {
+                    &.primary {
+                        &:extend(.abs-button-l all);
+                        display: block;
+                        width: 100%;
+                        margin-bottom: 15px;
+                        &:last-child {
+                            margin-bottom: 0;
+                        }
+                    }
                 }
             }
         }
-        > .secondary {
-            margin: 0 0 15px;
-        }
     }
     .block-category-link,
     .block-product-link,
@@ -84,10 +107,10 @@
     );
     float: right;
     .block-minicart {
-        padding: 25px 20px;
+        .css(padding, 25px @minicart__padding-horizontal);
         right: 0;
         width: 320px;
-        > .title {
+        .block-title {
             display: none;
         }
         &:after {
@@ -104,95 +127,138 @@
         > .primary,
         > .secondary {
             display: inline;
-            margin-right: @indent__s;
-            &:last-child {
-                margin-right: 0;
-            }
         }
     }
-    .action.close {
-        display: none;
-    }
-    .action.showcart {
-        .text {
-            &:extend(.abs-visually-hidden all);
+
+    .action {
+        &.close {
+            width: 40px;
+            height: 40px;
+            top: 0;
+            right: 0;
+            position: absolute;
+            .button-reset();
+            .button-icon(
+                @icon-remove,
+                @_icon-font-size: 32px,
+                @_icon-font-line-height: 32px,
+                @_icon-font-text-hide: true
+            );
         }
-        white-space: nowrap;
-        .counter.qty {
-            &.empty {
-               display: none;
+        &.showcart {
+            .text {
+                &:extend(.abs-visually-hidden all);
+            }
+            white-space: nowrap;
+            .counter.qty {
+                &.empty {
+                   display: none;
+                }
+                .css(background, @active__color);
+                border-radius: 2px;
+                .css(color, @page__background-color);
+                clip: none;
+                display: inline-block;
+                height: 24px;
+                line-height: 24px;
+                min-width: 18px;
+                margin: 3px 0 0;
+                padding: 0 3px;
+                overflow: hidden;
+                text-align: center;
+                white-space: normal;
+            }
+            .counter-label {
+                &:extend(.abs-visually-hidden all);
             }
-            .css(background, @active__color);
-            border-radius: 2px;
-            .css(color, @page__background-color);
-            clip: none;
-            display: inline-block;
-            height: 24px;
-            line-height: 24px;
-            min-width: 18px;
-            margin: 3px 0 0;
-            padding: 0 3px;
-            overflow: hidden;
-            text-align: center;
-            white-space: normal;
-        }
-        .counter-label {
-            &:extend(.abs-visually-hidden all);
         }
     }
+    .minicart-widgets {
+        margin-top: 15px;
+    }
+}
+
+.minicart-items-wrapper {
+    .css(border, 1px solid @minicart__border-color);
+    .css(margin, 0 -@minicart__padding-horizontal);
+    border-left: 0;
+    border-right: 0;
+    overflow-x: auto;
+    padding: 15px;
 }
 
-.minilist {
+.minicart-items {
     .list-reset-styles(0, 0);
     .item {
-        border-top: 1px solid @secondary__color;
-        padding: 20px 0;
-        z-index: 1;
-    }
-    .item > .product {
-        &:extend(.abs-add-clearfix all);
+        &:not(:first-child) {
+            .css(border-top, 1px solid @minicart__border-color);
+        }
+        padding: @indent__base 0;
+        &:first-child {
+            padding-top: 0;
+        }
+        &:last-child {
+            padding-bottom: 0;
+        }
+        > .product {
+            &:extend(.abs-add-clearfix all);
+        }
     }
     .product-image-wrapper {
         &:extend(.abs-reset-image-wrapper all);
     }
-    .product {
-        &-item-photo {
-            float: left;
-        }
-        &-item-name {
-            font-weight: @font-weight__regular;
-            margin-top: 0;
-            a {
-                .css(color, @link__color);
-            }
+    .product-item-pricing {
+        .label {
+            display: inline-block;
+            width: 4.5rem;
+         }
+    }
+    .price-minicart {
+        margin-bottom: @indent__xs;
+    }
+    .product-item-photo {
+        float: left;
+    }
+    .product-item-name {
+        font-weight: @font-weight__regular;
+        margin: 0 0 @indent__s;
+        a {
+            .css(color, @link__color);
         }
-        &-item-details {
-            padding-left: 88px;
-            .price {
-                font-weight: @font-weight__bold;
-            }
+    }
+    .product-item-details {
+        padding-left: 88px;
+        .price {
+            font-weight: @font-weight__bold;
         }
-        &.pricing {
-            margin-top: 3px;
-        }
-        &.options {
-            .tooltip.toggle {
-                .icon-font(
-                    @icon-down,
-                    @_icon-font-size: 28px,
-                    @_icon-font-line-height: 28px,
-                    @_icon-font-text-hide: true,
-                    @_icon-font-margin: -3px 0 0 7px,
-                    @_icon-font-position: after
-                );
-            }
+    }
+    .product.options {
+        .tooltip.toggle {
+            .icon-font(
+                @icon-down,
+                @_icon-font-size: 28px,
+                @_icon-font-line-height: 28px,
+                @_icon-font-text-hide: true,
+                @_icon-font-margin: -3px 0 0 7px,
+                @_icon-font-position: after
+            );
         }
     }
-    .details-qty {
-        .label:after {
-            content: ":";
+    .details-qty,
+    .price-minicart {
+        .label {
+            &:extend(.abs-colon all);
         }
     }
+    .item-qty {
+        width: 40px;
+        text-align: center;
+        margin-right: @indent__s;
+    }
+    .item-update {
+        vertical-align: top;
+        .font-size(11);
+    }
     .action {
          &.edit,
          &.delete {
@@ -217,8 +283,9 @@
 }
 
 //
-//    Mobile
-//--------------------------------------
+//  Mobile
+//  ---------------------------------------------
+
 .media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__xs) {
     .minicart-wrapper .block-minicart {
         width: 290px;
@@ -232,8 +299,9 @@
 }
 
 //
-//    Desktop
-//--------------------------------------
+//  Desktop
+//  ---------------------------------------------
+
 .media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
     .minicart-wrapper {
         margin-left: 13px;
diff --git a/app/design/frontend/Magento/blank/composer.json b/app/design/frontend/Magento/blank/composer.json
index 4e238d267afb5e499c9f49936fa95724e4c5232f..c0d99f390e24c49932d3a13c943004b7259241d2 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-beta1",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-theme",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "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 655c892d6dc9fff3b743a6ef799a617fd02c9a9d..3a65f3be3f3055aca8770b2ec9b94145206a63fc 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
@@ -4,58 +4,83 @@
 //  */
 
 //
-//    Common
-//--------------------------------------
+//  Variables
+//  ---------------------------------------------
+
+@minicart__border-color: @color-gray80;
+@minicart__padding-horizontal: @indent__base;
+
+//
+//  Common
+//  ---------------------------------------------
 
 & when (@media-common = true) {
 
 //
-//    Minicart
-//--------------------------------------
+//  Minicart
+//  ---------------------------------------------
+
 .block-minicart {
     .items-total {
         float: left;
-        margin: 0 10px;
+        margin: 0 @indent__s;
+        .count {
+            font-weight: @font-weight__bold;
+        }
     }
     .subtotal {
-        margin: 0 10px;
+        margin: 0 @indent__s;
         text-align: right;
+        .label {
+            &:extend(.abs-colon all);
+        }
     }
     .amount {
-        .price-wrapper:first-child .price {
-            font-size: @font-size__l;
-            font-weight: @font-weight__bold;
+        .price-wrapper {
+            &:first-child {
+                .price {
+                    font-size: @font-size__l;
+                    font-weight: @font-weight__bold;
+                }
+            }
         }
     }
     .subtitle {
         display: none;
     }
-    .subtitle.empty {
-        display: block;
-        padding: 30px 0 20px;
-        text-align: center;
-        font-size: 14px;
-    }
-    .empty.text {
-        text-align: center;
-    }
-    > .content > .actions {
-        margin-top: 15px;
-        > .secondary {
-            margin: 15px 0;
+    .subtitle {
+        &.empty {
+            display: block;
+            padding: @indent__l 0 @indent__base;
             text-align: center;
+            font-size: 14px;
         }
-        > .primary {
-            margin: 0 10px;
-            .action.primary {
-                &:extend(.abs-button-l all);
-                display: block;
-                width: 100%;
-            }
+    }
+    .text {
+        &.empty {
+            text-align: center;
         }
-        .paypal-logo {
+    }
+    .block-content {
+        > .actions {
             margin-top: 15px;
-            text-align: center;
+            > .secondary {
+                text-align: center;
+            }
+            > .primary {
+                margin: 0 @indent__s 15px;
+                .action {
+                    &.primary {
+                        &:extend(.abs-button-l all);
+                        display: block;
+                        width: 100%;
+                    }
+                }
+            }
+            .paypal-logo {
+                margin-top: 15px;
+                text-align: center;
+            }
         }
     }
     .block-category-link,
@@ -84,10 +109,10 @@
     );
     float: right;
     .block-minicart {
-        padding: 25px 20px;
+        .css(padding, 25px @minicart__padding-horizontal);
         right: 0;
         width: 320px;
-        > .title {
+        .block-title {
             display: none;
         }
         &:after {
@@ -99,77 +124,123 @@
             right: 26px;
         }
     }
-    .product.actions {
-        float: right;
-        margin: -24px 0 0;
-        > .primary,
-        > .secondary {
-            display: inline;
+    .product {
+        .actions {
+            float: right;
+            margin: -24px 0 0;
+            > .primary,
+            > .secondary {
+                display: inline;
+                &:not(:last-child) {
+                    margin-right: 15px;
+                }
+            }
         }
     }
-    .action.close {
-        display: none;
-    }
-    .action.showcart {
-        .text {
-            &:extend(.abs-visually-hidden all);
+    .action {
+        &.close {
+            width: 40px;
+            height: 40px;
+            top: 0;
+            right: 0;
+            position: absolute;
+            .button-reset();
+            .button-icon(
+                @icon-remove,
+                @_icon-font-color: @minicart-icons-color,
+                @_icon-font-size: 16px,
+                @_icon-font-line-height: 16px,
+                @_icon-font-text-hide: true
+            );
         }
-        white-space: nowrap;
-        .counter.qty {
-            &.empty {
-               display: none;
+        &.showcart {
+            .text {
+                &:extend(.abs-visually-hidden all);
+            }
+            white-space: nowrap;
+            .counter.qty {
+                &.empty {
+                   display: none;
+                }
+                .css(background, @active__color);
+                border-radius: 2px;
+                .css(color, @page__background-color);
+                clip: none;
+                display: inline-block;
+                height: 24px;
+                line-height: 24px;
+                min-width: 18px;
+                margin: 3px 0 0;
+                padding: 0 3px;
+                overflow: hidden;
+                text-align: center;
+                white-space: normal;
+            }
+            .counter-label {
+                &:extend(.abs-visually-hidden all);
             }
-            .css(background, @active__color);
-            border-radius: 2px;
-            .css(color, @page__background-color);
-            clip: none;
-            display: inline-block;
-            height: 24px;
-            line-height: 24px;
-            min-width: 18px;
-            margin: 3px 0 0;
-            padding: 0 3px;
-            overflow: hidden;
-            text-align: center;
-            white-space: normal;
-        }
-        .counter-label {
-            &:extend(.abs-visually-hidden all);
         }
     }
+    .minicart-widgets {
+        margin-top: 15px;
+    }
 }
 
-.minilist {
+.minicart-items-wrapper {
+    .css(border, 1px solid @minicart__border-color);
+    .css(margin, 0 -@minicart__padding-horizontal);
+    border-left: 0;
+    border-right: 0;
+    overflow-x: auto;
+    padding: 15px;
+}
+
+.minicart-items {
     .list-reset-styles(0, 0);
     .item {
-        border-top: 1px solid @secondary__color;
-        padding: 20px 0;
-        z-index: 1;
-    }
-
-    .item > .product {
-        &:extend(.abs-add-clearfix all);
+        &:not(:first-child) {
+            .css(border-top, 1px solid @minicart__border-color);
+        }
+        padding: @indent__base 0;
+        &:first-child {
+            padding-top: 0;
+        }
+        &:last-child {
+            padding-bottom: 0;
+        }
+        > .product {
+            &:extend(.abs-add-clearfix all);
+        }
     }
     .product-image-wrapper {
         &:extend(.abs-reset-image-wrapper all);
     }
-    .product {
-        &-item-photo {
-            float: left;
+    .product-item-pricing {
+        .label {
+            display: inline-block;
+            width: 4.5rem;
         }
-        &-item-name {
-            font-weight: @font-weight__regular;
-            margin-top: 0;
-            a {
-                .css(color, @link__color);
-            }
+    }
+    .price-minicart {
+        margin-bottom: @indent__xs;
+    }
+    .product-item-photo {
+        float: left;
+    }
+    .product-item-name {
+        font-weight: @font-weight__regular;
+        margin: 0 0 @indent__s;
+        a {
+            .css(color, @link__color);
         }
-        &-item-details {
-            padding-left: 88px;
-            .price {
-                font-weight: @font-weight__bold;
-            }
+    }
+    .product-item-details {
+        padding-left: 88px;
+        .price {
+            font-weight: @font-weight__bold;
         }
+    }
+    .product {
         .toggle {
             &:extend(.abs-toggling-title all);
             &:after {
@@ -179,7 +250,6 @@
             }
             border: 0;
             padding: 0 @indent__xl @indent__xs 0;
-
         }
         .active {
             > .toggle {
@@ -205,12 +275,21 @@
             }
         }
     }
-    .details-qty {
-        .label:after {
-            content: ":";
+    .details-qty,
+    .price-minicart {
+        .label {
+            &:extend(.abs-colon all);
         }
     }
-
+    .item-qty {
+        width: 40px;
+        text-align: center;
+        margin-right: @indent__s;
+    }
+    .update-cart-item {
+        vertical-align: top;
+        .font-size(11);
+    }
     .action {
         &.edit,
         &.delete {
@@ -235,8 +314,9 @@
 }
 
 //
-//    Mobile
-//--------------------------------------
+//  Mobile
+//  ---------------------------------------------
+
 .media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__xs) {
     .minicart-wrapper .block-minicart {
         width: 290px;
@@ -249,9 +329,11 @@
     }
 }
 
+
 //
-//    Desktop
-//--------------------------------------
+//  Desktop
+//  ---------------------------------------------
+
 .media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
     .minicart-wrapper {
         margin-left: 13px;
diff --git a/app/design/frontend/Magento/luma/composer.json b/app/design/frontend/Magento/luma/composer.json
index 6b06d6914a0feb010b8903bb2de4e8173a221290..7c4a0c1ab12379cec4f85df3b34bbb76efc2761e 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-beta1",
-        "magento/framework": "0.74.0-beta1",
+        "magento/theme-frontend-blank": "0.74.0-beta2",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-theme",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/i18n/magento/de_de/composer.json b/app/i18n/magento/de_de/composer.json
index 4405c15797e07f2c9742718c495e0a63d8f1f9c9..3489faab6623a1096e4bce93c145e2db131f690b 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-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
     ],
     "require": {
-        "magento/framework": "0.74.0-beta1",
+        "magento/framework": "0.74.0-beta2",
         "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 e60b68a5e769d9efcac3f03e691b823a27d4e7a7..03f6fae4438e0e91e923c22312afe699e0df225e 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-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
     ],
     "require": {
-        "magento/framework": "0.74.0-beta1",
+        "magento/framework": "0.74.0-beta2",
         "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 b0583142f7b14854b893ec53aa810bce785ba0c6..7b80bcc0f53436a9be865f48c0891a3c44582e39 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-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
     ],
     "require": {
-        "magento/framework": "0.74.0-beta1",
+        "magento/framework": "0.74.0-beta2",
         "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 f265ca1a3cd3288553ca3a0d68999f15da4ac8de..56a2643eef7abb99e163df1e69543150cf0543e2 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-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
     ],
     "require": {
-        "magento/framework": "0.74.0-beta1",
+        "magento/framework": "0.74.0-beta2",
         "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 aefcd710853b420915589d47411fbf6551d5a2a2..700e4cab06051364f4e5306a08f2ec6a0856b0af 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-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
     ],
     "require": {
-        "magento/framework": "0.74.0-beta1",
+        "magento/framework": "0.74.0-beta2",
         "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 916daafa18259faa6ede5a5c45bca6d291a31c00..d6a8fb0b185001e89b576dfbf7d591f0829f39ea 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-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
     ],
     "require": {
-        "magento/framework": "0.74.0-beta1",
+        "magento/framework": "0.74.0-beta2",
         "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 4075918bcb42bcb376461e9b9ab7aac37209131a..5d4c631ba8fb2d6c41cdd3751ddd21050058c2b1 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-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
     ],
     "require": {
-        "magento/framework": "0.74.0-beta1",
+        "magento/framework": "0.74.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-language",
diff --git a/composer.json b/composer.json
index c5b5d17eb8badb72eddfa355623f63ef51cad1ed..a0313c405b16650680d1ddecf2588bba16416653 100644
--- a/composer.json
+++ b/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/project-community-edition",
     "description": "Magento project (Community Edition)",
     "type": "project",
-    "version": "0.74.0-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/composer.lock b/composer.lock
index e941f4cfd37e10882f8cee92343b703f49202ceb..00989580f30f29375e5f2fe27c8a2668836854a0 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": "d5894e8331088f5a3432dec4ee28ace4",
+    "hash": "2540c30fb9f7ddea359e3a1f9bc67097",
     "packages": [
         {
             "name": "composer/composer",
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeRepositoryTest.php
index 7bb1fccd68818c9804f508c9c9f4a445527c9257..c57d73035b1a5f558741437393832e9d26f77348 100644
--- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeRepositoryTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeRepositoryTest.php
@@ -111,7 +111,7 @@ class ProductAttributeRepositoryTest extends \Magento\TestFramework\TestCase\Web
 
         $attributeData = [
             'attribute' => [
-                'attribute_code' => $attributeCode,
+                'attribute_id' => $attribute['attribute_id'],
                 'frontend_labels' => [
                     ['store_id' => 0, 'label' => 'front_lbl_new'],
                 ],
@@ -123,7 +123,7 @@ class ProductAttributeRepositoryTest extends \Magento\TestFramework\TestCase\Web
 
         $serviceInfo = [
             'rest' => [
-                'resourcePath' => self::RESOURCE_PATH . '/' . $attribute['attribute_id'],
+                'resourcePath' => self::RESOURCE_PATH . '/' . $attributeCode,
                 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_PUT,
             ],
             'soap' => [
@@ -134,7 +134,7 @@ class ProductAttributeRepositoryTest extends \Magento\TestFramework\TestCase\Web
         ];
 
         if (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) {
-            $attributeData['attribute']['attributeId'] = $attribute['attribute_id'];
+            $attributeData['attribute']['attributeCode'] = $attributeCode;
         }
         $result = $this->_webApiCall($serviceInfo, $attributeData);
 
diff --git a/dev/tests/functional/bootstrap.php b/dev/tests/functional/bootstrap.php
index b661b84d1ceccd96c2b4ceb28ee3ee9ff0d31dc2..5a4f9a7c490dee281665493f4eea214c77d2d4ca 100644
--- a/dev/tests/functional/bootstrap.php
+++ b/dev/tests/functional/bootstrap.php
@@ -4,7 +4,6 @@
  * See COPYING.txt for license details.
  */
 
-session_start();
 defined('MTF_BOOT_FILE') || define('MTF_BOOT_FILE', __FILE__);
 defined('MTF_BP') || define('MTF_BP', str_replace('\\', '/', (__DIR__)));
 require_once __DIR__ . '/../../../app/bootstrap.php';
diff --git a/dev/tests/functional/composer.json b/dev/tests/functional/composer.json
index 256e8f34c43778f4f2ff4f4feabb4b5c20547524..41482866c1b241dbf0feb2c100d029ed51e11d68 100644
--- a/dev/tests/functional/composer.json
+++ b/dev/tests/functional/composer.json
@@ -1,6 +1,6 @@
 {
     "require": {
-        "magento/mtf": "1.0.0-rc20",
+        "magento/mtf": "1.0.0-rc21",
         "php": "~5.5.0|~5.6.0",
         "phpunit/phpunit": "4.1.0",
         "phpunit/phpunit-selenium": ">=1.2",
diff --git a/dev/tests/functional/lib/Magento/Mtf/Util/Protocol/CurlTransport/BackendDecorator.php b/dev/tests/functional/lib/Magento/Mtf/Util/Protocol/CurlTransport/BackendDecorator.php
index c4b2a9d7f85cc2649fbe9c95f71063f5c9de7115..ff02e15272bd9dc13e0a1c1f58e445024d06c469 100644
--- a/dev/tests/functional/lib/Magento/Mtf/Util/Protocol/CurlTransport/BackendDecorator.php
+++ b/dev/tests/functional/lib/Magento/Mtf/Util/Protocol/CurlTransport/BackendDecorator.php
@@ -6,7 +6,7 @@
 
 namespace Magento\Mtf\Util\Protocol\CurlTransport;
 
-use Magento\Mtf\Config;
+use Magento\Mtf\Config\DataInterface;
 use Magento\Mtf\Util\Protocol\CurlInterface;
 use Magento\Mtf\Util\Protocol\CurlTransport;
 
@@ -40,7 +40,7 @@ class BackendDecorator implements CurlInterface
     /**
      * System config
      *
-     * @var Config
+     * @var DataInterface
      */
     protected $configuration;
 
@@ -48,9 +48,9 @@ class BackendDecorator implements CurlInterface
      * Constructor
      *
      * @param CurlTransport $transport
-     * @param Config $configuration
+     * @param DataInterface $configuration
      */
-    public function __construct(CurlTransport $transport, Config $configuration)
+    public function __construct(CurlTransport $transport, DataInterface $configuration)
     {
         $this->transport = $transport;
         $this->configuration = $configuration;
@@ -65,11 +65,10 @@ class BackendDecorator implements CurlInterface
      */
     protected function authorize()
     {
-        $url = $_ENV['app_backend_url'] .
-            $this->configuration->getParameter('application/backendLoginUrl');
+        $url = $_ENV['app_backend_url'] . $this->configuration->get('application/0/backendLoginUrl/0/value');
         $data = [
-            'login[username]' => $this->configuration->getParameter('application/backendLogin'),
-            'login[password]' => $this->configuration->getParameter('application/backendPassword'),
+            'login[username]' => $this->configuration->get('application/0/backendLogin/0/value'),
+            'login[password]' => $this->configuration->get('application/0/backendPassword/0/value'),
         ];
         $this->transport->write(CurlInterface::POST, $url, '1.0', [], $data);
         $response = $this->read();
diff --git a/dev/tests/functional/phpunit.xml.dist b/dev/tests/functional/phpunit.xml.dist
index 06b2ee9b0603d8fd6e602011e34ddbf2b131c00f..f99b813aa1073903e64d1495ea27d55440cd3547 100755
--- a/dev/tests/functional/phpunit.xml.dist
+++ b/dev/tests/functional/phpunit.xml.dist
@@ -26,7 +26,6 @@
             </arguments>
         </listener>
         <listener class="Magento\Mtf\System\Event\StateListener" />
-        <listener class="Magento\Mtf\System\JUnit"/>
     </listeners>
 
     <php>
@@ -37,7 +36,6 @@
         <env name="log_directory" value="var/log" />
         <env name="events_preset" value="base" />
         <env name="module_whitelist" value="Magento_Install,Magento_Core" />
-        <env name="report_file_name" value="test-cases-report.xml"/>
         <env name="basedir" value="var/log" />
         <env name="credentials_file_path" value="./credentials.xml.dist" />
     </php>
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Fixture/Admin/SuperAdmin.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Fixture/Admin/SuperAdmin.php
index fd1a66d884fbecb34528b214b112ad0afa7741ca..3d18543896556fd8cd86604348c2ce5da1650900 100644
--- a/dev/tests/functional/tests/app/Magento/Backend/Test/Fixture/Admin/SuperAdmin.php
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Fixture/Admin/SuperAdmin.php
@@ -22,10 +22,10 @@ class SuperAdmin extends DataFixture
         $this->_data = [
             'fields' => [
                 'username' => [
-                    'value' => $this->_configuration->getParameter('application/backendLogin'),
+                    'value' => $this->_configuration->get('application/0/backendLogin/0/value'),
                 ],
                 'password' => [
-                    'value' => $this->_configuration->getParameter('application/backendPassword'),
+                    'value' => $this->_configuration->get('application/0/backendPassword/0/value'),
                 ],
             ],
         ];
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Fixture/GlobalSearch.xml b/dev/tests/functional/tests/app/Magento/Backend/Test/Fixture/GlobalSearch.xml
index e40e21c4fca28b00ba54d39c6bd30bd66f20f241..7b1c3f2aeac1d2d0f6e9be43c3dab50609066d32 100644
--- a/dev/tests/functional/tests/app/Magento/Backend/Test/Fixture/GlobalSearch.xml
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Fixture/GlobalSearch.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
   <fixture name="globalSearch" module="Magento_Backend" class="Magento\Backend\Test\Fixture\GlobalSearch">
     <dataset name="default">
         <field name="query" xsi:type="string">catalogProductSimple::default::name</field>
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Handler/Extractor.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Handler/Extractor.php
index 967d142da277c2cb30be1ff7927363b03caf93a5..3df57e717b29304175d27a3fc9c66f4cb3cd9456 100755
--- a/dev/tests/functional/tests/app/Magento/Backend/Test/Handler/Extractor.php
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Handler/Extractor.php
@@ -7,7 +7,6 @@
 
 namespace Magento\Backend\Test\Handler;
 
-use Magento\Mtf\Config;
 use Magento\Mtf\Util\Protocol\CurlInterface;
 use Magento\Mtf\Util\Protocol\CurlTransport;
 use Magento\Mtf\Util\Protocol\CurlTransport\BackendDecorator;
@@ -62,8 +61,8 @@ class Extractor
      */
     public function getData()
     {
-        /** @var \Magento\Mtf\Config $config */
-        $config = \Magento\Mtf\ObjectManagerFactory::getObjectManager()->get('Magento\Mtf\Config');
+        /** @var \Magento\Mtf\Config\DataInterface $config */
+        $config = \Magento\Mtf\ObjectManagerFactory::getObjectManager()->get('Magento\Mtf\Config\DataInterface');
         $url = $_ENV['app_backend_url'] . $this->url;
         $curl = new BackendDecorator(new CurlTransport(), $config);
         $curl->addOption(CURLOPT_HEADER, 1);
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 02f5655d35fa05611ada2a097718106a14bda254..3c258a22f9d864ecfb636d2ebe46c65262f56740 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
@@ -39,7 +39,7 @@ class AdminAuthLogin extends Page
      *
      * @var string
      */
-    protected $messagesBlock = '#messages .messages';
+    protected $messagesBlock = '.messages .message';
 
     /**
      * Constructor.
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/BundleProduct.xml b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/BundleProduct.xml
index 6b345b542bb84bbdcfcfe6bd9ced8353fa68228f..b9f96e1cb55a7ff19150c846a5424c9b8a2c4414 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/BundleProduct.xml
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/BundleProduct.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
   <fixture name="bundleProduct" module="Magento_Bundle" type="eav" entity_type="catalog_product" product_type="bundle" collection="Magento\Catalog\Model\Resource\Product\Collection" identifier="sku" repository_class="Magento\Bundle\Test\Repository\BundleProduct" handler_interface="Magento\Bundle\Test\Handler\BundleProduct\BundleProductInterface" class="Magento\Bundle\Test\Fixture\BundleProduct">
     <dataset name="default">
         <field name="name" xsi:type="string">BundleProduct %isolation%</field>
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Handler/BundleProduct/Curl.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Handler/BundleProduct/Curl.php
index cbd47bd232e4ea5fd3f79bc667b3f73084b37eb2..6eeb06506c9cd342adeea36c2426cb964edaf6de 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Handler/BundleProduct/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Handler/BundleProduct/Curl.php
@@ -9,7 +9,8 @@ namespace Magento\Bundle\Test\Handler\BundleProduct;
 use Magento\Bundle\Test\Fixture\BundleProduct;
 use Magento\Catalog\Test\Handler\CatalogProductSimple\Curl as ProductCurl;
 use Magento\Mtf\Fixture\FixtureInterface;
-use Magento\Mtf\Config;
+use Magento\Mtf\Config\DataInterface;
+use Magento\Mtf\System\Event\EventManagerInterface;
 
 /**
  * Create new bundle product via curl.
@@ -25,11 +26,12 @@ class Curl extends ProductCurl implements BundleProductInterface
 
     /**
      * @constructor
-     * @param Config $configuration
+     * @param DataInterface $configuration
+     * @param EventManagerInterface $eventManager
      */
-    public function __construct(Config $configuration)
+    public function __construct(DataInterface $configuration, EventManagerInterface $eventManager)
     {
-        parent::__construct($configuration);
+        parent::__construct($configuration, $eventManager);
 
         $this->mappingData += [
             'selection_can_change_qty' => [
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 4a55128100962e9f84fab2be865d4439cf1678e5..08c75424ad8c707c1355f16833eaf8e28f17546f 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
@@ -43,14 +43,14 @@ class ListProduct extends Block
      *
      * @var string
      */
-    protected $productDetailsSelector = '//*[contains(@class, "product details") and .//*[text()="%s"]]';
+    protected $productDetailsSelector = '//*[contains(@class, "product details") and .//*[contains(text(),"%s")]]';
 
     /**
      * Product name.
      *
      * @var string
      */
-    protected $productTitle = './/*[@class="product name product-item-name"]/a[text()="%s"]';
+    protected $productTitle = './/*[@class="product name product-item-name"]/a[contains(text(),"%s")]';
 
     /**
      * Click for Price link on category page.
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogAttributeSet.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogAttributeSet.xml
index e30dafaff1c5a7eb1c90af347f40e670e8fe4b6e..20c3c831f6e627016d8ff8f74fff0f8d26485017 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogAttributeSet.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogAttributeSet.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
     <fixture name="catalogAttributeSet" module="Magento_Catalog" type="flat" entity_type="eav_attribute_set" collection="Magento\Catalog\Model\Resource\Product\Link\Product\Collection" repository_class="Magento\Catalog\Test\Repository\CatalogAttributeSet" handler_interface="Magento\Catalog\Test\Handler\CatalogAttributeSet\CatalogAttributeSetInterface" class="Magento\Catalog\Test\Fixture\CatalogAttributeSet">
     <dataset name="default">
         <field name="attribute_set_name" xsi:type="string">Default_attribute_set_%isolation%</field>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductAttribute.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductAttribute.xml
index 0a33bf96c60d635bad7e1cff10fa6da4f6f646b4..1e99a0752d4e407a6dfac02c519cf83d9f6ded54 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductAttribute.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductAttribute.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
   <fixture name="catalogProductAttribute" module="Magento_Catalog" type="composite" collection="Magento\Catalog\Model\Resource\Attribute" repository_class="Magento\Catalog\Test\Repository\CatalogProductAttribute" handler_interface="Magento\Catalog\Test\Handler\CatalogProductAttribute\CatalogProductAttributeInterface" class="Magento\Catalog\Test\Fixture\CatalogProductAttribute">
     <dataset name="default">
         <field name="frontend_label" xsi:type="string">attribute_label%isolation%</field>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.xml
index 1815359930d5d7827cd2ce06681b12c7da7f60a0..59bc10f7eeecdc84fcec704f0166306b479f60f5 100755
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
   <fixture name="catalogProductSimple" module="Magento_Catalog" type="eav" entity_type="catalog_product" product_type="simple" collection="Magento\Catalog\Model\Resource\Product\Collection" identifier="sku" repository_class="Magento\Catalog\Test\Repository\CatalogProductSimple" handler_interface="Magento\Catalog\Test\Handler\CatalogProductSimple\CatalogProductSimpleInterface" class="Magento\Catalog\Test\Fixture\CatalogProductSimple">
     <dataset name="default">
         <field name="name" xsi:type="string">Test simple product %isolation%</field>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/TaxClass.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/TaxClass.php
index 8ca245b0c1607022eb2da61b21028f5efd077404..7bc605d82acca354327d119a88a570982aec88a4 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/TaxClass.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/TaxClass.php
@@ -9,7 +9,6 @@ namespace Magento\Catalog\Test\Fixture\CatalogProductSimple;
 use Magento\Tax\Test\Fixture\TaxClass as FixtureTaxClass;
 use Magento\Mtf\Fixture\FixtureFactory;
 use Magento\Mtf\Fixture\FixtureInterface;
-use Magento\Mtf\Config;
 use Magento\Mtf\Util\Protocol\CurlInterface;
 use Magento\Mtf\Util\Protocol\CurlTransport;
 use Magento\Mtf\Util\Protocol\CurlTransport\BackendDecorator;
@@ -89,7 +88,7 @@ class TaxClass implements FixtureInterface
     protected function setTaxClassId($taxClassName)
     {
         $url = $_ENV['app_backend_url'] . 'tax/rule/new/';
-        $config = \Magento\Mtf\ObjectManagerFactory::getObjectManager()->create('Magento\Mtf\Config');
+        $config = \Magento\Mtf\ObjectManagerFactory::getObjectManager()->create('Magento\Mtf\Config\DataInterface');
         $curl = new BackendDecorator(new CurlTransport(), $config);
         $curl->addOption(CURLOPT_HEADER, 1);
         $curl->write(CurlInterface::POST, $url, '1.0', [], []);
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductVirtual.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductVirtual.xml
index fd551f743f338cc4b096d7085084070cc2a144a5..158e62ce41f722ec50d060011baf95da903f15f9 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductVirtual.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductVirtual.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
   <fixture name="catalogProductVirtual" module="Magento_Catalog" type="eav" entity_type="catalog_product" product_type="virtual" collection="Magento\Catalog\Model\Resource\Product\Collection" identifier="sku" repository_class="Magento\Catalog\Test\Repository\CatalogProductVirtual" handler_interface="Magento\Catalog\Test\Handler\CatalogProductVirtual\CatalogProductVirtualInterface" class="Magento\Catalog\Test\Fixture\CatalogProductVirtual">
     <dataset name="default">
         <field name="name" xsi:type="string">Test virtual product %isolation%</field>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/Category.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/Category.xml
index 663a249b5da66e367bd8b0a953e622653aaa065e..9ea63b5e3616f573ba5385f127969f81779f8210 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/Category.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/Category.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
   <fixture name="category" module="Magento_Catalog" type="eav" entity_type="catalog_category_entity" collection="Magento\Catalog\Model\Resource\Category\Collection" repository_class="Magento\Catalog\Test\Repository\Category" handler_interface="Magento\Catalog\Test\Handler\Category\CategoryInterface" class="Magento\Catalog\Test\Fixture\Category">
     <dataset name="default">
         <field name="name" xsi:type="string">Category%isolation%</field>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogAttributeSet/Curl.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogAttributeSet/Curl.php
index 8c7e5905afb7339488389ab62caeedc929ecd784..b5f8585e01fe459e6f67529a6683c2c3281ddba8 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogAttributeSet/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogAttributeSet/Curl.php
@@ -9,7 +9,6 @@ namespace Magento\Catalog\Test\Handler\CatalogAttributeSet;
 use Magento\Catalog\Test\Fixture\CatalogAttributeSet;
 use Magento\Mtf\Fixture\FixtureInterface;
 use Magento\Mtf\Handler\Curl as AbstractCurl;
-use Magento\Mtf\Config;
 use Magento\Mtf\Util\Protocol\CurlInterface;
 use Magento\Mtf\Util\Protocol\CurlTransport;
 use Magento\Mtf\Util\Protocol\CurlTransport\BackendDecorator;
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Curl.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Curl.php
index 123ef506c991ee390aedc790ce8f2e58fd8224e1..1e7ec99e39fe2fec29869f7faa934711cab988b0 100755
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Curl.php
@@ -405,7 +405,8 @@ class Curl extends AbstractCurl implements CatalogProductSimpleInterface
         $curl->close();
 
         if (!strpos($response, 'data-ui-id="messages-message-success"')) {
-            throw new \Exception("Product creation by curl handler was not successful! Response: $response");
+            $this->_eventManager->dispatchEvent(['curl_failed'], [$response]);
+            throw new \Exception('Product creation by curl handler was not successful!');
         }
 
         return $this->parseResponse($response);
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 9770e6726048c6139631ba6022d8801484e1c108..e684946a46f47f152fdd1d4373f31a31b1142dd4 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
@@ -8,7 +8,6 @@ namespace Magento\Catalog\Test\Handler\Category;
 
 use Magento\Mtf\Fixture\FixtureInterface;
 use Magento\Mtf\Handler\Curl as AbstractCurl;
-use Magento\Mtf\Config;
 use Magento\Mtf\Util\Protocol\CurlInterface;
 use Magento\Mtf\Util\Protocol\CurlTransport;
 use Magento\Mtf\Util\Protocol\CurlTransport\BackendDecorator;
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/Curl/CreateProductAttribute.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/Curl/CreateProductAttribute.php
index 6353c542d857e57541d700b0d9ad45d17e3a7a35..632de082cfe61df3dcfddd9ccf1359a9d3581638 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/Curl/CreateProductAttribute.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/Curl/CreateProductAttribute.php
@@ -9,7 +9,6 @@ namespace Magento\Catalog\Test\Handler\Curl;
 use Magento\Catalog\Test\Fixture\ProductAttribute;
 use Magento\Mtf\Fixture\FixtureInterface;
 use Magento\Mtf\Handler\Curl;
-use Magento\Mtf\Config;
 use Magento\Mtf\Util\Protocol\CurlInterface;
 use Magento\Mtf\Util\Protocol\CurlTransport;
 use Magento\Mtf\Util\Protocol\CurlTransport\BackendDecorator;
diff --git a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Fixture/CatalogRule.xml b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Fixture/CatalogRule.xml
index 073335f8ab0ff6b5aa04801c6d30489a51ac9ba5..88c2147c46a54c83273e0ebe386af6f4e3bf39a9 100644
--- a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Fixture/CatalogRule.xml
+++ b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Fixture/CatalogRule.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
   <fixture name="catalogRule" module="Magento_CatalogRule" type="eav" entity_type="catalog_rule" collection="Magento\CatalogRule\Model\Resource\Rule\Product\Price\Collection" repository_class="Magento\CatalogRule\Test\Repository\CatalogRule" handler_interface="Magento\CatalogRule\Test\Handler\CatalogRule\CatalogRuleInterface" class="Magento\CatalogRule\Test\Fixture\CatalogRule">
     <dataset name="default">
         <field name="name" xsi:type="string">CatalogPriceRule %isolation%</field>
diff --git a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Handler/CatalogRule/Curl.php b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Handler/CatalogRule/Curl.php
index 1c6d9a58f87105e992b2e1572477ef0085f32b6c..43089928c2c50da39f1c589cdb05a31ba4b6dc96 100644
--- a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Handler/CatalogRule/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Handler/CatalogRule/Curl.php
@@ -9,7 +9,6 @@ namespace Magento\CatalogRule\Test\Handler\CatalogRule;
 use Magento\Backend\Test\Handler\Conditions;
 use Magento\CatalogRule\Test\Handler\CatalogRule;
 use Magento\Mtf\Fixture\FixtureInterface;
-use Magento\Mtf\Config;
 use Magento\Mtf\Util\Protocol\CurlInterface;
 use Magento\Mtf\Util\Protocol\CurlTransport;
 use Magento\Mtf\Util\Protocol\CurlTransport\BackendDecorator;
diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Fixture/CatalogSearchQuery.xml b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Fixture/CatalogSearchQuery.xml
index 59b4b4ee904fa40efd1b4a71bc46a437543e8d74..940729a21995ef1db6dd3a718c6c92293ddbe299 100644
--- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Fixture/CatalogSearchQuery.xml
+++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Fixture/CatalogSearchQuery.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
   <fixture name="catalogSearchQuery" module="Magento_CatalogSearch" type="flat" entity_type="search_query" collection="Magento\Search\Model\Resource\Query\Collection" repository_class="Magento\CatalogSearch\Test\Repository\CatalogSearchQuery" handler_interface="Magento\CatalogSearch\Test\Handler\CatalogSearchQuery\CatalogSearchQueryInterface" class="Magento\CatalogSearch\Test\Fixture\CatalogSearchQuery">
     <field name="query_id" is_required="1">
       <default_value xsi:type="null"/>
diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Handler/CatalogSearchQuery/Curl.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Handler/CatalogSearchQuery/Curl.php
index 049e2e77a7d47967f1cc79cb7339c9ac17d63b0c..3381fe268097374df309f6d511e2b8fa7750747f 100644
--- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Handler/CatalogSearchQuery/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Handler/CatalogSearchQuery/Curl.php
@@ -8,7 +8,6 @@ namespace Magento\CatalogSearch\Test\Handler\CatalogSearchQuery;
 
 use Magento\Mtf\Fixture\FixtureInterface;
 use Magento\Mtf\Handler\Curl as AbstractCurl;
-use Magento\Mtf\Config;
 use Magento\Mtf\Util\Protocol\CurlInterface;
 use Magento\Mtf\Util\Protocol\CurlTransport;
 use Magento\Mtf\Util\Protocol\CurlTransport\BackendDecorator;
diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Fixture/Cart.xml b/dev/tests/functional/tests/app/Magento/Checkout/Test/Fixture/Cart.xml
index 564e190e5f0f65b62786e16a4164e7e360617577..9c79804bfe3b25fd4bbe857f9f17c46fe9da2e08 100644
--- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Fixture/Cart.xml
+++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Fixture/Cart.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
   <fixture name="cart" module="Magento_Checkout" type="flat" entity_type="quote" repository_class="Magento\Checkout\Test\Repository\Cart" handler_interface="Magento\Checkout\Test\Handler\Cart\CartInterface" class="Magento\Checkout\Test\Fixture\Cart">
     <field name="entity_id" is_required="1">
       <default_value xsi:type="null"/>
diff --git a/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/Fixture/CheckoutAgreement.xml b/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/Fixture/CheckoutAgreement.xml
index 4a9a438e8460ae93d277273787204e0d78bfd333..d1f5018824ca4b96d33cf487ce339c285c1022f5 100644
--- a/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/Fixture/CheckoutAgreement.xml
+++ b/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/Fixture/CheckoutAgreement.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
     <fixture name="checkoutAgreement" module="Magento_CheckoutAgreements"
              type="flat" entity_type="checkout_agreement" collection="Magento\CheckoutAgreements\Model\Resource\Agreement\Collection"
              repository_class="Magento\CheckoutAgreements\Test\Repository\CheckoutAgreement"
diff --git a/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/Handler/CheckoutAgreement/Curl.php b/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/Handler/CheckoutAgreement/Curl.php
index 426831f470e92ed668e07a121bdc21fe1f2f1d07..9c241ef1354cd41eea088125162a1fe2b80df565 100644
--- a/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/Handler/CheckoutAgreement/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/Handler/CheckoutAgreement/Curl.php
@@ -8,7 +8,6 @@ namespace Magento\CheckoutAgreements\Test\Handler\CheckoutAgreement;
 
 use Magento\Mtf\Fixture\FixtureInterface;
 use Magento\Mtf\Handler\Curl as AbstractCurl;
-use Magento\Mtf\Config;
 use Magento\Mtf\Util\Protocol\CurlInterface;
 use Magento\Mtf\Util\Protocol\CurlTransport;
 use Magento\Mtf\Util\Protocol\CurlTransport\BackendDecorator;
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/Fixture/CmsBlock.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/Fixture/CmsBlock.xml
index 36bb9cf39af0421b3a0bc9e6e25115cb312ad55e..5d1a718ff1178b9a4737c8bbcc3df08f9e79accf 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/Fixture/CmsBlock.xml
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/Fixture/CmsBlock.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
     <fixture name="cmsBlock" module="Magento_Cms" type="flat" entity_type="cms_block" collection="Magento\Cms\Model\Resource\Block\Grid\Collection" identifier="identifier"
              handler_interface="Magento\Cms\Test\Handler\CmsBlock\CmsBlockInterface" class="Magento\Cms\Test\Fixture\CmsBlock">
         <dataset name="default">
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/Fixture/CmsPage.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/Fixture/CmsPage.xml
index 149bef091c83163e09710dbaa2cd7f4bc6930058..071897f0c5b13b72147ac1b674931f71e784f333 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/Fixture/CmsPage.xml
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/Fixture/CmsPage.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
     <fixture name="cmsPage" module="Magento_Cms" type="flat" entity_type="cms_page" collection="Magento\Cms\Model\Resource\Page\Grid\Collection" identifier="identifier"
              repository_class="Magento\Cms\Test\Repository\CmsPage" handler_interface="Magento\Cms\Test\Handler\CmsPage\CmsPageInterface" class="Magento\Cms\Test\Fixture\CmsPage">
         <dataset name="default">
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/Handler/CmsBlock/Curl.php b/dev/tests/functional/tests/app/Magento/Cms/Test/Handler/CmsBlock/Curl.php
index c3aefd941fc29abf6f5b823497131213d235f6ed..05564ee03f0572909f449a17b07910d1f4d54234 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/Handler/CmsBlock/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/Handler/CmsBlock/Curl.php
@@ -8,7 +8,6 @@ namespace Magento\Cms\Test\Handler\CmsBlock;
 
 use Magento\Mtf\Fixture\FixtureInterface;
 use Magento\Mtf\Handler\Curl as AbstractCurl;
-use Magento\Mtf\Config;
 use Magento\Mtf\Util\Protocol\CurlInterface;
 use Magento\Mtf\Util\Protocol\CurlTransport;
 use Magento\Mtf\Util\Protocol\CurlTransport\BackendDecorator;
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/Handler/CmsPage/Curl.php b/dev/tests/functional/tests/app/Magento/Cms/Test/Handler/CmsPage/Curl.php
index 4187350d28d7aead4044c949f745be6968cf1a17..a91b23ff28b1bba3b0802c4a3881a041e0517008 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/Handler/CmsPage/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/Handler/CmsPage/Curl.php
@@ -8,7 +8,8 @@ namespace Magento\Cms\Test\Handler\CmsPage;
 
 use Magento\Backend\Test\Handler\Conditions;
 use Magento\Mtf\Fixture\FixtureInterface;
-use Magento\Mtf\Config;
+use Magento\Mtf\Config\DataInterface;
+use Magento\Mtf\System\Event\EventManagerInterface;
 use Magento\Mtf\Util\Protocol\CurlInterface;
 use Magento\Mtf\Util\Protocol\CurlTransport;
 use Magento\Mtf\Util\Protocol\CurlTransport\BackendDecorator;
@@ -55,12 +56,13 @@ class Curl extends Conditions implements CmsPageInterface
 
     /**
      * @constructor
-     * @param Config $configuration
+     * @param DataInterface $configuration
+     * @param EventManagerInterface $eventManager
      */
-    public function __construct(Config $configuration)
+    public function __construct(DataInterface $configuration, EventManagerInterface $eventManager)
     {
         $this->mappingData = array_merge($this->mappingData, $this->additionalMappingData);
-        parent::__construct($configuration);
+        parent::__construct($configuration, $eventManager);
     }
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertChildProductsInGrid.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertChildProductsInGrid.php
index a467c0ad9af43e6223eb416643bdebafe9b00031..557e1c09882feee7e9194e88305861f2676b9e29 100755
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertChildProductsInGrid.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertChildProductsInGrid.php
@@ -52,7 +52,7 @@ class AssertChildProductsInGrid extends AbstractConstraint
             }
         }
 
-        \PHPUnit_Framework_Assert::assertEmpty($errors, implode($errors, ' '));
+        \PHPUnit_Framework_Assert::assertEmpty($errors, implode(' ', $errors));
     }
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/ConfigurableProduct.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/ConfigurableProduct.xml
index 839a00ef4a8074e7da8e5f7e59398ac5a578a3a7..6eb5ee6976ace67bf42136395b5894d354f7618c 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/ConfigurableProduct.xml
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/ConfigurableProduct.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
   <fixture name="configurableProduct"
            module="Magento_ConfigurableProduct" 
            type="eav" 
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Handler/ConfigurableProduct/Curl.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Handler/ConfigurableProduct/Curl.php
index 1bed329a243d055bce4df0c0a5a19b997806a639..7e0813eca10a21cbce34254bfd1eb9e3dafecb20 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Handler/ConfigurableProduct/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Handler/ConfigurableProduct/Curl.php
@@ -10,7 +10,8 @@ use Magento\Catalog\Test\Fixture\CatalogProductAttribute;
 use Magento\Catalog\Test\Handler\CatalogProductSimple\Curl as ProductCurl;
 use Magento\ConfigurableProduct\Test\Fixture\ConfigurableProduct\ConfigurableAttributesData;
 use Magento\Mtf\Fixture\FixtureInterface;
-use Magento\Mtf\Config;
+use Magento\Mtf\Config\DataInterface;
+use Magento\Mtf\System\Event\EventManagerInterface;
 
 /**
  * Class Curl
@@ -21,11 +22,12 @@ class Curl extends ProductCurl implements ConfigurableProductInterface
     /**
      * Constructor
      *
-     * @param Config $configuration
+     * @param DataInterface $configuration
+     * @param EventManagerInterface $eventManager
      */
-    public function __construct(Config $configuration)
+    public function __construct(DataInterface $configuration, EventManagerInterface $eventManager)
     {
-        parent::__construct($configuration);
+        parent::__construct($configuration, $eventManager);
 
         $this->mappingData += [
             'is_percent' => [
diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/Fixture/ConfigData.xml b/dev/tests/functional/tests/app/Magento/Core/Test/Fixture/ConfigData.xml
index 8bed37c9f9ba9a008e35327b901217acf596e00a..6b95f1c29ea9eac1be055d42985aeb2434aaecef 100644
--- a/dev/tests/functional/tests/app/Magento/Core/Test/Fixture/ConfigData.xml
+++ b/dev/tests/functional/tests/app/Magento/Core/Test/Fixture/ConfigData.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
   <fixture name="configData" 
            module="Magento_Core" 
            type="flat" 
diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/Fixture/SystemVariable.xml b/dev/tests/functional/tests/app/Magento/Core/Test/Fixture/SystemVariable.xml
index 01f5710dc7a3d13d105d0dfbfadf6c06406d55f2..ccb72344e985faaeb96b30a64cf2faa43c8cc27d 100644
--- a/dev/tests/functional/tests/app/Magento/Core/Test/Fixture/SystemVariable.xml
+++ b/dev/tests/functional/tests/app/Magento/Core/Test/Fixture/SystemVariable.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
   <fixture name="systemVariable" 
            module="Magento_Core" 
            type="composite" 
diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/Handler/ConfigData/Curl.php b/dev/tests/functional/tests/app/Magento/Core/Test/Handler/ConfigData/Curl.php
index 25be5b6e1ff02b819dc98d9fa7cc7467ce135eae..1a761f03046e6420cdef332767f73301ff55c0e5 100644
--- a/dev/tests/functional/tests/app/Magento/Core/Test/Handler/ConfigData/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/Core/Test/Handler/ConfigData/Curl.php
@@ -8,7 +8,6 @@ namespace Magento\Core\Test\Handler\ConfigData;
 
 use Magento\Mtf\Fixture\FixtureInterface;
 use Magento\Mtf\Handler\Curl as AbstractCurl;
-use Magento\Mtf\Config;
 use Magento\Mtf\Util\Protocol\CurlInterface;
 use Magento\Mtf\Util\Protocol\CurlTransport;
 use Magento\Mtf\Util\Protocol\CurlTransport\BackendDecorator;
@@ -116,7 +115,8 @@ class Curl extends AbstractCurl implements ConfigDataInterface
         $curl->close();
 
         if (strpos($response, 'data-ui-id="messages-message-success"') === false) {
-            throw new \Exception("Settings are not applied! Response: $response");
+            $this->_eventManager->dispatchEvent(['curl_failed'], [$response]);
+            throw new \Exception("Configuration settings are not applied! Url: $url");
         }
     }
 
@@ -128,7 +128,6 @@ class Curl extends AbstractCurl implements ConfigDataInterface
      */
     protected function getUrl($section)
     {
-        return $_ENV['app_backend_url'] .
-        'admin/system_config/save/section/' . $section;
+        return $_ENV['app_backend_url'] . 'admin/system_config/save/section/' . $section;
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/Handler/SystemVariable/Curl.php b/dev/tests/functional/tests/app/Magento/Core/Test/Handler/SystemVariable/Curl.php
index 6c02a8ae428e78fb67e534d0d4b973f5d52417b9..0ded2518a3b8ff6f98febb4e8f24d851d007a664 100644
--- a/dev/tests/functional/tests/app/Magento/Core/Test/Handler/SystemVariable/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/Core/Test/Handler/SystemVariable/Curl.php
@@ -8,7 +8,6 @@ namespace Magento\Core\Test\Handler\SystemVariable;
 
 use Magento\Mtf\Fixture\FixtureInterface;
 use Magento\Mtf\Handler\Curl as AbstractCurl;
-use Magento\Mtf\Config;
 use Magento\Mtf\Util\Protocol\CurlInterface;
 use Magento\Mtf\Util\Protocol\CurlTransport;
 use Magento\Mtf\Util\Protocol\CurlTransport\BackendDecorator;
diff --git a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Fixture/CurrencySymbolEntity.xml b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Fixture/CurrencySymbolEntity.xml
index ad576cb9359802523e8db4a07f0c35d27626bf5f..9b37f90342b5b9e52c0a7b3fa232d85409f6c41f 100644
--- a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Fixture/CurrencySymbolEntity.xml
+++ b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Fixture/CurrencySymbolEntity.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
   <fixture name="currencySymbolEntity" module="Magento_CurrencySymbol" type="flat" entity_type="core_config_data" repository_class="Magento\CurrencySymbol\Test\Repository\CurrencySymbolEntity" handler_interface="Magento\CurrencySymbol\Test\Handler\CurrencySymbolEntity\CurrencySymbolEntityInterface" class="Magento\CurrencySymbol\Test\Fixture\CurrencySymbolEntity">
     <dataset name="default">
         <field name="inherit_custom_currency_symbol" xsi:type="string">Yes</field>
diff --git a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Handler/CurrencySymbolEntity/Curl.php b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Handler/CurrencySymbolEntity/Curl.php
index d1b311772c5129904075f55be2f2137f21b0a3eb..34a5317bf187b7e1811371b985c8ecd962fa71b6 100644
--- a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Handler/CurrencySymbolEntity/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Handler/CurrencySymbolEntity/Curl.php
@@ -8,7 +8,6 @@ namespace Magento\CurrencySymbol\Test\Handler\CurrencySymbolEntity;
 
 use Magento\Mtf\Fixture\FixtureInterface;
 use Magento\Mtf\Handler\Curl as AbstractCurl;
-use Magento\Mtf\Config;
 use Magento\Mtf\Util\Protocol\CurlInterface;
 use Magento\Mtf\Util\Protocol\CurlTransport;
 use Magento\Mtf\Util\Protocol\CurlTransport\BackendDecorator;
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/Address.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/Address.xml
index c092c7e6aa3102711ebab77769dc5a07d48f5c3e..09e93bbf76968ec5a9dc5cdcaec363c71607cb39 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/Address.xml
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/Address.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
   <fixture name="address" module="Magento_Customer" type="eav" entity_type="customer_address" collection="Magento\Customer\Model\Resource\Address\Collection" repository_class="Magento\Customer\Test\Repository\Address" handler_interface="Magento\Customer\Test\Handler\Address\AddressInterface" class="Magento\Customer\Test\Fixture\Address">
     <dataset name="default">
         <field name="firstname" xsi:type="string">John</field>
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/Customer.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/Customer.xml
index d5afd5538951e8d4ecddcfaaeb6820c742ce3e04..fe4bdb7814a700b02ed39663d62dc2b11379f814 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/Customer.xml
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/Customer.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
   <fixture name="customer" module="Magento_Customer" type="eav" entity_type="customer" collection="Magento\Customer\Model\Resource\Customer\Collection" identifier="email" repository_class="Magento\Customer\Test\Repository\Customer" handler_interface="Magento\Customer\Test\Handler\Customer\CustomerInterface" class="Magento\Customer\Test\Fixture\Customer">
     <dataset name="default">
         <field name="firstname" xsi:type="string">John</field>
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/CustomerGroupInjectable.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/CustomerGroupInjectable.xml
index b470b1c21b5e357d8532cecd566650cff0cb1a51..cec2cec3a74619acaa55ad468a50738441768df7 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/CustomerGroupInjectable.xml
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/CustomerGroupInjectable.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
   <fixture name="customerGroupInjectable" module="Magento_Customer" type="flat" entity_type="customer_group" collection="Magento\Customer\Model\Resource\Group\Collection" repository_class="Magento\Customer\Test\Repository\CustomerGroupInjectable" handler_interface="Magento\Customer\Test\Handler\CustomerGroupInjectable\CustomerGroupInjectableInterface" class="Magento\Customer\Test\Fixture\CustomerGroupInjectable">
     <dataset name="default">
         <field name="customer_group_code" xsi:type="string">customer_code_%isolation%</field>
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/Curl/CreateCustomerBackend.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/Curl/CreateCustomerBackend.php
index e9860e68c44a4e346ab2a85c02021ae3c29992b2..cad3c992efa4681f8bf0851d50fa211c22aad7cc 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/Curl/CreateCustomerBackend.php
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/Curl/CreateCustomerBackend.php
@@ -8,7 +8,6 @@ namespace Magento\Customer\Test\Handler\Curl;
 
 use Magento\Mtf\Fixture\FixtureInterface;
 use Magento\Mtf\Handler\Curl;
-use Magento\Mtf\Config;
 use Magento\Mtf\Util\Protocol\CurlInterface;
 use Magento\Mtf\Util\Protocol\CurlTransport;
 use Magento\Mtf\Util\Protocol\CurlTransport\BackendDecorator;
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/Curl/CreateCustomerGroup.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/Curl/CreateCustomerGroup.php
index 22410354e5802ef983d6e3429696c464b086abf4..dadc4e66523bbc76d77a1ba8cbb52bba1fa744ff 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/Curl/CreateCustomerGroup.php
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/Curl/CreateCustomerGroup.php
@@ -8,7 +8,6 @@ namespace Magento\Customer\Test\Handler\Curl;
 
 use Magento\Mtf\Fixture\FixtureInterface;
 use Magento\Mtf\Handler\Curl;
-use Magento\Mtf\Config;
 use Magento\Mtf\Util\Protocol\CurlInterface;
 use Magento\Mtf\Util\Protocol\CurlTransport;
 use Magento\Mtf\Util\Protocol\CurlTransport\BackendDecorator;
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 1831cdcbd2168ecca66ec836b256511705db838a..67d98b313afe2c576d620daed3c0dfd392d40315 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
@@ -179,6 +179,7 @@ class Curl extends AbstractCurl implements CustomerInterface
         $curl->close();
 
         if (!strpos($response, 'data-ui-id="messages-message-success"')) {
+            $this->_eventManager->dispatchEvent(['curl_failed', [$response]]);
             throw new \Exception('Failed to update customer!');
         }
     }
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/CustomerGroupInjectable/Curl.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/CustomerGroupInjectable/Curl.php
index 4ca4adb67291be8c6fcaf88c6d694c73419a5a65..f2f7c1b52e6d809286919606322486f1421ee6bc 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/CustomerGroupInjectable/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/CustomerGroupInjectable/Curl.php
@@ -9,7 +9,6 @@ namespace Magento\Customer\Test\Handler\CustomerGroupInjectable;
 use Magento\Backend\Test\Handler\Extractor;
 use Magento\Mtf\Fixture\FixtureInterface;
 use Magento\Mtf\Handler\Curl as AbstractCurl;
-use Magento\Mtf\Config;
 use Magento\Mtf\Util\Protocol\CurlInterface;
 use Magento\Mtf\Util\Protocol\CurlTransport;
 use Magento\Mtf\Util\Protocol\CurlTransport\BackendDecorator;
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/Webapi/CreateCustomer.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/Webapi/CreateCustomer.php
index 0087460d6e6f69ae0212096882fe0d40b5e06852..af06e68b03ef85b14d92d27f4044803de10e059b 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/Webapi/CreateCustomer.php
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/Webapi/CreateCustomer.php
@@ -24,7 +24,7 @@ class CreateCustomer extends Webapi
      */
     public function persist(FixtureInterface $fixture = null)
     {
-        $configuration = $this->_configuration->getParameter('handler/webapi');
+        $configuration = $this->_configuration->get('handler/0/webapi/0/value');
 
         $soap = new SoapTransport($configuration['soap']);
         return $soap->call('customerCustomerList', $fixture->getData());
diff --git a/dev/tests/functional/tests/app/Magento/Directory/Test/Repository/ConfigData.xml b/dev/tests/functional/tests/app/Magento/Directory/Test/Repository/ConfigData.xml
index 546ccb6cda264b3d7100c471dd0489427a3d87cf..1afdae4142c3ca241c73666e9d8c9e310be9b530 100644
--- a/dev/tests/functional/tests/app/Magento/Directory/Test/Repository/ConfigData.xml
+++ b/dev/tests/functional/tests/app/Magento/Directory/Test/Repository/ConfigData.xml
@@ -9,27 +9,27 @@
     <repository class="Magento\Core\Test\Repository\ConfigData">
         <dataset name="config_currency_symbols_usd_and_uah">
             <field path="currency/options/allow" scope="currency" scope_id="1" xsi:type="array">
-                <item label="US Dollar" xsi:type="string">USD</item>
-                <item label="Ukrainian Hryvnia" xsi:type="string">UAH</item>
+                <item name="US Dollar" xsi:type="string">USD</item>
+                <item name="Ukrainian Hryvnia" xsi:type="string">UAH</item>
             </field>
         </dataset>
 
         <dataset name="config_currency_symbols_usd_and_uah_rollback">
             <field path="currency/options/allow" scope="currency" scope_id="1" xsi:type="array">
-                <item label="US Dollar" xsi:type="string">USD</item>
+                <item name="US Dollar" xsi:type="string">USD</item>
             </field>
         </dataset>
 
         <dataset name="config_currency_symbols_usd_and_chf">
             <field path="currency/options/allow" scope="currency" scope_id="1" xsi:type="array">
-                <item label="US Dollar" xsi:type="string">USD</item>
-                <item label="Swiss Franc" xsi:type="string">CHF</item>
+                <item name="US Dollar" xsi:type="string">USD</item>
+                <item name="Swiss Franc" xsi:type="string">CHF</item>
             </field>
         </dataset>
 
         <dataset name="config_currency_symbols_usd">
             <field path="currency/options/allow" scope="currency" scope_id="1" label="" xsi:type="array">
-                <item label="US Dollar" xsi:type="string">USD</item>
+                <item name="US Dollar" xsi:type="string">USD</item>
             </field>
         </dataset>
     </repository>
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/DownloadableProduct.xml b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/DownloadableProduct.xml
index 572574f962f25db2eff34e2a52855ec760a87e7a..7c7caf2f5c2495c7e0fdf71340026c83ad3e7bb3 100644
--- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/DownloadableProduct.xml
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/DownloadableProduct.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
   <fixture name="downloadableProduct" module="Magento_Downloadable" type="eav" entity_type="catalog_product" product_type="downloadable" collection="Magento\Catalog\Model\Resource\Product\Collection" identifier="sku" repository_class="Magento\Downloadable\Test\Repository\DownloadableProduct" handler_interface="Magento\Downloadable\Test\Handler\DownloadableProduct\DownloadableProductInterface" class="Magento\Downloadable\Test\Fixture\DownloadableProduct">
     <dataset name="default">
         <field name="name" xsi:type="string">DownloadableProduct_%isolation%</field>
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Handler/DownloadableProduct/Curl.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Handler/DownloadableProduct/Curl.php
index 9812c5b6aca7e4266eebc0c6e8a99c5ac2c64155..7d05456656c3ccb3c46190a06b19c26c6cd02950 100644
--- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Handler/DownloadableProduct/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Handler/DownloadableProduct/Curl.php
@@ -8,7 +8,8 @@ namespace Magento\Downloadable\Test\Handler\DownloadableProduct;
 
 use Magento\Catalog\Test\Handler\CatalogProductSimple\Curl as ProductCurl;
 use Magento\Mtf\Fixture\FixtureInterface;
-use Magento\Mtf\Config;
+use Magento\Mtf\Config\DataInterface;
+use Magento\Mtf\System\Event\EventManagerInterface;
 use Magento\Mtf\Util\Protocol\CurlInterface;
 use Magento\Mtf\Util\Protocol\CurlTransport;
 use Magento\Mtf\Util\Protocol\CurlTransport\BackendDecorator;
@@ -22,11 +23,12 @@ class Curl extends ProductCurl implements DownloadableProductInterface
     /**
      * Constructor
      *
-     * @param Config $configuration
+     * @param DataInterface $configuration
+     * @param EventManagerInterface $eventManager
      */
-    public function __construct(Config $configuration)
+    public function __construct(DataInterface $configuration, EventManagerInterface $eventManager)
     {
-        parent::__construct($configuration);
+        parent::__construct($configuration, $eventManager);
 
         $this->mappingData += [
             'links_purchased_separately' => [
diff --git a/dev/tests/functional/tests/app/Magento/GiftMessage/Test/Fixture/GiftMessage.xml b/dev/tests/functional/tests/app/Magento/GiftMessage/Test/Fixture/GiftMessage.xml
index be06e0300b46846747b71fd0a6b99c1d621277a3..d11995d1e7dc6baef8dc65be2371f688ec1c73dc 100644
--- a/dev/tests/functional/tests/app/Magento/GiftMessage/Test/Fixture/GiftMessage.xml
+++ b/dev/tests/functional/tests/app/Magento/GiftMessage/Test/Fixture/GiftMessage.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
   <fixture name="giftMessage" module="Magento_GiftMessage" type="flat" entity_type="gift_message" collection="Magento\GiftMessage\Model\Resource\Message\Collection" identifier="gift_message_id" repository_class="Magento\GiftMessage\Test\Repository\GiftMessage" class="Magento\GiftMessage\Test\Fixture\GiftMessage">
     <dataset name="default">
         <field name="allow_gift_options" xsi:type="string">Yes</field>
diff --git a/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/Fixture/GoogleShoppingAttribute.xml b/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/Fixture/GoogleShoppingAttribute.xml
index 61944b24eed8fafc0154028a32cd80db5d596d75..b33b9b5cc9eb62b3c8ae87cebeb824634d22db03 100644
--- a/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/Fixture/GoogleShoppingAttribute.xml
+++ b/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/Fixture/GoogleShoppingAttribute.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
   <fixture name="googleShoppingAttribute" module="Magento_GoogleShopping" type="flat" entity_type="googleshopping_types" collection="Magento\GoogleShopping\Model\Resource\Attribute\Collection" repository_class="Magento\GoogleShopping\Test\Repository\GoogleShoppingAttribute" handler_interface="Magento\GoogleShopping\Test\Handler\GoogleShoppingAttribute\GoogleShoppingAttributeInterface" class="Magento\GoogleShopping\Test\Fixture\GoogleShoppingAttribute">
     <dataset name="default">
         <field name="target_country" xsi:type="string">United States</field>
diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Fixture/GroupedProduct.xml b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Fixture/GroupedProduct.xml
index 22c825f3680670eb388bd767c7f79efbdf545bcf..5fc47bd6a0c653287b86c7ccc4ecd29838839f8d 100644
--- a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Fixture/GroupedProduct.xml
+++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Fixture/GroupedProduct.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
   <fixture name="groupedProduct" module="Magento_GroupedProduct" type="eav" entity_type="catalog_product" product_type="grouped" collection="Magento\Catalog\Model\Resource\Product\Collection" identifier="sku" repository_class="Magento\GroupedProduct\Test\Repository\GroupedProduct" handler_interface="Magento\GroupedProduct\Test\Handler\GroupedProduct\GroupedProductInterface" class="Magento\GroupedProduct\Test\Fixture\GroupedProduct">
     <dataset name="default">
         <field name="name" xsi:type="string">GroupedProduct_%isolation%</field>
diff --git a/dev/tests/functional/tests/app/Magento/ImportExport/Test/Fixture/ImportExport.xml b/dev/tests/functional/tests/app/Magento/ImportExport/Test/Fixture/ImportExport.xml
index 08b3dd3c556210d2efd6bc3a25a85e048a209413..01f5463b5f052fac98c49d795f3ac38e4979139f 100644
--- a/dev/tests/functional/tests/app/Magento/ImportExport/Test/Fixture/ImportExport.xml
+++ b/dev/tests/functional/tests/app/Magento/ImportExport/Test/Fixture/ImportExport.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
   <fixture name="importExport" module="Magento_ImportExport" type="flat" entity_type="importexport_importdata" class="Magento\ImportExport\Test\Fixture\ImportExport">
     <dataset name="default">
         <field name="entity" xsi:type="string">Products</field>
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertSuccessInstall.php b/dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertSuccessInstall.php
index 7bf6181d89616a2c86b5b08b108f19e4c6086aa6..2f7039d86953e8694ebe824973be8225edac004c 100644
--- a/dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertSuccessInstall.php
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertSuccessInstall.php
@@ -52,6 +52,11 @@ class AssertSuccessInstall extends AbstractConstraint
         $dbData = $installPage->getInstallBlock()->getDbInfo();
 
         $allData = array_merge($user->getData(), $installConfig->getData());
+
+        foreach ($installConfig->getData() as $key => $value) {
+            $allData[$key] = isset($value['value']) ? $value['value'] : $value;
+        }
+
         $allData['admin'] = $allData['web'] . $allData['admin'] . '/';
 
         foreach ($this->adminFieldsList as $field) {
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/Fixture/Install.xml b/dev/tests/functional/tests/app/Magento/Install/Test/Fixture/Install.xml
index f2d6025c12beb22e083405f5592bf2a209e53985..d846de8f0bd45b0ed71068f8146e171994d682f6 100644
--- a/dev/tests/functional/tests/app/Magento/Install/Test/Fixture/Install.xml
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/Fixture/Install.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
   <fixture name="install" module="Magento_Install" type="virtual" entity_type="install" repository_class="Magento\Install\Test\Repository\Install" handler_interface="Magento\Install\Test\Handler\Install\InstallInterface" class="Magento\Install\Test\Fixture\Install">
     <field name="dbHost"/>
     <field name="dbUser"/>
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest.php b/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest.php
index 96e18ffc8452ce74121d887ac3290f17842f1277..74ec107e09a60690f1292e847fbc0a5c289f41b0 100644
--- a/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest.php
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest.php
@@ -10,10 +10,9 @@ use Magento\Cms\Test\Page\CmsIndex;
 use Magento\Install\Test\Page\Install;
 use Magento\Install\Test\Fixture\Install as InstallConfig;
 use Magento\User\Test\Fixture\User;
-use Magento\Mtf\Config;
 use Magento\Mtf\Fixture\FixtureFactory;
 use Magento\Mtf\TestCase\Injectable;
-use Magento\Mtf\Config\GlobalConfig;
+use Magento\Mtf\Config\DataInterface;
 use Magento\Install\Test\Constraint\AssertAgreementTextPresent;
 use Magento\Install\Test\Constraint\AssertSuccessfulReadinessCheck;
 use Magento\Mtf\ObjectManagerFactory;
@@ -68,14 +67,14 @@ class InstallTest extends Injectable
      */
     public function __prepare()
     {
-        $config = ObjectManagerFactory::getObjectManager()->get('Magento\Mtf\Config\GlobalConfig');
+        $config = ObjectManagerFactory::getObjectManager()->get('Magento\Mtf\Config\DataInterface');
         // Prepare config data
-        $configData['dbHost'] = $config->get('install/host');
-        $configData['dbUser'] = $config->get('install/user');
-        $configData['dbPassword'] = $config->get('install/password');
-        $configData['dbName'] = $config->get('install/dbName');
-        $configData['web'] = $config->get('install/baseUrl');
-        $configData['admin'] = $config->get('install/backendName');
+        $configData['dbHost'] = $config->get('install/0/host/0');
+        $configData['dbUser'] = $config->get('install/0/user/0');
+        $configData['dbPassword'] = $config->get('install/0/password/0');
+        $configData['dbName'] = $config->get('install/0/dbName/0');
+        $configData['web'] = $config->get('install/0/baseUrl/0');
+        $configData['admin'] = $config->get('install/0/backendName/0');
 
         return ['configData' => $configData];
     }
diff --git a/dev/tests/functional/tests/app/Magento/Integration/Test/Fixture/Integration.xml b/dev/tests/functional/tests/app/Magento/Integration/Test/Fixture/Integration.xml
index 3e58557ff604b5282f1e552fd95d3f0ad6bf65de..30c8310ea5534bdabf634e3e4e005c1ac71a87ca 100644
--- a/dev/tests/functional/tests/app/Magento/Integration/Test/Fixture/Integration.xml
+++ b/dev/tests/functional/tests/app/Magento/Integration/Test/Fixture/Integration.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
   <fixture name="integration" module="Magento_Integration" type="composite" entity_type="integration" collection="Magento\Integration\Model\Resource\Integration\Collection" repository_class="Magento\Integration\Test\Repository\Integration" handler_interface="Magento\Integration\Test\Handler\Integration\IntegrationInterface" class="Magento\Integration\Test\Fixture\Integration">
     <dataset name="default">
         <field name="name" xsi:type="string">default_integration_%isolation%</field>
diff --git a/dev/tests/functional/tests/app/Magento/Integration/Test/Handler/Integration/Curl.php b/dev/tests/functional/tests/app/Magento/Integration/Test/Handler/Integration/Curl.php
index d8047148bec4461e4396776c0cb3a1b2d5621957..900572434e6de4e5719fabe54f620e87053ce375 100644
--- a/dev/tests/functional/tests/app/Magento/Integration/Test/Handler/Integration/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/Integration/Test/Handler/Integration/Curl.php
@@ -8,7 +8,6 @@ namespace Magento\Integration\Test\Handler\Integration;
 
 use Magento\Mtf\Fixture\FixtureInterface;
 use Magento\Mtf\Handler\Curl as AbstractCurl;
-use Magento\Mtf\Config;
 use Magento\Mtf\Util\Protocol\CurlInterface;
 use Magento\Mtf\Util\Protocol\CurlTransport;
 use Magento\Mtf\Util\Protocol\CurlTransport\BackendDecorator;
diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/Fixture/Template.xml b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Fixture/Template.xml
index 9d216c522278f6d9ac793770a231c61ed446e108..6311e64c6602a507e3da61125c06670429df3af5 100644
--- a/dev/tests/functional/tests/app/Magento/Newsletter/Test/Fixture/Template.xml
+++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Fixture/Template.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
   <fixture name="template" module="Magento_Newsletter" type="flat" entity_type="newsletter_template" collection="Magento\Newsletter\Model\Resource\Template\Collection" identifier="template_id" repository_class="Magento\Newsletter\Test\Repository\Template" handler_interface="Magento\Newsletter\Test\Handler\Template\TemplateInterface" class="Magento\Newsletter\Test\Fixture\Template">
     <dataset name="default">
         <field name="code" xsi:type="string">TemplateName%isolation%</field>
diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/Handler/Template/Curl.php b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Handler/Template/Curl.php
index 7578ea44254810996850a51e69d5b37d0377670b..8d94f60cda0c41ae9a9c18434edb8780d9165db6 100644
--- a/dev/tests/functional/tests/app/Magento/Newsletter/Test/Handler/Template/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Handler/Template/Curl.php
@@ -8,7 +8,6 @@ namespace Magento\Newsletter\Test\Handler\Template;
 
 use Magento\Mtf\Fixture\FixtureInterface;
 use Magento\Mtf\Handler\Curl as AbstractCurl;
-use Magento\Mtf\Config;
 use Magento\Mtf\Util\Protocol\CurlInterface;
 use Magento\Mtf\Util\Protocol\CurlTransport;
 use Magento\Mtf\Util\Protocol\CurlTransport\BackendDecorator;
diff --git a/dev/tests/functional/tests/app/Magento/OfflinePayments/Test/Repository/ConfigData.xml b/dev/tests/functional/tests/app/Magento/OfflinePayments/Test/Repository/ConfigData.xml
index 0e2819446d17c536bc36b2f20dc6444b5f102429..a6eb9d9e85ee49354c799e5b7d254786b5198c5c 100644
--- a/dev/tests/functional/tests/app/Magento/OfflinePayments/Test/Repository/ConfigData.xml
+++ b/dev/tests/functional/tests/app/Magento/OfflinePayments/Test/Repository/ConfigData.xml
@@ -19,7 +19,7 @@
             <field path="payment/cashondelivery/active" scope="payment" scope_id="1" label="Yes" xsi:type="string">1</field>
             <field path="payment/cashondelivery/allowspecific" scope="payment" scope_id="1" label="Specific Countries" xsi:type="string">1</field>
             <field path="payment/cashondelivery/specificcountry" scope="payment" scope_id="1" xsi:type="array">
-                <item label="United Kingdom" xsi:type="string">GB</item>
+                <item name="United Kingdom" xsi:type="string">GB</item>
             </field>
         </dataset>
 
@@ -40,7 +40,7 @@
             <field path="payment/checkmo/active" scope="payment" scope_id="1" label="Yes" xsi:type="string">1</field>
             <field path="payment/checkmo/allowspecific" scope="payment" scope_id="1" label="Specific Countries" xsi:type="string">1</field>
             <field path="payment/checkmo/specificcountry" scope="payment" scope_id="1" xsi:type="array">
-                <item label="United Kingdom" xsi:type="string">GB</item>
+                <item name="United Kingdom" xsi:type="string">GB</item>
             </field>
         </dataset>
 
@@ -61,7 +61,7 @@
             <field path="payment/banktransfer/active" scope="payment" scope_id="1" label="Yes" xsi:type="string">1</field>
             <field path="payment/banktransfer/allowspecific" scope="payment" scope_id="1" label="Specific Countries" xsi:type="string">1</field>
             <field path="payment/banktransfer/specificcountry" scope="payment" scope_id="1" xsi:type="array">
-                <item label="United Kingdom" xsi:type="string">GB</item>
+                <item name="United Kingdom" xsi:type="string">GB</item>
             </field>
         </dataset>
 
@@ -82,7 +82,7 @@
             <field path="payment/purchaseorder/active" scope="payment" scope_id="1" label="Yes" xsi:type="string">1</field>
             <field path="payment/purchaseorder/allowspecific" scope="payment" scope_id="1" label="Specific Countries" xsi:type="string">1</field>
             <field path="payment/purchaseorder/specificcountry" scope="payment" scope_id="1" xsi:type="array">
-                <item label="United Kingdom" xsi:type="string">GB</item>
+                <item name="United Kingdom" xsi:type="string">GB</item>
             </field>
         </dataset>
 
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Fixture/Rating.xml b/dev/tests/functional/tests/app/Magento/Review/Test/Fixture/Rating.xml
index 99e16141dcdfc1ce45c3b9c890d6aac75a1e05ab..d551947d8c420dd84ac3396c240ec9bf0d140a76 100755
--- a/dev/tests/functional/tests/app/Magento/Review/Test/Fixture/Rating.xml
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/Fixture/Rating.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
   <fixture name="rating" module="Magento_Review" type="flat" entity_type="rating" collection="Magento\Review\Model\Resource\Rating\Collection" identifier="rating_code" repository_class="Magento\Review\Test\Repository\Rating" handler_interface="Magento\Review\Test\Handler\Rating\RatingInterface" class="Magento\Review\Test\Fixture\Rating">
     <dataset name="default">
         <field name="rating_code" xsi:type="string">Rating %isolation%</field>
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Fixture/Review.xml b/dev/tests/functional/tests/app/Magento/Review/Test/Fixture/Review.xml
index 50ede32fea8d7b74f06a6395941376ef155ef70f..a118552b4f5c6c97ee8523795f77d6e8b4d79d5b 100755
--- a/dev/tests/functional/tests/app/Magento/Review/Test/Fixture/Review.xml
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/Fixture/Review.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
   <fixture name="review" module="Magento_Review" type="composite" collection="Magento\Review\Model\Resource\Review\Collection" repository_class="Magento\Review\Test\Repository\Review" handler_interface="Magento\Review\Test\Handler\Review\ReviewInterface" class="Magento\Review\Test\Fixture\Review">
     <dataset name="default">
         <field name="status_id" xsi:type="string">Approved</field>
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Handler/Rating/Curl.php b/dev/tests/functional/tests/app/Magento/Review/Test/Handler/Rating/Curl.php
index 58206282eb611641755d1f42f2e8c4667a1e4a97..ea7b1d6bad431f6814c07c6c5d97c553071dfe71 100755
--- a/dev/tests/functional/tests/app/Magento/Review/Test/Handler/Rating/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/Handler/Rating/Curl.php
@@ -9,7 +9,6 @@ namespace Magento\Review\Test\Handler\Rating;
 use Magento\Backend\Test\Handler\Extractor;
 use Magento\Mtf\Fixture\FixtureInterface;
 use Magento\Mtf\Handler\Curl as AbstractCurl;
-use Magento\Mtf\Config;
 use Magento\Mtf\Util\Protocol\CurlInterface;
 use Magento\Mtf\Util\Protocol\CurlTransport;
 use Magento\Mtf\Util\Protocol\CurlTransport\BackendDecorator;
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Handler/Review/Curl.php b/dev/tests/functional/tests/app/Magento/Review/Test/Handler/Review/Curl.php
index df3c3004b7c979c7a2f84efc3588c373ad89038d..986d1f4883123d27e8f743e5473346c9948f9399 100644
--- a/dev/tests/functional/tests/app/Magento/Review/Test/Handler/Review/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/Handler/Review/Curl.php
@@ -6,7 +6,6 @@
 
 namespace Magento\Review\Test\Handler\Review;
 
-use Magento\Mtf\Config;
 use Magento\Mtf\Fixture\FixtureInterface;
 use Magento\Mtf\Util\Protocol\CurlInterface;
 use Magento\Mtf\Util\Protocol\CurlTransport;
diff --git a/dev/tests/functional/tests/app/Magento/Sitemap/Test/Fixture/Sitemap.xml b/dev/tests/functional/tests/app/Magento/Sitemap/Test/Fixture/Sitemap.xml
index dc51c43e5dd1f27e7789fbe1da1972a324120885..6927691a7aa8e27bc0be0ff11dd70d694724a917 100644
--- a/dev/tests/functional/tests/app/Magento/Sitemap/Test/Fixture/Sitemap.xml
+++ b/dev/tests/functional/tests/app/Magento/Sitemap/Test/Fixture/Sitemap.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
   <fixture name="sitemap" module="Magento_Sitemap" type="flat" entity_type="sitemap" collection="Magento\Sitemap\Model\Resource\Sitemap\Collection" repository_class="Magento\Sitemap\Test\Repository\Sitemap" handler_interface="Magento\Sitemap\Test\Handler\Sitemap\SitemapInterface" class="Magento\Sitemap\Test\Fixture\Sitemap">
     <dataset name="default">
         <field name="sitemap_filename" xsi:type="string">sitemap.xml</field>
diff --git a/dev/tests/functional/tests/app/Magento/Sitemap/Test/Handler/Sitemap/Curl.php b/dev/tests/functional/tests/app/Magento/Sitemap/Test/Handler/Sitemap/Curl.php
index c8b09124666bd8ab70c40b40bdf1f93affca8550..e78e858ded474e8669a7dc19f81afd22fe245ee8 100644
--- a/dev/tests/functional/tests/app/Magento/Sitemap/Test/Handler/Sitemap/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/Sitemap/Test/Handler/Sitemap/Curl.php
@@ -10,7 +10,6 @@ use Magento\Backend\Test\Handler\Extractor;
 use Magento\Sitemap\Test\Handler\Sitemap;
 use Magento\Mtf\Fixture\FixtureInterface;
 use Magento\Mtf\Handler\Curl as AbstractCurl;
-use Magento\Mtf\Config;
 use Magento\Mtf\Util\Protocol\CurlInterface;
 use Magento\Mtf\Util\Protocol\CurlTransport;
 use Magento\Mtf\Util\Protocol\CurlTransport\BackendDecorator;
diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/Fixture/Store.xml b/dev/tests/functional/tests/app/Magento/Store/Test/Fixture/Store.xml
index b9be593561d7c588beb8de9f6aff896b262a5270..3a95b594d8400494d3809ae19d53599b063821f8 100644
--- a/dev/tests/functional/tests/app/Magento/Store/Test/Fixture/Store.xml
+++ b/dev/tests/functional/tests/app/Magento/Store/Test/Fixture/Store.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
   <fixture name="store" module="Magento_Store" type="flat" entity_type="store" collection="Magento\Store\Model\Resource\Store\Collection" repository_class="Magento\Store\Test\Repository\Store" handler_interface="Magento\Store\Test\Handler\Store\StoreInterface" class="Magento\Store\Test\Fixture\Store">
     <dataset name="default">
         <field name="group_id" xsi:type="array">
diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/Fixture/StoreGroup.xml b/dev/tests/functional/tests/app/Magento/Store/Test/Fixture/StoreGroup.xml
index fcd43ace417f90fc83a88a6d89d96a3eb24db03f..7b6a5ad692b1add59ad8803aa85e8832e8b6db9a 100644
--- a/dev/tests/functional/tests/app/Magento/Store/Test/Fixture/StoreGroup.xml
+++ b/dev/tests/functional/tests/app/Magento/Store/Test/Fixture/StoreGroup.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
   <fixture name="storeGroup" module="Magento_Store" type="flat" entity_type="store_group" collection="Magento\Store\Model\Resource\Group\Collection" identifier="" repository_class="Magento\Store\Test\Repository\StoreGroup" handler_interface="Magento\Store\Test\Handler\StoreGroup\StoreGroupInterface" class="Magento\Store\Test\Fixture\StoreGroup">
     <dataset name="default">
         <field name="website_id" xsi:type="array">
diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/Fixture/Website.xml b/dev/tests/functional/tests/app/Magento/Store/Test/Fixture/Website.xml
index 261b506e96a6127b5de859597b3ca13bd6d717ef..0878f90e302a1d1594eac5f1d8af895f8fd4e418 100644
--- a/dev/tests/functional/tests/app/Magento/Store/Test/Fixture/Website.xml
+++ b/dev/tests/functional/tests/app/Magento/Store/Test/Fixture/Website.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
   <fixture name="website" module="Magento_Store" type="flat" entity_type="store_website" collection="Magento\Store\Model\Resource\Website\Collection" identifier="code" repository_class="Magento\Store\Test\Repository\Website" handler_interface="Magento\Store\Test\Handler\Website\WebsiteInterface" class="Magento\Store\Test\Fixture\Website">
     <dataset name="default">
         <field name="name" xsi:type="string">Main Website</field>
diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/Handler/Store/Curl.php b/dev/tests/functional/tests/app/Magento/Store/Test/Handler/Store/Curl.php
index aaa0e84ce103a1a2813086a88aca122f793eddb1..d6293b08cd50a9f0773b6bf4b9c8680033b36553 100644
--- a/dev/tests/functional/tests/app/Magento/Store/Test/Handler/Store/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/Store/Test/Handler/Store/Curl.php
@@ -8,7 +8,6 @@ namespace Magento\Store\Test\Handler\Store;
 
 use Magento\Mtf\Fixture\FixtureInterface;
 use Magento\Mtf\Handler\Curl as AbstractCurl;
-use Magento\Mtf\Config;
 use Magento\Mtf\Util\Protocol\CurlInterface;
 use Magento\Mtf\Util\Protocol\CurlTransport;
 use Magento\Mtf\Util\Protocol\CurlTransport\BackendDecorator;
diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/Handler/StoreGroup/Curl.php b/dev/tests/functional/tests/app/Magento/Store/Test/Handler/StoreGroup/Curl.php
index 9922064088af8416f8e7d3adde471a174448a789..71faf510eed5e5886c59a8a19398f28cad987ed5 100644
--- a/dev/tests/functional/tests/app/Magento/Store/Test/Handler/StoreGroup/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/Store/Test/Handler/StoreGroup/Curl.php
@@ -8,7 +8,6 @@ namespace Magento\Store\Test\Handler\StoreGroup;
 
 use Magento\Mtf\Fixture\FixtureInterface;
 use Magento\Mtf\Handler\Curl as AbstractCurl;
-use Magento\Mtf\Config;
 use Magento\Mtf\Util\Protocol\CurlInterface;
 use Magento\Mtf\Util\Protocol\CurlTransport;
 use Magento\Mtf\Util\Protocol\CurlTransport\BackendDecorator;
diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/Handler/Website/Curl.php b/dev/tests/functional/tests/app/Magento/Store/Test/Handler/Website/Curl.php
index 4de491270189098448ffb31ad31bfb2a87a4485b..bbd183601e4ef3697021b64745bad2b0bdadb64f 100644
--- a/dev/tests/functional/tests/app/Magento/Store/Test/Handler/Website/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/Store/Test/Handler/Website/Curl.php
@@ -8,7 +8,6 @@ namespace Magento\Store\Test\Handler\Website;
 
 use Magento\Mtf\Fixture\FixtureInterface;
 use Magento\Mtf\Handler\Curl as AbstractCurl;
-use Magento\Mtf\Config;
 use Magento\Mtf\Util\Protocol\CurlInterface;
 use Magento\Mtf\Util\Protocol\CurlTransport;
 use Magento\Mtf\Util\Protocol\CurlTransport\BackendDecorator;
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxClass.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxClass.xml
index 13e6c00c52879193a38fb344bba0ccf716eab9b1..30710bb5b2f81fc5e2f5f53025b9f6d5dc225476 100644
--- a/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxClass.xml
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxClass.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
   <fixture name="taxClass" module="Magento_Tax" type="flat" entity_type="tax_class" collection="Magento\Tax\Model\Resource\TaxClass\Collection" identifier="" repository_class="Magento\Tax\Test\Repository\TaxClass" handler_interface="Magento\Tax\Test\Handler\TaxClass\TaxClassInterface" class="Magento\Tax\Test\Fixture\TaxClass">
     <dataset name="default">
         <field name="class_name" xsi:type="string">Tax Class %isolation%</field>
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRate.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRate.xml
index a344ad905106d0f0b6b363d9fc83fabb103d0779..b9a4a30142690008bd8b142c8e8a74692b19307a 100644
--- a/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRate.xml
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRate.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
   <fixture name="taxRate" module="Magento_Tax" type="flat" entity_type="tax_calculation_rate" collection="Magento\Tax\Model\Resource\Calculation\Rate\Collection" identifier="code" repository_class="Magento\Tax\Test\Repository\TaxRate" handler_interface="Magento\Tax\Test\Handler\TaxRate\TaxRateInterface" class="Magento\Tax\Test\Fixture\TaxRate">
     <dataset name="default">
         <field name="code" xsi:type="string">Tax Rate %isolation%</field>
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRule.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRule.xml
index 82d0dc07793aeef0b07f4e2186b8bdb19830b146..b53f3f1eba5d9b4c3f29653c282cf1b7af82820a 100644
--- a/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRule.xml
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRule.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
   <fixture name="taxRule" module="Magento_Tax" type="flat" entity_type="tax_calculation_rule" collection="Magento\Tax\Model\Resource\Calculation\Rule\Collection" identifier="code" repository_class="Magento\Tax\Test\Repository\TaxRule" handler_interface="Magento\Tax\Test\Handler\TaxRule\TaxRuleInterface" class="Magento\Tax\Test\Fixture\TaxRule">
     <dataset name="default">
         <field name="code" xsi:type="string">TaxIdentifier%isolation%</field>
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxClass/Curl.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxClass/Curl.php
index 28e77379db72e1010f28e6bf0212e34ac8a2feea..b6d6072bcb5a13ebcaba872d5465f00ed29681e8 100644
--- a/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxClass/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxClass/Curl.php
@@ -8,7 +8,6 @@ namespace Magento\Tax\Test\Handler\TaxClass;
 
 use Magento\Mtf\Fixture\FixtureInterface;
 use Magento\Mtf\Handler\Curl as AbstractCurl;
-use Magento\Mtf\Config;
 use Magento\Mtf\Util\Protocol\CurlInterface;
 use Magento\Mtf\Util\Protocol\CurlTransport;
 use Magento\Mtf\Util\Protocol\CurlTransport\BackendDecorator;
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxRate/Curl.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxRate/Curl.php
index 6cc269c5525d86bd6d4d7b854a4a3231d4dd8fbf..e1b370a6e44f8463404f512142f91449412b9903 100644
--- a/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxRate/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxRate/Curl.php
@@ -8,7 +8,6 @@ namespace Magento\Tax\Test\Handler\TaxRate;
 
 use Magento\Mtf\Fixture\FixtureInterface;
 use Magento\Mtf\Handler\Curl as AbstractCurl;
-use Magento\Mtf\Config;
 use Magento\Mtf\Util\Protocol\CurlInterface;
 use Magento\Mtf\Util\Protocol\CurlTransport;
 use Magento\Mtf\Util\Protocol\CurlTransport\BackendDecorator;
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxRule/Curl.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxRule/Curl.php
index 2d47e8b3bdb62090385ef7b15d2bbff156bbc80f..872f49ae0387a92bd9bd19ad7a6b0ccbdfe6ee0b 100644
--- a/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxRule/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxRule/Curl.php
@@ -8,7 +8,6 @@ namespace Magento\Tax\Test\Handler\TaxRule;
 
 use Magento\Mtf\Fixture\FixtureInterface;
 use Magento\Mtf\Handler\Curl as AbstractCurl;
-use Magento\Mtf\Config;
 use Magento\Mtf\Util\Protocol\CurlInterface;
 use Magento\Mtf\Util\Protocol\CurlTransport;
 use Magento\Mtf\Util\Protocol\CurlTransport\BackendDecorator;
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 a6d197824433ed7cae1e7ede9e230d4b6defe362..6c8afa0db50de401e34b56f1bd04c938e74a9016 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
@@ -29,17 +29,17 @@
             <field path="carriers/ups/tracking_xml_url" scope="carriers" scope_id="1" label="" xsi:type="string">https://wwwcie.ups.com/ups.app/xml/Track</field>
             <field path="carriers/ups/unit_of_measure" scope="carriers" scope_id="1" label="LBS" xsi:type="string">LBS</field>
             <field path="carriers/ups/allowed_methods" scope="carriers" scope_id="1" xsi:type="array">
-                <item label="UPS Standard" xsi:type="string">11</item>
-                <item label="UPS Three-Day Select" xsi:type="string">12</item>
-                <item label="UPS Next Day Air Early A.M." xsi:type="string">14</item>
-                <item label="UPS Worldwide Express Plus" xsi:type="string">54</item>
-                <item label="UPS Second Day Air A.M." xsi:type="string">59</item>
-                <item label="UPS Worldwide Saver" xsi:type="string">65</item>
-                <item label="UPS Next Day Air" xsi:type="string">01</item>
-                <item label="UPS Second Day Air" xsi:type="string">02</item>
-                <item label="UPS Ground" xsi:type="string">03</item>
-                <item label="UPS Worldwide Express" xsi:type="string">07</item>
-                <item label="UPS Worldwide Expedited" xsi:type="string">08</item>
+                <item name="UPS Standard" xsi:type="string">11</item>
+                <item name="UPS Three-Day Select" xsi:type="string">12</item>
+                <item name="UPS Next Day Air Early A.M." xsi:type="string">14</item>
+                <item name="UPS Worldwide Express Plus" xsi:type="string">54</item>
+                <item name="UPS Second Day Air A.M." xsi:type="string">59</item>
+                <item name="UPS Worldwide Saver" xsi:type="string">65</item>
+                <item name="UPS Next Day Air" xsi:type="string">01</item>
+                <item name="UPS Second Day Air" xsi:type="string">02</item>
+                <item name="UPS Ground" xsi:type="string">03</item>
+                <item name="UPS Worldwide Express" xsi:type="string">07</item>
+                <item name="UPS Worldwide Expedited" xsi:type="string">08</item>
             </field>
             <field path="carriers/ups/sallowspecific" scope="carriers" scope_id="1" label="All Allowed Countries" xsi:type="string">0</field>
             <field path="carriers/ups/showmethod" scope="carriers" scope_id="1" label="No" xsi:type="string">0</field>
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite.xml b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite.xml
index a73037a6417cea31f404c94f66c3f1fd72b0a6af..f0fda4e5442de3338d518ecad3cc758bfa82f5db 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite.xml
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
   <fixture name="urlRewrite" module="Magento_UrlRewrite" type="virtual" entity_type="url_rewrite" collection="Magento\UrlRewrite\Model\Resource\UrlRewriteCollection" identifier="request_path" repository_class="Magento\UrlRewrite\Test\Repository\UrlRewrite" handler_interface="Magento\UrlRewrite\Test\Handler\UrlRewrite\UrlRewriteInterface" class="Magento\UrlRewrite\Test\Fixture\UrlRewrite">
     <dataset name="default">
         <field name="store_id" xsi:type="string">Main Website/Main Website Store/Default Store View</field>
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Handler/UrlRewrite/Curl.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Handler/UrlRewrite/Curl.php
index ccc680aab72bdac4600300aaf370b56e22e1bc66..ab9aaa6a50f976b8b03880fb2a6c9bb6d25c4db1 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Handler/UrlRewrite/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Handler/UrlRewrite/Curl.php
@@ -8,7 +8,6 @@ namespace Magento\UrlRewrite\Test\Handler\UrlRewrite;
 
 use Magento\Mtf\Fixture\FixtureInterface;
 use Magento\Mtf\Handler\Curl as AbstractCurl;
-use Magento\Mtf\Config;
 use Magento\Mtf\Util\Protocol\CurlInterface;
 use Magento\Mtf\Util\Protocol\CurlTransport;
 use Magento\Mtf\Util\Protocol\CurlTransport\BackendDecorator;
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Fixture/Role.xml b/dev/tests/functional/tests/app/Magento/User/Test/Fixture/Role.xml
index 671556ced60023e557fce39be0f51dd6fef2d5d9..39ac5778e0cc30e30d6d8edeca2824949954327d 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Fixture/Role.xml
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Fixture/Role.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
     <fixture name="role" module="Magento_User" type="flat" entity_type="authorization_role" collection="Magento\User\Model\Resource\Role\User\Collection" repository_class="Magento\User\Test\Repository\Role" handler_interface="Magento\User\Test\Handler\Role\RoleInterface" class="Magento\User\Test\Fixture\Role">
         <dataset name="default">
             <field name="rolename" xsi:type="string">AdminRole%isolation%</field>
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Fixture/User.xml b/dev/tests/functional/tests/app/Magento/User/Test/Fixture/User.xml
index 1044838fb45f6ee3a9bb9f0467e8425451130790..80c969cf4bbfe3c393e25e8abae8066e552ec028 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Fixture/User.xml
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Fixture/User.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
   <fixture name="user" module="Magento_User" type="flat" entity_type="admin_user" collection="Magento\User\Model\Resource\User\Collection" repository_class="Magento\User\Test\Repository\User" handler_interface="Magento\User\Test\Handler\User\UserInterface" class="Magento\User\Test\Fixture\User">
     <dataset name="default">
         <field name="username" xsi:type="string">AdminUser%isolation%</field>
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Fixture/User/CurrentPassword.php b/dev/tests/functional/tests/app/Magento/User/Test/Fixture/User/CurrentPassword.php
index 31ab14a90355b4a9ed4f4cf01dcc246adc61c417..7c7e8bc1d8a073e2c3c848ab0390e2e97232af14 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Fixture/User/CurrentPassword.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Fixture/User/CurrentPassword.php
@@ -36,10 +36,10 @@ class CurrentPassword implements FixtureInterface
     public function __construct(array $params, $data = '')
     {
         $this->params = $params;
-        /** @var \Magento\Mtf\Config $systemConfig */
+        /** @var \Magento\Mtf\Config\DataInterface $systemConfig */
         if ($data == '%current_password%') {
-            $systemConfig = ObjectManager::getInstance()->create('Magento\Mtf\Config');
-            $data = $systemConfig->getParameter('application/backendPassword');
+            $systemConfig = ObjectManager::getInstance()->create('Magento\Mtf\Config\DataInterface');
+            $data = $systemConfig->get('application/0/backendPassword/0/value');
         }
         $this->data = $data;
     }
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Handler/Role/Curl.php b/dev/tests/functional/tests/app/Magento/User/Test/Handler/Role/Curl.php
index 857ae696219497fb2ac8c399047066dfae8e7a40..b5b05e9b9183aba2d472163610318b7cee4d6329 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Handler/Role/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Handler/Role/Curl.php
@@ -9,7 +9,8 @@ namespace Magento\User\Test\Handler\Role;
 use Magento\Backend\Test\Handler\Extractor;
 use Magento\Mtf\Fixture\FixtureInterface;
 use Magento\Mtf\Handler\Curl as AbstractCurl;
-use Magento\Mtf\Config;
+use Magento\Mtf\Config\DataInterface;
+use Magento\Mtf\System\Event\EventManagerInterface;
 use Magento\Mtf\Util\Protocol\CurlInterface;
 use Magento\Mtf\Util\Protocol\CurlTransport;
 use Magento\Mtf\Util\Protocol\CurlTransport\BackendDecorator;
@@ -28,15 +29,16 @@ class Curl extends AbstractCurl implements RoleInterface
 
     /**
      * @constructor
-     * @param Config $configuration
+     * @param DataInterface $configuration
+     * @param EventManagerInterface $eventManager
      */
-    public function __construct(Config $configuration)
+    public function __construct(DataInterface $configuration, EventManagerInterface $eventManager)
     {
         $this->mappingData = array_merge(
             (null !== $this->mappingData) ? $this->mappingData : [],
             $this->additionalMappingData
         );
-        parent::__construct($configuration);
+        parent::__construct($configuration, $eventManager);
     }
 
     /**
@@ -61,7 +63,7 @@ class Curl extends AbstractCurl implements RoleInterface
         }
 
         $url = 'admin/user_role/roleGrid/sort/role_id/dir/desc/';
-        $regExpPattern = '/col\-role_id[\s\W]*(\d+)\s*<.td>\s*<[^<>]*?>' . $data['rolename'] . '/siu';
+        $regExpPattern = '/col\-role_id[^\>]+\>\s*(\d+)\s*<.td>\s*<[^<>]*?>\s*' . $data['rolename'] . '/siu';
 
         $extractor = new Extractor($url, $regExpPattern);
 
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Handler/User/Curl.php b/dev/tests/functional/tests/app/Magento/User/Test/Handler/User/Curl.php
index 1026e872f89221e111761229063be05f2bf2e24e..115d2c932836012dce9e88dfa8bf0baca774a36d 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Handler/User/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Handler/User/Curl.php
@@ -9,7 +9,6 @@ namespace Magento\User\Test\Handler\User;
 use Magento\Backend\Test\Handler\Extractor;
 use Magento\Mtf\Fixture\FixtureInterface;
 use Magento\Mtf\Handler\Curl as AbstractCurl;
-use Magento\Mtf\Config;
 use Magento\Mtf\Util\Protocol\CurlInterface;
 use Magento\Mtf\Util\Protocol\CurlTransport;
 use Magento\Mtf\Util\Protocol\CurlTransport\BackendDecorator;
@@ -47,7 +46,7 @@ class Curl extends AbstractCurl implements UserInterface
         }
 
         $url = 'admin/user/roleGrid/sort/user_id/dir/desc';
-        $regExpPattern = '/col-user_id[\s\W]*(\d+)\s*<.td>\s*<[^<>]*?>' . $data['username'] . '/siu';
+        $regExpPattern = '/col-user_id[^\>]+\>\s*(\d+)\s*<.td>\s*<[^<>]*?>\s*' . $data['username'] . '/siu';
         $extractor = new Extractor($url, $regExpPattern);
 
         return ['user_id' => $extractor->getData()[1]];
diff --git a/dev/tests/integration/testsuite/Magento/Backend/Model/AuthTest.php b/dev/tests/integration/testsuite/Magento/Backend/Model/AuthTest.php
index 762fcf94aa70576a4cc04f3b6f16b1015885ba69..3f0e20d8a744b52b81313fb8e2a38c57af8d1a0c 100644
--- a/dev/tests/integration/testsuite/Magento/Backend/Model/AuthTest.php
+++ b/dev/tests/integration/testsuite/Magento/Backend/Model/AuthTest.php
@@ -30,11 +30,22 @@ class AuthTest extends \PHPUnit_Framework_TestCase
     }
 
     /**
+     * @dataProvider getLoginDataProvider
+     * @param string $userName
+     * @param string $password
      * @expectedException \Magento\Framework\Exception\AuthenticationException
      */
-    public function testLoginFailed()
+    public function testLoginFailed($userName, $password)
     {
-        $this->_model->login('not_exists', 'not_exists');
+        $this->_model->login($userName, $password);
+    }
+
+    public function getLoginDataProvider()
+    {
+        return [
+            'Invalid credentials' => ['not_exists', 'not_exists'],
+            'Empty credentials' => ['', 'not_exists']
+        ];
     }
 
     public function testSetGetAuthStorage()
@@ -77,17 +88,13 @@ class AuthTest extends \PHPUnit_Framework_TestCase
      */
     public function testLogout()
     {
-        $this->markTestIncomplete('MAGETWO-17021');
         $this->_model->login(
             \Magento\TestFramework\Bootstrap::ADMIN_NAME,
             \Magento\TestFramework\Bootstrap::ADMIN_PASSWORD
         );
         $this->assertNotEmpty($this->_model->getAuthStorage()->getData());
-        $cookie = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Framework\Stdlib\Cookie');
-        $cookie->set($this->_model->getAuthStorage()->getName(), 'session_id');
         $this->_model->logout();
         $this->assertEmpty($this->_model->getAuthStorage()->getData());
-        $this->assertEmpty($cookie->get($this->_model->getAuthStorage()->getName()));
     }
 
     /**
diff --git a/dev/tests/integration/testsuite/Magento/Backend/Model/Search/CustomerTest.php b/dev/tests/integration/testsuite/Magento/Backend/Model/Search/CustomerTest.php
index fb4b79dfe54a16bcb4738af561ea64ad253c455a..e17b5accf97dd08dc234b90e73192bb51a573bd7 100644
--- a/dev/tests/integration/testsuite/Magento/Backend/Model/Search/CustomerTest.php
+++ b/dev/tests/integration/testsuite/Magento/Backend/Model/Search/CustomerTest.php
@@ -10,12 +10,12 @@ use Magento\TestFramework\Helper\Bootstrap;
 
 /**
  * @magentoAppArea adminhtml
+ * @magentoDataFixture Magento/Customer/_files/three_customers.php
+ * @magentoDataFixture Magento/Customer/_files/customer_address.php
  */
 class CustomerTest extends \PHPUnit_Framework_TestCase
 {
     /**
-     * @magentoDataFixture Magento/Customer/_files/three_customers.php
-     * @magentoDataFixture Magento/Customer/_files/customer_address.php
      * @dataProvider loadDataProvider
      */
     public function testLoad($query, $limit, $start, $expectedResult)
diff --git a/dev/tests/integration/testsuite/Magento/Backend/Model/Search/OrderTest.php b/dev/tests/integration/testsuite/Magento/Backend/Model/Search/OrderTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..759951c785d8590a1e9651a68f7a3ceeffae6371
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Backend/Model/Search/OrderTest.php
@@ -0,0 +1,135 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Backend\Model\Search;
+
+use Magento\TestFramework\Helper\Bootstrap;
+
+/**
+ * @magentoAppArea adminhtml
+ * @magentoDataFixture Magento/Sales/_files/order.php
+ * @magentoDataFixture Magento/Sales/_files/order_shipping_address_different_to_billing.php
+ */
+class OrderTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @dataProvider loadDataProvider
+     */
+    public function testLoad($query, $limit, $start, $expectedResult)
+    {
+        /** @var $order \Magento\Sales\Model\Order */
+        $order = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Sales\Model\Order');
+        $orderIdByIncrementId = [];
+        foreach (['100000001', '100000002', '100000003'] as $incrementId) {
+            $orderIdByIncrementId[$incrementId] = $order->loadByIncrementId($incrementId)->getId();
+        }
+
+        /** Preconditions */
+        $objectManager = Bootstrap::getObjectManager();
+        /** @var \Magento\Backend\Model\Search\Order $orderSearch */
+        $orderSearch = $objectManager->create('Magento\Backend\Model\Search\Order');
+        $orderSearch->setQuery($query);
+        $orderSearch->setLimit($limit);
+        $orderSearch->setStart($start);
+        $orderSearch->load();
+
+        /** SUT Execution */
+        $searchResults = $orderSearch->getResults();
+
+        /** Ensure that search results are correct */
+        $this->assertCount(count($expectedResult), $searchResults, 'Quantity of search result items is invalid.');
+        foreach ($expectedResult as $itemIndex => $expectedItem) {
+            /** Validate URL to item */
+            $orderIncrementId = substr($expectedItem['id'], strlen('order/1/#'));
+            $this->assertContains(
+                "order/view/order_id/{$orderIdByIncrementId[$orderIncrementId]}",
+                $searchResults[$itemIndex]['url'],
+                'Item URL is invalid.'
+            );
+            $expectedItem['id'] = 'order/1/' . $orderIdByIncrementId[$orderIncrementId];
+            unset($searchResults[$itemIndex]['url']);
+
+            /** Validate other item data */
+            foreach ($expectedItem as $field => $value) {
+                $this->assertEquals(
+                    $value,
+                    (string)$searchResults[$itemIndex][$field],
+                    "Data of item #$itemIndex is invalid."
+                );
+            }
+        }
+    }
+
+    public static function loadDataProvider()
+    {
+        return [
+            'All items, first page' => [
+                '10000000',
+                2, // Items on page
+                1, // Page number
+                [
+                    [
+                        'id' => 'order/1/#100000001',
+                        'type' => 'Order',
+                        'name' => 'Order #100000001',
+                        'description' => 'firstname lastname',
+                    ],
+                    [
+                        'id' => 'order/1/#100000002',
+                        'type' => 'Order',
+                        'name' => 'Order #100000002',
+                        'description' => 'guest guest'
+                    ]
+                ],
+            ],
+            'All items, second page' => [
+                '10000000',
+                2, // Items on page
+                2, // Page number
+                [
+                    [
+                        'id' => 'order/1/#100000003',
+                        'type' => 'Order',
+                        'name' => 'Order #100000003',
+                        'description' => 'guest guest',
+                    ]
+                ],
+            ],
+            'Search by first name, first item only' => [
+                'First',
+                10, // Items on page
+                1, // Page number
+                [
+                    [
+                        'id' => 'order/1/#100000001',
+                        'type' => 'Order',
+                        'name' => 'Order #100000001',
+                        'description' => 'firstname lastname',
+                    ]
+                ],
+            ],
+            'No results' => [
+                'NotExistingOrder',
+                10, // Items on page
+                1, // Page number
+                [],
+            ],
+            'Search by last name, first item only' => [
+                'last',
+                10, // Items on page
+                1, // Page number
+                [
+                    [
+                        'id' => 'order/1/#100000001',
+                        'type' => 'Order',
+                        'name' => 'Order #100000001',
+                        'description' => 'firstname lastname',
+                    ]
+                ],
+            ],
+        ];
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Email/Block/Adminhtml/Template/Edit/FormTest.php b/dev/tests/integration/testsuite/Magento/Email/Block/Adminhtml/Template/Edit/FormTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..035efbb3bb89879982b67db8f958456ad61b84c2
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Email/Block/Adminhtml/Template/Edit/FormTest.php
@@ -0,0 +1,91 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Email\Block\Adminhtml\Template\Edit;
+
+/**
+ * Test class for \Magento\Email\Block\Adminhtml\Template\Edit\Form
+ * @magentoAppArea adminhtml
+ * @magentoAppIsolation enabled
+ */
+class FormTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var string[] */
+    protected $expectedFields;
+
+    /** @var Magento\Email\Model\Template */
+    protected $template;
+
+    /** @var Magento\Framework\TestFramework\Unit\Helper\ObjectManager */
+    protected $objectManager;
+
+    /** @var \Magento\Framework\Registry */
+    protected $registry;
+
+    /** @var \Magento\Email\Block\Adminhtml\Template\Edit\Form */
+    protected $block;
+
+    /** @var \ReflectionMethod */
+    protected $prepareFormMethod;
+
+    public function setUp()
+    {
+        $this->expectedFields = [
+            'base_fieldset',
+            'template_code',
+            'template_subject',
+            'orig_template_variables',
+            'variables',
+            'template_variables',
+            'insert_variable',
+            'template_text',
+            'template_styles'
+        ];
+
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        $this->template = $this->objectManager->get('Magento\Email\Model\Template')
+            ->setId(1)
+            ->setTemplateType(\Magento\Framework\App\TemplateTypesInterface::TYPE_HTML);
+        $this->registry = $this->objectManager->get('Magento\Framework\Registry');
+        if ($this->registry->registry('current_email_template') == null) {
+            $this->registry->register('current_email_template', $this->template);
+        }
+        $this->block = $this->objectManager->create('Magento\Email\Block\Adminhtml\Template\Edit\Form');
+        $this->prepareFormMethod = new \ReflectionMethod(
+            'Magento\Email\Block\Adminhtml\Template\Edit\Form',
+            '_prepareForm'
+        );
+        $this->prepareFormMethod->setAccessible(true);
+    }
+
+    /**
+     * @covers \Magento\Email\Block\Adminhtml\Template\Edit\Form::_prepareForm
+     */
+    public function testPrepareFormWithTemplateId()
+    {
+        $this->expectedFields[] = 'used_currently_for';
+        $this->runTest();
+    }
+
+    /**
+     * @covers \Magento\Email\Block\Adminhtml\Template\Edit\Form::_prepareForm
+     */
+    public function testPrepareFormWithoutTemplateId()
+    {
+        $this->template->setId(null);
+        $this->expectedFields[] = 'used_default_for';
+        $this->runTest();
+    }
+
+    protected function runTest()
+    {
+        $this->prepareFormMethod->invoke($this->block);
+        $form = $this->block->getForm();
+        foreach ($this->expectedFields as $key) {
+            $this->assertNotNull($form->getElement($key));
+        }
+        $this->assertGreaterThan(0, strpos($form->getElement('insert_variable')->getData('text'), 'Insert Variable'));
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Email/Model/TemplateTest.php b/dev/tests/integration/testsuite/Magento/Email/Model/TemplateTest.php
index 72cbb8f071d6f7b0a8cdd2574bc3ccb6005eabe1..f7c9bcc53653adc6854ac860d56bab6bf17a6da3 100644
--- a/dev/tests/integration/testsuite/Magento/Email/Model/TemplateTest.php
+++ b/dev/tests/integration/testsuite/Magento/Email/Model/TemplateTest.php
@@ -201,4 +201,104 @@ class TemplateTest extends \PHPUnit_Framework_TestCase
             [['store' => $storeId]],
         ];
     }
+
+    public function testSetAndGetId()
+    {
+        $testId = 9999;
+        $this->_model->setId($testId);
+        $this->assertEquals($testId, $this->_model->getId());
+    }
+
+    public function testIsValidForSend()
+    {
+        $this->assertTrue($this->_model->isValidForSend());
+    }
+
+    /**
+     * @expectedException \UnexpectedValueException
+     * @expectedExceptionMessage Email template 'foo' is not defined.
+     */
+    public function testGetTypeNonExistentType()
+    {
+        $this->_model->setId('foo');
+        $this->_model->getType();
+    }
+
+    public function testGetTypeHtml()
+    {
+        $this->_model->setId('customer_create_account_email_template');
+        $this->assertEquals(\Magento\Framework\App\TemplateTypesInterface::TYPE_HTML, $this->_model->getType());
+    }
+
+    public function testGetType()
+    {
+        $templateTypeId = 'test_template';
+        $this->_model->setTemplateType($templateTypeId);
+        $this->assertEquals($templateTypeId, $this->_model->getType());
+    }
+
+    public function testGetPreparedTemplateText()
+    {
+        $this->_model->loadDefault('customer_create_account_email_template');
+        $this->assertContains('<body style', $this->_model->getPreparedTemplateText());
+    }
+
+    public function testGetSendingException()
+    {
+        $this->assertNull($this->_model->getSendingException());
+    }
+
+    public function testGetVariablesOptionArray()
+    {
+        $testTemplateVariables = '{"var data.name":"Sender Name","var data.email":"Sender Email"}';
+        $this->_model->setOrigTemplateVariables($testTemplateVariables);
+        $variablesOptionArray = $this->_model->getVariablesOptionArray();
+        $this->assertEquals('{{var data.name}}', $variablesOptionArray[0]['value']);
+        $this->assertEquals('Sender Name', $variablesOptionArray[0]['label']->getArguments()[0]);
+        $this->assertEquals('{{var data.email}}', $variablesOptionArray[1]['value']);
+        $this->assertEquals('Sender Email', $variablesOptionArray[1]['label']->getArguments()[0]);
+    }
+
+    public function testGetVariablesOptionArrayInGroup()
+    {
+        $testTemplateVariables = '{"var data.name":"Sender Name","var data.email":"Sender Email"}';
+        $this->_model->setOrigTemplateVariables($testTemplateVariables);
+        $variablesOptionArray = $this->_model->getVariablesOptionArray(true);
+        $this->assertEquals('Template Variables', $variablesOptionArray['label']->getText());
+        $this->assertEquals($this->_model->getVariablesOptionArray(), $variablesOptionArray['value']);
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Mail\Exception
+     * @expectedExceptionMessage The template Name must not be empty.
+     */
+    public function testBeforeSaveEmptyTemplateCode()
+    {
+        $this->_model->beforeSave();
+    }
+
+    public function testBeforeSave()
+    {
+        $this->_model->setTemplateCode('test template code');
+        $this->_model->beforeSave();
+    }
+
+    public function testProcessTemplate()
+    {
+        $this->_model->setId('customer_create_account_email_template');
+        $this->assertContains('<body style', $this->_model->processTemplate());
+    }
+
+    public function testGetSubject()
+    {
+        $this->_model->setVars(['foo', 'bar', 'baz']);
+        $this->assertEquals('Subject', $this->_model->getSubject());
+    }
+
+    public function testSetOptions()
+    {
+        $options = ['area' => 'test area', 'store' => 1];
+        $this->_model->setOptions($options);
+        $this->assertEquals($options, $this->_model->getDesignConfig()->getData());
+    }
 }
diff --git a/dev/tests/integration/testsuite/Magento/GiftMessage/Model/OrderItemRepositoryTest.php b/dev/tests/integration/testsuite/Magento/GiftMessage/Model/OrderItemRepositoryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..18532c48952e48d2f1abd65f62514eeb45c7acbf
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/GiftMessage/Model/OrderItemRepositoryTest.php
@@ -0,0 +1,163 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\GiftMessage\Model;
+
+class OrderItemRepositoryTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\Framework\ObjectManagerInterface */
+    protected $objectManager;
+
+    /** @var \Magento\GiftMessage\Model\Message */
+    protected $message;
+
+    /** @var \Magento\GiftMessage\Model\OrderItemRepository */
+    protected $giftMessageOrderItemRepository;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+
+        $this->message = $this->objectManager->create('Magento\GiftMessage\Model\Message');
+        $this->message->setSender('Romeo');
+        $this->message->setRecipient('Mercutio');
+        $this->message->setMessage('I thought all for the best.');
+
+        $this->giftMessageOrderItemRepository = $this->objectManager->create(
+            'Magento\GiftMessage\Model\OrderItemRepository'
+        );
+
+    }
+
+    protected function tearDown()
+    {
+        unset($this->objectManager);
+        unset($this->message);
+        unset($this->giftMessageOrderItemRepository);
+    }
+
+    /**
+     * @magentoDataFixture Magento/GiftMessage/_files/order_with_message.php
+     * @magentoConfigFixture default_store sales/gift_options/allow_items 1
+     */
+    public function testGet()
+    {
+        /** @var \Magento\Sales\Model\Order $order */
+        $order = $this->objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId('100000001');
+        /** @var \Magento\Sales\Api\Data\OrderItemInterface $orderItem */
+        $orderItem = $order->getItems();
+        $orderItem = array_shift($orderItem);
+
+        /** @var \Magento\GiftMessage\Api\Data\MessageInterface $message */
+        $message = $this->giftMessageOrderItemRepository->get($order->getEntityId(), $orderItem->getItemId());
+        $this->assertEquals('Romeo', $message->getSender());
+        $this->assertEquals('Mercutio', $message->getRecipient());
+        $this->assertEquals('I thought all for the best.', $message->getMessage());
+    }
+
+    /**
+     * @magentoDataFixture Magento/GiftMessage/_files/order_with_message.php
+     * @magentoConfigFixture default_store sales/gift_options/allow_items 1
+     * @expectedException \Magento\Framework\Exception\NoSuchEntityException
+     * @expectedExceptionMessage There is no item with provided id in the order
+     */
+    public function testGetNoProvidedItemId()
+    {
+        /** @var \Magento\Sales\Model\Order $order */
+        $order = $this->objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId('100000001');
+        /** @var \Magento\Sales\Api\Data\OrderItemInterface $orderItem */
+        $orderItem = $order->getItems();
+        $orderItem = array_shift($orderItem);
+
+        /** @var \Magento\GiftMessage\Api\Data\MessageInterface $message */
+        $this->giftMessageOrderItemRepository->get($order->getEntityId(), $orderItem->getItemId() * 10);
+    }
+
+    /**
+     * @magentoDataFixture Magento/Sales/_files/order.php
+     * @magentoConfigFixture default_store sales/gift_options/allow_items 1
+     */
+    public function testSave()
+    {
+        /** @var \Magento\Sales\Model\Order $order */
+        $order = $this->objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId('100000001');
+        /** @var \Magento\Sales\Api\Data\OrderItemInterface $orderItem */
+        $orderItem = $order->getItems();
+        $orderItem = array_shift($orderItem);
+
+        /** @var \Magento\GiftMessage\Api\Data\MessageInterface $message */
+        $result = $this->giftMessageOrderItemRepository->save(
+            $order->getEntityId(),
+            $orderItem->getItemId(),
+            $this->message
+        );
+
+        $message = $this->giftMessageOrderItemRepository->get($order->getEntityId(), $orderItem->getItemId());
+
+        $this->assertTrue($result);
+        $this->assertEquals('Romeo', $message->getSender());
+        $this->assertEquals('Mercutio', $message->getRecipient());
+        $this->assertEquals('I thought all for the best.', $message->getMessage());
+    }
+
+
+    /**
+     * @magentoDataFixture Magento/Sales/_files/order.php
+     * @magentoConfigFixture default_store sales/gift_options/allow_items 0
+     * @expectedException \Magento\Framework\Exception\CouldNotSaveException
+     * @expectedExceptionMessage Gift Message is not available
+     */
+    public function testSaveMessageIsNotAvailable()
+    {
+        /** @var \Magento\Sales\Model\Order $order */
+        $order = $this->objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId('100000001');
+        /** @var \Magento\Sales\Api\Data\OrderItemInterface $orderItem */
+        $orderItem = $order->getItems();
+        $orderItem = array_shift($orderItem);
+
+        /** @var \Magento\GiftMessage\Api\Data\MessageInterface $message */
+        $this->giftMessageOrderItemRepository->save($order->getEntityId(), $orderItem->getItemId(), $this->message);
+    }
+
+    /**
+     * @magentoDataFixture Magento/GiftMessage/_files/virtual_order.php
+     * @magentoConfigFixture default_store sales/gift_options/allow_items 1
+     * @expectedException \Magento\Framework\Exception\State\InvalidTransitionException
+     * @expectedExceptionMessage Gift Messages is not applicable for virtual products
+     */
+    public function testSaveMessageIsVirtual()
+    {
+        /** @var \Magento\Sales\Model\Order $order */
+        $order = $this->objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId('100000001');
+        /** @var \Magento\Sales\Api\Data\OrderItemInterface $orderItem */
+        $orderItem = $order->getItems();
+        $orderItem = array_shift($orderItem);
+
+        /** @var \Magento\GiftMessage\Api\Data\MessageInterface $message */
+        $this->giftMessageOrderItemRepository->save($order->getEntityId(), $orderItem->getItemId(), $this->message);
+    }
+
+    /**
+     * @magentoDataFixture Magento/GiftMessage/_files/empty_order.php
+     * @magentoConfigFixture default_store sales/gift_options/allow_items 1
+     * @expectedException  \Magento\Framework\Exception\NoSuchEntityException
+     * @expectedExceptionMessage There is no item with provided id in the order
+     */
+    public function testSaveMessageNoProvidedItemId()
+    {
+        /** @var \Magento\Sales\Model\Order $order */
+        $order = $this->objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId('100000001');
+        /** @var \Magento\Sales\Api\Data\OrderItemInterface $orderItem */
+        $orderItem = $order->getItems();
+        $orderItem = array_shift($orderItem);
+
+        /** @var \Magento\GiftMessage\Api\Data\MessageInterface $message */
+        $this->giftMessageOrderItemRepository->save(
+            $order->getEntityId(),
+            $orderItem->getItemId() * 10,
+            $this->message
+        );
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/GiftMessage/Model/OrderRepositoryTest.php b/dev/tests/integration/testsuite/Magento/GiftMessage/Model/OrderRepositoryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..f47174a49cf265d42dd203ad3d758b605606d552
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/GiftMessage/Model/OrderRepositoryTest.php
@@ -0,0 +1,133 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\GiftMessage\Model;
+
+class OrderRepositoryTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\Framework\ObjectManagerInterface */
+    protected $objectManager;
+
+    /** @var \Magento\GiftMessage\Model\Message */
+    protected $message;
+
+    /** @var \Magento\GiftMessage\Model\OrderRepository */
+    protected $giftMessageOrderRepository;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+
+        $this->message = $this->objectManager->create('Magento\GiftMessage\Model\Message');
+        $this->message->setSender('Romeo');
+        $this->message->setRecipient('Mercutio');
+        $this->message->setMessage('I thought all for the best.');
+
+        $this->giftMessageOrderRepository = $this->objectManager->create('Magento\GiftMessage\Model\OrderRepository');
+    }
+
+    protected function tearDown()
+    {
+        unset($this->objectManager);
+        unset($this->message);
+        unset($this->giftMessageOrderRepository);
+    }
+
+    /**
+     * @magentoDataFixture Magento/GiftMessage/_files/order_with_message.php
+     * @magentoConfigFixture default_store sales/gift_options/allow_order 1
+     */
+    public function testGet()
+    {
+        /** @var \Magento\Sales\Model\Order $order */
+        $order = $this->objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId('100000001');
+
+        /** @var \Magento\GiftMessage\Api\Data\MessageInterface $message */
+        $message = $this->giftMessageOrderRepository->get($order->getEntityId());
+        $this->assertEquals('Romeo', $message->getSender());
+        $this->assertEquals('Mercutio', $message->getRecipient());
+        $this->assertEquals('I thought all for the best.', $message->getMessage());
+    }
+
+    /**
+     * @magentoDataFixture Magento/Sales/_files/order.php
+     * @magentoConfigFixture default_store sales/gift_options/allow_order 1
+     */
+    public function testSave()
+    {
+        /** @var \Magento\Sales\Model\Order $order */
+        $order = $this->objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId('100000001');
+
+        /** @var \Magento\GiftMessage\Api\Data\MessageInterface $message */
+        $result = $this->giftMessageOrderRepository->save($order->getEntityId(), $this->message);
+
+        $message = $this->giftMessageOrderRepository->get($order->getEntityId());
+
+        $this->assertTrue($result);
+        $this->assertEquals('Romeo', $message->getSender());
+        $this->assertEquals('Mercutio', $message->getRecipient());
+        $this->assertEquals('I thought all for the best.', $message->getMessage());
+    }
+
+    /**
+     * @magentoDataFixture Magento/Sales/_files/order.php
+     * @magentoConfigFixture default_store sales/gift_options/allow_order 0
+     * @expectedException \Magento\Framework\Exception\CouldNotSaveException
+     * @expectedExceptionMessage Gift Message is not available
+     */
+    public function testSaveMessageIsNotAvailable()
+    {
+        /** @var \Magento\Sales\Model\Order $order */
+        $order = $this->objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId('100000001');
+
+        /** @var \Magento\GiftMessage\Api\Data\MessageInterface $message */
+        $this->giftMessageOrderRepository->save($order->getEntityId(), $this->message);
+    }
+
+    /**
+     * @magentoDataFixture Magento/GiftMessage/_files/virtual_order.php
+     * @magentoConfigFixture default_store sales/gift_options/allow_order 1
+     * @expectedException \Magento\Framework\Exception\State\InvalidTransitionException
+     * @expectedExceptionMessage Gift Messages is not applicable for virtual products
+     */
+    public function testSaveMessageIsVirtual()
+    {
+        /** @var \Magento\Sales\Model\Order $order */
+        $order = $this->objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId('100000001');
+
+        /** @var \Magento\GiftMessage\Api\Data\MessageInterface $message */
+        $this->giftMessageOrderRepository->save($order->getEntityId(), $this->message);
+    }
+
+    /**
+     * @magentoDataFixture Magento/GiftMessage/_files/empty_order.php
+     * @magentoConfigFixture default_store sales/gift_options/allow_order 1
+     * @expectedException \Magento\Framework\Exception\InputException
+     * @expectedExceptionMessage Gift Messages is not applicable for empty order
+     */
+    public function testSaveMessageIsEmpty()
+    {
+        /** @var \Magento\Sales\Model\Order $order */
+        $order = $this->objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId('100000001');
+
+        /** @var \Magento\GiftMessage\Api\Data\MessageInterface $message */
+        $this->giftMessageOrderRepository->save($order->getEntityId(), $this->message);
+    }
+
+    /**
+     * @magentoDataFixture Magento/GiftMessage/_files/empty_order.php
+     * @magentoConfigFixture default_store sales/gift_options/allow_order 1
+     * @expectedException  \Magento\Framework\Exception\NoSuchEntityException
+     * @expectedExceptionMessage There is no order with provided id
+     */
+    public function testSaveMessageNoProvidedItemId()
+    {
+        /** @var \Magento\Sales\Model\Order $order */
+        $order = $this->objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId('100000001');
+
+        /** @var \Magento\GiftMessage\Api\Data\MessageInterface $message */
+        $this->giftMessageOrderRepository->save($order->getEntityId() * 10, $this->message);
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/GiftMessage/_files/empty_order.php b/dev/tests/integration/testsuite/Magento/GiftMessage/_files/empty_order.php
new file mode 100644
index 0000000000000000000000000000000000000000..40a28f6d051f7f6b53e491ceaa44a195d15d56f4
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/GiftMessage/_files/empty_order.php
@@ -0,0 +1,12 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+require __DIR__ . '/../../../Magento/Sales/_files/order.php';
+/** @var \Magento\Sales\Model\Order $order */
+
+$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+
+$order = $objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId('100000001');
+$order->setItems([])->setTotalItemCount(0)->save();
diff --git a/dev/tests/integration/testsuite/Magento/GiftMessage/_files/order_with_message.php b/dev/tests/integration/testsuite/Magento/GiftMessage/_files/order_with_message.php
new file mode 100644
index 0000000000000000000000000000000000000000..b99eddea282846771d77bfc51cf101789e191b52
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/GiftMessage/_files/order_with_message.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+require __DIR__ . '/../../../Magento/Sales/_files/order.php';
+
+$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+
+/** @var \Magento\GiftMessage\Model\Message $message */
+$message = $objectManager->create('Magento\GiftMessage\Model\Message');
+$message->setSender('Romeo');
+$message->setRecipient('Mercutio');
+$message->setMessage('I thought all for the best.');
+$message->save();
+
+/** @var \Magento\Sales\Model\Order $order */
+$order = $objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId('100000001');
+
+/** @var \Magento\Sales\Api\Data\OrderItemInterface $orderItem */
+$orderItem = $order->getItems();
+$orderItem = array_shift($orderItem);
+$orderItem->setGiftMessageId($message->getId());
+
+$order->setItems([$orderItem])->setGiftMessageId($message->getId());
+$order->save();
diff --git a/dev/tests/integration/testsuite/Magento/GiftMessage/_files/virtual_order.php b/dev/tests/integration/testsuite/Magento/GiftMessage/_files/virtual_order.php
new file mode 100644
index 0000000000000000000000000000000000000000..1e33aba1663cb9c01beb1cbf0d53c0cd61e3ca8b
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/GiftMessage/_files/virtual_order.php
@@ -0,0 +1,12 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+require __DIR__ . '/../../../Magento/Sales/_files/order.php';
+/** @var \Magento\Sales\Model\Order $order */
+
+$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+
+$order = $objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId('100000001');
+$order->setIsVirtual(1)->save();
diff --git a/dev/tests/integration/testsuite/Magento/Multishipping/Controller/CheckoutTest.php b/dev/tests/integration/testsuite/Magento/Multishipping/Controller/CheckoutTest.php
index c70148b0ffcdf0a06f2076da845c4d17349ac51f..f4022f124511e6ff7e953af51754645b55399e28 100644
--- a/dev/tests/integration/testsuite/Magento/Multishipping/Controller/CheckoutTest.php
+++ b/dev/tests/integration/testsuite/Magento/Multishipping/Controller/CheckoutTest.php
@@ -5,51 +5,65 @@
  */
 namespace Magento\Multishipping\Controller;
 
-use Magento\TestFramework\Helper\Bootstrap;
+use \Magento\Multishipping\Model\Checkout\Type\Multishipping\State;
 
 /**
  * Test class for \Magento\Multishipping\Controller\Checkout
  *
  * @magentoAppArea frontend
+ * @magentoDataFixture Magento/Sales/_files/quote.php
+ * @magentoDataFixture Magento/Customer/_files/customer.php
  */
 class CheckoutTest extends \Magento\TestFramework\TestCase\AbstractController
 {
     /**
-     * Covers app/code/Magento/Checkout/Block/Multishipping/Payment/Info.php
-     * and app/code/Magento/Checkout/Block/Multishipping/Overview.php
+     * @var \Magento\Quote\Model\Quote
+     */
+    protected $quote;
+
+    /**
+     * @var \Magento\Checkout\Model\Session
+     */
+    protected $checkoutSession;
+
+    /**
+     * @inheritdoc
+     */
+    public function setUp()
+    {
+        parent::setUp();
+        $this->quote = $this->_objectManager->create('Magento\Quote\Model\Quote');
+        $this->checkoutSession = $this->_objectManager->get('Magento\Checkout\Model\Session');
+
+        $this->quote->load('test01', 'reserved_order_id');
+        $this->checkoutSession->setQuoteId($this->quote->getId());
+        $this->checkoutSession->setCartWasUpdated(false);
+    }
+
+    /**
+     * Covers \Magento\Multishipping\Block\Checkout\Payment\Info and \Magento\Multishipping\Block\Checkout\Overview
      *
-     * @magentoDataFixture Magento/Sales/_files/quote.php
-     * @magentoDataFixture Magento/Customer/_files/customer.php
      * @magentoConfigFixture current_store multishipping/options/checkout_multiple 1
      */
     public function testOverviewAction()
     {
-        /** @var $quote \Magento\Quote\Model\Quote */
-        $quote = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Quote\Model\Quote');
-        $quote->load('test01', 'reserved_order_id');
-
-        \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Checkout\Model\Session')
-            ->setQuoteId($quote->getId());
-
+        /** @var \Magento\Framework\Data\Form\FormKey $formKey */
         $formKey = $this->_objectManager->get('Magento\Framework\Data\Form\FormKey');
         $logger = $this->getMock('Psr\Log\LoggerInterface', [], [], '', false);
-
-        /** @var $session \Magento\Customer\Model\Session */
-        $session = Bootstrap::getObjectManager()->create('Magento\Customer\Model\Session', [$logger]);
-
-        /** @var \Magento\Customer\Api\AccountManagementInterface  $service */
-        $service = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
-            ->create('Magento\Customer\Api\AccountManagementInterface');
+        /** @var \Magento\Customer\Api\AccountManagementInterface $service */
+        $service = $this->_objectManager->create('Magento\Customer\Api\AccountManagementInterface');
         $customer = $service->authenticate('customer@example.com', 'password');
-
-        $session->setCustomerDataAsLoggedIn($customer);
+        /** @var \Magento\Customer\Model\Session $customerSession */
+        $customerSession = $this->_objectManager->create('Magento\Customer\Model\Session', [$logger]);
+        $customerSession->setCustomerDataAsLoggedIn($customer);
+        $this->checkoutSession->setCheckoutState(State::STEP_BILLING);
         $this->getRequest()->setPostValue('payment', ['method' => 'checkmo']);
         $this->dispatch('multishipping/checkout/overview');
         $html = $this->getResponse()->getBody();
         $this->assertContains('<div class="box box-billing-method">', $html);
         $this->assertContains('<div class="box box-shipping-method">', $html);
         $this->assertContains(
-            '<dt class="title">' . $quote->getPayment()->getMethodInstance()->getTitle() . '</dt>',
+            '<dt class="title">' . $this->quote->getPayment()->getMethodInstance()->getTitle() . '</dt>',
             $html
         );
         $this->assertContains('<span class="price">$10.00</span>', $html);
diff --git a/dev/tests/integration/testsuite/Magento/Sales/Model/AdminOrder/CreateTest.php b/dev/tests/integration/testsuite/Magento/Sales/Model/AdminOrder/CreateTest.php
index d53554db1622aaf000606fd11378630584e89d7a..ab65efa40a0ec16a5e87507b90e0cde8139b8377 100644
--- a/dev/tests/integration/testsuite/Magento/Sales/Model/AdminOrder/CreateTest.php
+++ b/dev/tests/integration/testsuite/Magento/Sales/Model/AdminOrder/CreateTest.php
@@ -83,7 +83,7 @@ class CreateTest extends \PHPUnit_Framework_TestCase
 
         /** @var $order \Magento\Sales\Model\Order */
         $order = $objectManager->create('Magento\Sales\Model\Order');
-        $order->loadByIncrementId('100000001');
+        $order->loadByIncrementId('100000002');
 
         $this->assertNull($order->getShippingAddress()->getSameAsBilling());
 
diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/order_shipping_address_different_to_billing.php b/dev/tests/integration/testsuite/Magento/Sales/_files/order_shipping_address_different_to_billing.php
index d46172f603d9538db67d078db203080b47664b6a..9a4f95e5fbf0199ea442e40f1c18152d08cf7d82 100644
--- a/dev/tests/integration/testsuite/Magento/Sales/_files/order_shipping_address_different_to_billing.php
+++ b/dev/tests/integration/testsuite/Magento/Sales/_files/order_shipping_address_different_to_billing.php
@@ -30,13 +30,21 @@ $shippingAddress->setId(null)->setPostcode('2')->setAddressType('shipping');
 $order = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Sales\Model\Order');
 $order->loadByIncrementId('100000001');
 $clonedOrder = clone $order;
-$order->setIncrementId('100000002');
-$order->save();
 
 /** @var $payment \Magento\Sales\Model\Order\Payment */
 $payment = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Sales\Model\Order\Payment');
 $payment->setMethod('checkmo');
+$clonedOrder->setIncrementId('100000002')
+    ->setId(null)
+    ->setBillingAddress($billingAddress)
+    ->setShippingAddress($shippingAddress)
+    ->setPayment($payment);
+$clonedOrder->save();
 
-$order = $clonedOrder;
-$order->setId(null)->setBillingAddress($billingAddress)->setShippingAddress($shippingAddress)->setPayment($payment);
-$order->save();
+$secondClonedOrder = clone $order;
+$secondClonedOrder->setIncrementId('100000003')
+    ->setId(null)
+    ->setBillingAddress($billingAddress->setId(null))
+    ->setShippingAddress($shippingAddress->setId(null))
+    ->setPayment($payment->setId(null));
+$secondClonedOrder->save();
diff --git a/dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/UserTest.php b/dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/UserTest.php
index 0fa5bfb6712bbf3d47504100f45b355cc980f4da..f7de99380e8423f158736487530959823e2fb917 100644
--- a/dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/UserTest.php
+++ b/dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/UserTest.php
@@ -95,6 +95,32 @@ class UserTest extends \Magento\Backend\Utility\Controller
         $this->assertRedirect($this->stringContains('backend/admin/user/index/'));
     }
 
+    /**
+     * @magentoDbIsolation enabled
+     * @magentoDataFixture Magento/User/_files/user_with_role.php
+     */
+    public function testSaveActionDuplicateUser()
+    {
+        $this->getRequest()->setPostValue(
+            [
+                'username' => 'adminUser',
+                'email' => 'adminUser@example.com',
+                'firstname' => 'John',
+                'lastname' => 'Doe',
+                'password' => \Magento\TestFramework\Bootstrap::ADMIN_PASSWORD,
+                'password_confirmation' => \Magento\TestFramework\Bootstrap::ADMIN_PASSWORD,
+                \Magento\User\Block\User\Edit\Tab\Main::CURRENT_USER_PASSWORD_FIELD => Bootstrap::ADMIN_PASSWORD,
+            ]
+        );
+        $this->dispatch('backend/admin/user/save/active_tab/main_section');
+        $this->assertSessionMessages(
+            $this->equalTo(['A user with the same user name or email already exists.']),
+            \Magento\Framework\Message\MessageInterface::TYPE_ERROR
+        );
+        $this->assertRedirect($this->stringContains('backend/admin/user/edit/'));
+        $this->assertRedirect($this->matchesRegularExpression('/^((?!active_tab).)*$/'));
+    }
+
     /**
      * @magentoDbIsolation enabled
      * @dataProvider resetPasswordDataProvider
diff --git a/dev/tests/js/.gitignore b/dev/tests/js/JsTestDriver/.gitignore
similarity index 100%
rename from dev/tests/js/.gitignore
rename to dev/tests/js/JsTestDriver/.gitignore
diff --git a/dev/tests/js/framework/qunit/qunit-1.14.0.css b/dev/tests/js/JsTestDriver/framework/qunit/qunit-1.14.0.css
similarity index 100%
rename from dev/tests/js/framework/qunit/qunit-1.14.0.css
rename to dev/tests/js/JsTestDriver/framework/qunit/qunit-1.14.0.css
diff --git a/dev/tests/js/framework/qunit/qunit-1.14.0.js b/dev/tests/js/JsTestDriver/framework/qunit/qunit-1.14.0.js
similarity index 100%
rename from dev/tests/js/framework/qunit/qunit-1.14.0.js
rename to dev/tests/js/JsTestDriver/framework/qunit/qunit-1.14.0.js
diff --git a/dev/tests/js/framework/requirejs-util.js b/dev/tests/js/JsTestDriver/framework/requirejs-util.js
similarity index 100%
rename from dev/tests/js/framework/requirejs-util.js
rename to dev/tests/js/JsTestDriver/framework/requirejs-util.js
diff --git a/dev/tests/js/framework/stub.js b/dev/tests/js/JsTestDriver/framework/stub.js
similarity index 100%
rename from dev/tests/js/framework/stub.js
rename to dev/tests/js/JsTestDriver/framework/stub.js
diff --git a/dev/tests/js/jsTestDriver.php.dist b/dev/tests/js/JsTestDriver/jsTestDriver.php.dist
similarity index 92%
rename from dev/tests/js/jsTestDriver.php.dist
rename to dev/tests/js/JsTestDriver/jsTestDriver.php.dist
index 49d93ba262e50d6a6c5916bbf82ad731d659994d..e3f8985644d0bcfc909b299627cf885f045d6099 100644
--- a/dev/tests/js/jsTestDriver.php.dist
+++ b/dev/tests/js/JsTestDriver/jsTestDriver.php.dist
@@ -11,7 +11,7 @@
 return array(
     'server' => 'http://localhost:9876',
     'load' => array(
-        '/dev/tests/js/framework',
+        '/dev/tests/js/JsTestDriver/framework',
         '/lib/web/mage/webapi.js',
         '/lib/web/mage/validation/validation.js',
         '/app/code/Magento/DesignEditor/view/adminhtml/web/js/infinitescroll.js',
@@ -33,6 +33,6 @@ return array(
         '/lib/web/mage/gallery-fullscreen.js',
         '/lib/web/mage/zoom.js',
     ),
-    'test' => array('/dev/tests/js/testsuite'),
+    'test' => array('/dev/tests/js/JsTestDriver/testsuite'),
     'JsTestDriver' => '{{path_to_jstestdriver_jar}}'
 );
diff --git a/dev/tests/js/jsTestDriverOrder.php b/dev/tests/js/JsTestDriver/jsTestDriverOrder.php
similarity index 92%
rename from dev/tests/js/jsTestDriverOrder.php
rename to dev/tests/js/JsTestDriver/jsTestDriverOrder.php
index 763e221c28cde73759221a3980d0e34758b5e303..b12aef10f57a3c4eea9993b1fa2092e7c5848e56 100644
--- a/dev/tests/js/jsTestDriverOrder.php
+++ b/dev/tests/js/JsTestDriver/jsTestDriverOrder.php
@@ -14,7 +14,7 @@ return [
     '/lib/web/underscore.js',
     '/lib/web/mage/template.js',
     '/lib/web/jquery/jquery-ui-1.9.2.js',
-    '/dev/tests/js/framework/requirejs-util.js',
+    '/dev/tests/js/JsTestDriver/framework/requirejs-util.js',
     '/lib/web/jquery/jquery.cookie.js',
     '/lib/web/mage/apply/main.js',
     '/lib/web/mage/mage.js',
diff --git a/dev/tests/js/run_js_tests.php b/dev/tests/js/JsTestDriver/run_js_tests.php
similarity index 98%
rename from dev/tests/js/run_js_tests.php
rename to dev/tests/js/JsTestDriver/run_js_tests.php
index 3bafc3318adeb11d0e8a17e33ae776c124901861..846b4681e197d1d524d1eb21a5a03add3b909b13 100644
--- a/dev/tests/js/run_js_tests.php
+++ b/dev/tests/js/JsTestDriver/run_js_tests.php
@@ -6,8 +6,8 @@
  * See COPYING.txt for license details.
  */
 
-define('RELATIVE_APP_ROOT', '../../..');
-require __DIR__ . '/../../../app/autoload.php';
+define('RELATIVE_APP_ROOT', '../../../..');
+require __DIR__ . '/../../../../app/autoload.php';
 
 $userConfig = normalize('jsTestDriver.php');
 $defaultConfig = normalize('jsTestDriver.php.dist');
diff --git a/dev/tests/js/testsuite/lib/ko/datepicker/datepicker.js b/dev/tests/js/JsTestDriver/testsuite/lib/ko/datepicker/datepicker.js
similarity index 100%
rename from dev/tests/js/testsuite/lib/ko/datepicker/datepicker.js
rename to dev/tests/js/JsTestDriver/testsuite/lib/ko/datepicker/datepicker.js
diff --git a/dev/tests/js/testsuite/lib/ko/datepicker/index.html b/dev/tests/js/JsTestDriver/testsuite/lib/ko/datepicker/index.html
similarity index 100%
rename from dev/tests/js/testsuite/lib/ko/datepicker/index.html
rename to dev/tests/js/JsTestDriver/testsuite/lib/ko/datepicker/index.html
diff --git a/dev/tests/js/testsuite/lib/storage/index.html b/dev/tests/js/JsTestDriver/testsuite/lib/storage/index.html
similarity index 100%
rename from dev/tests/js/testsuite/lib/storage/index.html
rename to dev/tests/js/JsTestDriver/testsuite/lib/storage/index.html
diff --git a/dev/tests/js/testsuite/lib/storage/test-storage.js b/dev/tests/js/JsTestDriver/testsuite/lib/storage/test-storage.js
similarity index 100%
rename from dev/tests/js/testsuite/lib/storage/test-storage.js
rename to dev/tests/js/JsTestDriver/testsuite/lib/storage/test-storage.js
diff --git a/dev/tests/js/testsuite/mage/_demo/index.html b/dev/tests/js/JsTestDriver/testsuite/mage/_demo/index.html
similarity index 100%
rename from dev/tests/js/testsuite/mage/_demo/index.html
rename to dev/tests/js/JsTestDriver/testsuite/mage/_demo/index.html
diff --git a/dev/tests/js/testsuite/mage/_demo/test.js b/dev/tests/js/JsTestDriver/testsuite/mage/_demo/test.js
similarity index 100%
rename from dev/tests/js/testsuite/mage/_demo/test.js
rename to dev/tests/js/JsTestDriver/testsuite/mage/_demo/test.js
diff --git a/dev/tests/js/testsuite/mage/accordion/accordion.js b/dev/tests/js/JsTestDriver/testsuite/mage/accordion/accordion.js
similarity index 100%
rename from dev/tests/js/testsuite/mage/accordion/accordion.js
rename to dev/tests/js/JsTestDriver/testsuite/mage/accordion/accordion.js
diff --git a/dev/tests/js/testsuite/mage/accordion/index.html b/dev/tests/js/JsTestDriver/testsuite/mage/accordion/index.html
similarity index 100%
rename from dev/tests/js/testsuite/mage/accordion/index.html
rename to dev/tests/js/JsTestDriver/testsuite/mage/accordion/index.html
diff --git a/dev/tests/js/testsuite/mage/button/button-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/button/button-test.js
similarity index 100%
rename from dev/tests/js/testsuite/mage/button/button-test.js
rename to dev/tests/js/JsTestDriver/testsuite/mage/button/button-test.js
diff --git a/dev/tests/js/testsuite/mage/calendar/calendar-qunit.js b/dev/tests/js/JsTestDriver/testsuite/mage/calendar/calendar-qunit.js
similarity index 100%
rename from dev/tests/js/testsuite/mage/calendar/calendar-qunit.js
rename to dev/tests/js/JsTestDriver/testsuite/mage/calendar/calendar-qunit.js
diff --git a/dev/tests/js/testsuite/mage/calendar/calendar-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/calendar/calendar-test.js
similarity index 100%
rename from dev/tests/js/testsuite/mage/calendar/calendar-test.js
rename to dev/tests/js/JsTestDriver/testsuite/mage/calendar/calendar-test.js
diff --git a/dev/tests/js/testsuite/mage/calendar/calendar.html b/dev/tests/js/JsTestDriver/testsuite/mage/calendar/calendar.html
similarity index 100%
rename from dev/tests/js/testsuite/mage/calendar/calendar.html
rename to dev/tests/js/JsTestDriver/testsuite/mage/calendar/calendar.html
diff --git a/dev/tests/js/testsuite/mage/calendar/date-range-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/calendar/date-range-test.js
similarity index 100%
rename from dev/tests/js/testsuite/mage/calendar/date-range-test.js
rename to dev/tests/js/JsTestDriver/testsuite/mage/calendar/date-range-test.js
diff --git a/dev/tests/js/testsuite/mage/collapsible/content.html b/dev/tests/js/JsTestDriver/testsuite/mage/collapsible/content.html
similarity index 100%
rename from dev/tests/js/testsuite/mage/collapsible/content.html
rename to dev/tests/js/JsTestDriver/testsuite/mage/collapsible/content.html
diff --git a/dev/tests/js/testsuite/mage/collapsible/index.html b/dev/tests/js/JsTestDriver/testsuite/mage/collapsible/index.html
similarity index 100%
rename from dev/tests/js/testsuite/mage/collapsible/index.html
rename to dev/tests/js/JsTestDriver/testsuite/mage/collapsible/index.html
diff --git a/dev/tests/js/testsuite/mage/collapsible/test-collapsible.js b/dev/tests/js/JsTestDriver/testsuite/mage/collapsible/test-collapsible.js
similarity index 100%
rename from dev/tests/js/testsuite/mage/collapsible/test-collapsible.js
rename to dev/tests/js/JsTestDriver/testsuite/mage/collapsible/test-collapsible.js
diff --git a/dev/tests/js/testsuite/mage/decorate-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/decorate-test.js
similarity index 100%
rename from dev/tests/js/testsuite/mage/decorate-test.js
rename to dev/tests/js/JsTestDriver/testsuite/mage/decorate-test.js
diff --git a/dev/tests/js/testsuite/mage/design_editor/adminhtml/js/infinitescroll.js b/dev/tests/js/JsTestDriver/testsuite/mage/design_editor/adminhtml/js/infinitescroll.js
similarity index 100%
rename from dev/tests/js/testsuite/mage/design_editor/adminhtml/js/infinitescroll.js
rename to dev/tests/js/JsTestDriver/testsuite/mage/design_editor/adminhtml/js/infinitescroll.js
diff --git a/dev/tests/js/testsuite/mage/dropdown/index.html b/dev/tests/js/JsTestDriver/testsuite/mage/dropdown/index.html
similarity index 100%
rename from dev/tests/js/testsuite/mage/dropdown/index.html
rename to dev/tests/js/JsTestDriver/testsuite/mage/dropdown/index.html
diff --git a/dev/tests/js/testsuite/mage/dropdown/test-dropdown.js b/dev/tests/js/JsTestDriver/testsuite/mage/dropdown/test-dropdown.js
similarity index 100%
rename from dev/tests/js/testsuite/mage/dropdown/test-dropdown.js
rename to dev/tests/js/JsTestDriver/testsuite/mage/dropdown/test-dropdown.js
diff --git a/dev/tests/js/testsuite/mage/edit_trigger/edit-trigger-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/edit_trigger/edit-trigger-test.js
similarity index 100%
rename from dev/tests/js/testsuite/mage/edit_trigger/edit-trigger-test.js
rename to dev/tests/js/JsTestDriver/testsuite/mage/edit_trigger/edit-trigger-test.js
diff --git a/dev/tests/js/testsuite/mage/form/form-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/form/form-test.js
similarity index 100%
rename from dev/tests/js/testsuite/mage/form/form-test.js
rename to dev/tests/js/JsTestDriver/testsuite/mage/form/form-test.js
diff --git a/dev/tests/js/testsuite/mage/gallery/gallery-fullscreen-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/gallery/gallery-fullscreen-test.js
similarity index 100%
rename from dev/tests/js/testsuite/mage/gallery/gallery-fullscreen-test.js
rename to dev/tests/js/JsTestDriver/testsuite/mage/gallery/gallery-fullscreen-test.js
diff --git a/dev/tests/js/testsuite/mage/gallery/gallery-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/gallery/gallery-test.js
similarity index 100%
rename from dev/tests/js/testsuite/mage/gallery/gallery-test.js
rename to dev/tests/js/JsTestDriver/testsuite/mage/gallery/gallery-test.js
diff --git a/dev/tests/js/testsuite/mage/list/index.html b/dev/tests/js/JsTestDriver/testsuite/mage/list/index.html
similarity index 100%
rename from dev/tests/js/testsuite/mage/list/index.html
rename to dev/tests/js/JsTestDriver/testsuite/mage/list/index.html
diff --git a/dev/tests/js/testsuite/mage/list/jquery-list-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/list/jquery-list-test.js
similarity index 100%
rename from dev/tests/js/testsuite/mage/list/jquery-list-test.js
rename to dev/tests/js/JsTestDriver/testsuite/mage/list/jquery-list-test.js
diff --git a/dev/tests/js/testsuite/mage/loader/jquery-loader-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/loader/jquery-loader-test.js
similarity index 100%
rename from dev/tests/js/testsuite/mage/loader/jquery-loader-test.js
rename to dev/tests/js/JsTestDriver/testsuite/mage/loader/jquery-loader-test.js
diff --git a/dev/tests/js/testsuite/mage/loader/loader-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/loader/loader-test.js
similarity index 100%
rename from dev/tests/js/testsuite/mage/loader/loader-test.js
rename to dev/tests/js/JsTestDriver/testsuite/mage/loader/loader-test.js
diff --git a/dev/tests/js/testsuite/mage/loader/loader.html b/dev/tests/js/JsTestDriver/testsuite/mage/loader/loader.html
similarity index 100%
rename from dev/tests/js/testsuite/mage/loader/loader.html
rename to dev/tests/js/JsTestDriver/testsuite/mage/loader/loader.html
diff --git a/dev/tests/js/testsuite/mage/mage-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/mage-test.js
similarity index 100%
rename from dev/tests/js/testsuite/mage/mage-test.js
rename to dev/tests/js/JsTestDriver/testsuite/mage/mage-test.js
diff --git a/dev/tests/js/testsuite/mage/menu/index.html b/dev/tests/js/JsTestDriver/testsuite/mage/menu/index.html
similarity index 100%
rename from dev/tests/js/testsuite/mage/menu/index.html
rename to dev/tests/js/JsTestDriver/testsuite/mage/menu/index.html
diff --git a/dev/tests/js/testsuite/mage/menu/test-menu.js b/dev/tests/js/JsTestDriver/testsuite/mage/menu/test-menu.js
similarity index 100%
rename from dev/tests/js/testsuite/mage/menu/test-menu.js
rename to dev/tests/js/JsTestDriver/testsuite/mage/menu/test-menu.js
diff --git a/dev/tests/js/testsuite/mage/requirejs/plugin/id-normalizer-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/requirejs/plugin/id-normalizer-test.js
similarity index 100%
rename from dev/tests/js/testsuite/mage/requirejs/plugin/id-normalizer-test.js
rename to dev/tests/js/JsTestDriver/testsuite/mage/requirejs/plugin/id-normalizer-test.js
diff --git a/dev/tests/js/testsuite/mage/search/regular-search-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/search/regular-search-test.js
similarity index 100%
rename from dev/tests/js/testsuite/mage/search/regular-search-test.js
rename to dev/tests/js/JsTestDriver/testsuite/mage/search/regular-search-test.js
diff --git a/dev/tests/js/testsuite/mage/suggest/suggest-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/suggest/suggest-test.js
similarity index 100%
rename from dev/tests/js/testsuite/mage/suggest/suggest-test.js
rename to dev/tests/js/JsTestDriver/testsuite/mage/suggest/suggest-test.js
diff --git a/dev/tests/js/testsuite/mage/suggest/tree-suggest-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/suggest/tree-suggest-test.js
similarity index 100%
rename from dev/tests/js/testsuite/mage/suggest/tree-suggest-test.js
rename to dev/tests/js/JsTestDriver/testsuite/mage/suggest/tree-suggest-test.js
diff --git a/dev/tests/js/testsuite/mage/tabs/index.html b/dev/tests/js/JsTestDriver/testsuite/mage/tabs/index.html
similarity index 100%
rename from dev/tests/js/testsuite/mage/tabs/index.html
rename to dev/tests/js/JsTestDriver/testsuite/mage/tabs/index.html
diff --git a/dev/tests/js/testsuite/mage/tabs/tabs-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/tabs/tabs-test.js
similarity index 100%
rename from dev/tests/js/testsuite/mage/tabs/tabs-test.js
rename to dev/tests/js/JsTestDriver/testsuite/mage/tabs/tabs-test.js
diff --git a/dev/tests/js/testsuite/mage/tabs/tabs.js b/dev/tests/js/JsTestDriver/testsuite/mage/tabs/tabs.js
similarity index 100%
rename from dev/tests/js/testsuite/mage/tabs/tabs.js
rename to dev/tests/js/JsTestDriver/testsuite/mage/tabs/tabs.js
diff --git a/dev/tests/js/testsuite/mage/translate/translate-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/translate/translate-test.js
similarity index 100%
rename from dev/tests/js/testsuite/mage/translate/translate-test.js
rename to dev/tests/js/JsTestDriver/testsuite/mage/translate/translate-test.js
diff --git a/dev/tests/js/testsuite/mage/translate_inline/translate-inline-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/translate_inline/translate-inline-test.js
similarity index 100%
rename from dev/tests/js/testsuite/mage/translate_inline/translate-inline-test.js
rename to dev/tests/js/JsTestDriver/testsuite/mage/translate_inline/translate-inline-test.js
diff --git a/dev/tests/js/testsuite/mage/translate_inline_vde/translate-inline-vde-dialog-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/translate_inline_vde/translate-inline-vde-dialog-test.js
similarity index 100%
rename from dev/tests/js/testsuite/mage/translate_inline_vde/translate-inline-vde-dialog-test.js
rename to dev/tests/js/JsTestDriver/testsuite/mage/translate_inline_vde/translate-inline-vde-dialog-test.js
diff --git a/dev/tests/js/testsuite/mage/translate_inline_vde/translate-inline-vde-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/translate_inline_vde/translate-inline-vde-test.js
similarity index 100%
rename from dev/tests/js/testsuite/mage/translate_inline_vde/translate-inline-vde-test.js
rename to dev/tests/js/JsTestDriver/testsuite/mage/translate_inline_vde/translate-inline-vde-test.js
diff --git a/dev/tests/js/testsuite/mage/validation/index.html b/dev/tests/js/JsTestDriver/testsuite/mage/validation/index.html
similarity index 100%
rename from dev/tests/js/testsuite/mage/validation/index.html
rename to dev/tests/js/JsTestDriver/testsuite/mage/validation/index.html
diff --git a/dev/tests/js/testsuite/mage/validation/test-validation.js b/dev/tests/js/JsTestDriver/testsuite/mage/validation/test-validation.js
similarity index 100%
rename from dev/tests/js/testsuite/mage/validation/test-validation.js
rename to dev/tests/js/JsTestDriver/testsuite/mage/validation/test-validation.js
diff --git a/dev/tests/js/testsuite/mage/webapi-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/webapi-test.js
similarity index 100%
rename from dev/tests/js/testsuite/mage/webapi-test.js
rename to dev/tests/js/JsTestDriver/testsuite/mage/webapi-test.js
diff --git a/dev/tests/js/testsuite/mage/zoom/zoom-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/zoom/zoom-test.js
similarity index 100%
rename from dev/tests/js/testsuite/mage/zoom/zoom-test.js
rename to dev/tests/js/JsTestDriver/testsuite/mage/zoom/zoom-test.js
diff --git a/dev/tests/js/framework/spec_runner.js b/dev/tests/js/framework/spec_runner.js
deleted file mode 100644
index 733cad2f7c4da5516ad6abd9178787671a5d23e1..0000000000000000000000000000000000000000
--- a/dev/tests/js/framework/spec_runner.js
+++ /dev/null
@@ -1,200 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-/**
- * Creates jasmine configuration object
- *
- * @param  {String} type - type of tests
- * @param  {String} dir - area dir
- * @param  {Number} port - port to run on
- * @return {Object}
- */
-function buildConfig(type, dir, port) {
-    'use strict';
-
-    var isLib           = dir === 'lib',
-        requireConfigs  = [
-            '<%= path.spec %>/require.config.js',
-            '<%= path.spec %>/' + type + '/config/global.js'
-        ],
-        specsRoot       = '<%= path.spec %>/' + type,
-        specs           =  specsRoot + (isLib ? '/lib/**/*.js' : '/**/' + dir + '/**/*.js');
-    
-    if (!isLib) {
-        requireConfigs.push('<%= path.spec %>/' + type + '/config/' + dir + '.js');
-    }
-
-    return {
-        src: '<%= path.spec %>/shim.js',
-        options: {
-            host: 'http://localhost:' + port,
-            specs: specs,
-            templateOptions: {
-                requireConfigFile: requireConfigs
-            }
-        }
-    };
-}
-
-module.exports = function (grunt) {
-    'use strict';
-
-    var connect     = require('connect'),
-        logger      = require('morgan'),
-        serveStatic = require('serve-static'),
-        fs          = require('fs'),
-        root;
-
-    root = __dirname
-        .replace('/dev/tests/js/framework', '')
-        .replace('\\dev\\tests\\js\\framework', '');
-
-    grunt.registerMultiTask('specRunner', function () {
-        var app = connect(),
-            options,
-            area,
-            theme,
-            share,
-            middlewares;
-
-        options = this.options({
-            port: 3000,
-            theme: null,
-            areaDir: null,
-            shareDir: null,
-            enableLogs: false,
-            middleware: null
-        });
-
-        area    = options.areaDir;
-        share   = options.shareDir;
-        theme   = options.theme;
-
-        if (options.enableLogs) {
-            app.use(logger('dev'));
-        }
-
-        app.use(function (req, res, next) {
-            var url     = req.url,
-                match   = url.match(/^\/([A-Z][^\/]+)_(\w+)\/(.+)$/),
-                vendor,
-                module,
-                path,
-                getModuleUrl,
-                getThemeUrl;
-
-            /**
-             * Returns path to theme root folder
-             *
-             * @return {String}
-             */
-            function themeRoot() {
-                return [
-                    '/app/design',
-                    area,
-                    vendor,
-                    theme
-                ].join('/');
-            }
-
-            /**
-             * Based on 'thematic' parameter, returnes either path to theme's lib,
-             *     or 'lib/web'.
-             *
-             * @param  {Boolean} thematic
-             * @return {String}
-             */
-            function lib(thematic) {
-                return thematic ? themeRoot() + '/web' : '/lib/web';
-            }
-
-            if (match !== null) {
-                vendor  = match[1];
-                module  = match[2];
-                path    = match[3];
-
-                /**
-                 * Assembles modular path. If 'shared' flag provided and is truthy,
-                 *     will use share dir instead of area one.
-                 *
-                 * @param  {Boolean} shared
-                 * @return {String}
-                 */
-                getModuleUrl = function (shared) {
-                    return [
-                        '/app/code',
-                        vendor,
-                        module,
-                        'view',
-                        !!shared ? share : area,
-                        'web',
-                        path
-                    ].join('/');
-                };
-
-                /**
-                 * Assembles theme modular path.
-                 *
-                 * @return {String}
-                 */
-                getThemeUrl = function () {
-                    return [
-                        themeRoot(),
-                        vendor + '_' + module,
-                        'web',
-                        path
-                    ].join('/');
-                };
-
-                url = exists(url = getThemeUrl()) ?
-                    url :
-                    exists(url = getModuleUrl()) ?
-                        url : getModuleUrl(true);
-
-            } else if (canModify(url)) {
-                url = (exists(url = lib(true)) ? url : lib()) + req.url;
-            }
-
-            req.url = url;
-
-            next();
-        });
-
-        if (options.middleware && typeof options.middleware === 'function') {
-            middlewares = options.middleware(connect, options);
-
-            if (Array.isArray(middlewares)) {
-                middlewares.forEach(function (middleware) {
-                    app.use(middleware);
-                });
-            }
-        }
-
-        app.use(serveStatic(root));
-
-        app.listen(options.port);
-    });
-
-    /**
-     * Defines if passed file path exists
-     *
-     * @param  {String} path
-     * @return {Boolean}
-     */
-    function exists(path) {
-        return fs.existsSync(root + path);
-    }
-
-    /**
-     * Restricts url's which lead to '/_SpecRunner.html', '/dev/tests' or '.grunt' folders from being modified
-     *
-     * @param  {String} url
-     * @return {Boolean}
-     */
-    function canModify(url) {
-        return url.match(/^\/(\.grunt)|(dev\/tests)|(dev\\tests)|(_SpecRunner\.html)/) === null;
-    }
-
-    return { configure: buildConfig };
-};
diff --git a/dev/tests/js/spec/assets/apply/components/fn.js b/dev/tests/js/jasmine/assets/apply/components/fn.js
similarity index 100%
rename from dev/tests/js/spec/assets/apply/components/fn.js
rename to dev/tests/js/jasmine/assets/apply/components/fn.js
diff --git a/dev/tests/js/spec/assets/apply/config.json b/dev/tests/js/jasmine/assets/apply/config.json
similarity index 100%
rename from dev/tests/js/spec/assets/apply/config.json
rename to dev/tests/js/jasmine/assets/apply/config.json
diff --git a/dev/tests/js/spec/assets/apply/index.js b/dev/tests/js/jasmine/assets/apply/index.js
similarity index 94%
rename from dev/tests/js/spec/assets/apply/index.js
rename to dev/tests/js/jasmine/assets/apply/index.js
index 31268a6aa773230559203076bff7998a1d91c1ea..7fd9b379e1f24ef6329d9ed5c21ef02c3654c7f5 100644
--- a/dev/tests/js/spec/assets/apply/index.js
+++ b/dev/tests/js/jasmine/assets/apply/index.js
@@ -3,7 +3,7 @@
  * See COPYING.txt for license details.
  */
 define([
-    'tests/tools',
+    'tests/assets/tools',
     'tests/assets/apply/components/fn',
     'text!./config.json',
     'text!./templates/node.html'
diff --git a/dev/tests/js/spec/assets/apply/templates/node.html b/dev/tests/js/jasmine/assets/apply/templates/node.html
similarity index 100%
rename from dev/tests/js/spec/assets/apply/templates/node.html
rename to dev/tests/js/jasmine/assets/apply/templates/node.html
diff --git a/dev/tests/js/spec/assets/jsbuild/config.js b/dev/tests/js/jasmine/assets/jsbuild/config.js
similarity index 100%
rename from dev/tests/js/spec/assets/jsbuild/config.js
rename to dev/tests/js/jasmine/assets/jsbuild/config.js
diff --git a/dev/tests/js/spec/assets/jsbuild/external.js b/dev/tests/js/jasmine/assets/jsbuild/external.js
similarity index 100%
rename from dev/tests/js/spec/assets/jsbuild/external.js
rename to dev/tests/js/jasmine/assets/jsbuild/external.js
diff --git a/dev/tests/js/spec/assets/jsbuild/local.js b/dev/tests/js/jasmine/assets/jsbuild/local.js
similarity index 100%
rename from dev/tests/js/spec/assets/jsbuild/local.js
rename to dev/tests/js/jasmine/assets/jsbuild/local.js
diff --git a/dev/tests/js/spec/assets/script/config.json b/dev/tests/js/jasmine/assets/script/config.json
similarity index 100%
rename from dev/tests/js/spec/assets/script/config.json
rename to dev/tests/js/jasmine/assets/script/config.json
diff --git a/dev/tests/js/spec/assets/script/index.js b/dev/tests/js/jasmine/assets/script/index.js
similarity index 93%
rename from dev/tests/js/spec/assets/script/index.js
rename to dev/tests/js/jasmine/assets/script/index.js
index 031241f4c2d3e8beb24b9d7ee2373daa058a03f7..e9519e7ebe1e6b4e398ef06b68e59facb73850f5 100644
--- a/dev/tests/js/spec/assets/script/index.js
+++ b/dev/tests/js/jasmine/assets/script/index.js
@@ -3,7 +3,7 @@
  * See COPYING.txt for license details.
  */
 define([
-    'tests/tools',
+    'tests/assets/tools',
     'text!./config.json',
     'text!./templates/selector.html',
     'text!./templates/virtual.html'
diff --git a/dev/tests/js/spec/assets/script/templates/selector.html b/dev/tests/js/jasmine/assets/script/templates/selector.html
similarity index 100%
rename from dev/tests/js/spec/assets/script/templates/selector.html
rename to dev/tests/js/jasmine/assets/script/templates/selector.html
diff --git a/dev/tests/js/spec/assets/script/templates/virtual.html b/dev/tests/js/jasmine/assets/script/templates/virtual.html
similarity index 100%
rename from dev/tests/js/spec/assets/script/templates/virtual.html
rename to dev/tests/js/jasmine/assets/script/templates/virtual.html
diff --git a/dev/tests/js/spec/assets/text/config.js b/dev/tests/js/jasmine/assets/text/config.js
similarity index 50%
rename from dev/tests/js/spec/assets/text/config.js
rename to dev/tests/js/jasmine/assets/text/config.js
index fe8bc894e540567eb4948f04a683003932e39bda..0b0faa2d5cdd3eb68a7aeaccb5637f7c3eb97fcc 100644
--- a/dev/tests/js/spec/assets/text/config.js
+++ b/dev/tests/js/jasmine/assets/text/config.js
@@ -8,11 +8,11 @@ define(function () {
     return {
         local: {
             path: 'text!tests/assets/text/local.html',
-            result: '<span>Local Template</span>'
+            result: '<!--\n/**\n * Copyright © 2015 Magento. All rights reserved.\n * See COPYING.txt for license details.\n */\n-->\n<span>Local Template</span>'
         },
         external: {
             path: 'text!tests/assets/text/external.html',
-            result: '<span>External Template</span>'
+            result: '<!--\n/**\n * Copyright © 2015 Magento. All rights reserved.\n * See COPYING.txt for license details.\n */\n-->\n<span>External Template</span>'
         }
     };
 });
diff --git a/dev/tests/js/spec/assets/text/external.html b/dev/tests/js/jasmine/assets/text/external.html
similarity index 100%
rename from dev/tests/js/spec/assets/text/external.html
rename to dev/tests/js/jasmine/assets/text/external.html
diff --git a/dev/tests/js/spec/assets/text/local.html b/dev/tests/js/jasmine/assets/text/local.html
similarity index 100%
rename from dev/tests/js/spec/assets/text/local.html
rename to dev/tests/js/jasmine/assets/text/local.html
diff --git a/dev/tests/js/spec/tools.js b/dev/tests/js/jasmine/assets/tools.js
similarity index 100%
rename from dev/tests/js/spec/tools.js
rename to dev/tests/js/jasmine/assets/tools.js
diff --git a/dev/tests/js/jasmine/require.conf.js b/dev/tests/js/jasmine/require.conf.js
new file mode 100644
index 0000000000000000000000000000000000000000..88a0960aa1876bf8eca5c99e520f23965b83ea50
--- /dev/null
+++ b/dev/tests/js/jasmine/require.conf.js
@@ -0,0 +1,32 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+'use strict';
+
+require.config({
+    baseUrl: './',
+    bundles: {
+        'mage/requirejs/static': [
+            'buildTools',
+            'jsbuild',
+            'statistician',
+            'text'
+        ]
+    },
+    paths: {
+        'tests': 'dev/tests/js/jasmine'
+    },
+    config: {
+        jsbuild: {
+            'dev/tests/js/jasmine/assets/jsbuild/local.js': 'define([], function () {\'use strict\'; return \'internal module\'; });'
+        },
+        text: {
+            'dev/tests/js/jasmine/assets/text/local.html': '<!--\n/**\n * Copyright © 2015 Magento. All rights reserved.\n * See COPYING.txt for license details.\n */\n-->\n<span>Local Template</span>'
+        }
+    },
+    deps: [
+        'mage/requirejs/static'
+    ]
+});
\ No newline at end of file
diff --git a/dev/tests/js/jasmine/spec_runner/index.js b/dev/tests/js/jasmine/spec_runner/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..d63429aae1270559b0ef2af345d06d8dde170b8c
--- /dev/null
+++ b/dev/tests/js/jasmine/spec_runner/index.js
@@ -0,0 +1,62 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+'use strict';
+
+var tasks = [],
+    _ = require('underscore');
+
+function init(grunt, options) {
+    var _                   = require('underscore'),
+        stripJsonComments   = require('strip-json-comments'),
+        path                = require('path'),
+        config,
+        themes;
+        
+    config = grunt.file.read(__dirname + '/settings.json');
+    config = stripJsonComments(config);
+    config = JSON.parse(config);
+
+    themes = require(path.resolve(process.cwd(), config.themes));
+
+    if (options.theme) {
+        themes = _.pick(themes, options.theme);
+    }
+
+    tasks = Object.keys(themes);
+
+    config.themes = themes;
+
+    enableTasks(grunt, config);
+}
+
+function enableTasks(grunt, config) {
+    var jasmine = require('./tasks/jasmine'),
+        connect = require('./tasks/connect');
+
+    jasmine.init(config);
+    connect.init(config);
+
+    grunt.initConfig({
+        jasmine: jasmine.getTasks(),
+        connect: connect.getTasks()
+    });
+}
+
+function getTasks() {
+    tasks = tasks.map(function (theme) {
+        return [
+            'connect:' + theme,
+            'jasmine:' + theme
+        ]
+    });
+
+    return _.flatten(tasks);
+}
+
+module.exports = {
+    init: init,
+    getTasks: getTasks
+};
\ No newline at end of file
diff --git a/dev/tests/js/jasmine/spec_runner/settings.json b/dev/tests/js/jasmine/spec_runner/settings.json
new file mode 100644
index 0000000000000000000000000000000000000000..109da479146da84882c4a6a68e8778db0b19701d
--- /dev/null
+++ b/dev/tests/js/jasmine/spec_runner/settings.json
@@ -0,0 +1,72 @@
+{
+    "host": "http://localhost:<%= port %>",
+    "port": 8000,
+    "root": "dev/tests/js/jasmine",
+
+    /**
+     * Path to themes configuration module. Relative to Magento root.
+     * This node is replaced by formatted theme configuration by 'dev/tests/jasmine/spec_runner' module
+     */
+    "themes": "dev/tools/grunt/configs/themes",
+    
+    "files": {
+        /**
+         * Path to RequireJS library. Relative to "server.base" config.
+         */
+        "requireJs": "requirejs/require.js",
+
+        /**
+         * Overridden "grunt-contrib-jasmine" SpecRunner template.
+         */
+        "template": "<%= root %>/spec_runner/template.html",
+
+        /**
+         * These files are included to the page in <head> right after "require.js" in declared sequence.
+         */
+        "requirejsConfigs": [
+            "pub/static/_requirejs/<%= area %>/<%= name %>/<%= locale %>/requirejs-config.js",
+            "<%= root %>/require.conf.js",
+            "<%= root %>/tests/lib/**/*.conf.js",
+            "<%= root %>/tests/app/code/**/base/**/*.conf.js",
+            "<%= root %>/tests/app/code/**/<%= area %>/**/*.conf.js",
+            "<%= root %>/tests/app/design/<%= area %>/<%= name %>/**/*.conf.js"
+        ],
+
+        /**
+         * Files that contain tests. These are loaded to the page via RequireJS after all RequireJS configuration files have been loaded to the page.
+         * The sequence is ignored.
+         */
+        "specs": [
+            "<%= root %>/tests/lib/**/*.test.js",
+            "<%= root %>/tests/app/code/**/base/**/*.test.js",
+            "<%= root %>/tests/app/code/**/<%= area %>/**/*.test.js",
+            "<%= root %>/tests/app/design/<%= area %>/<%= name %>/**/*.test.js"
+        ]
+    },
+    "server": {
+        /**
+         * Directory to serve files from
+         */
+        "base": "pub/static/<%= area %>/<%= name %>/<%= locale %>",
+
+        /**
+         * Strings, mentioned here are interpreted as regular expressions. Use this option to override server's
+         *     default behaviour and serve matched urls "as is" from Magento root.
+         */
+        "serveAsIs": [
+            "^\/_SpecRunner.html",
+            "^\/dev\/tests",
+            "^\/.grunt",
+            "^\/pub\/static"
+        ],
+        "options": {
+            /**
+             * All options mentioned here are defaults for "connect" grunt task.
+             * "debug" option enables server logs
+             * "keepalive" makes "connect" task pause with set up spec server, which you can fetch by %host%:%port%/_SpecRunner.html address in browser
+             */
+            "debug": false,
+            "keepalive": false
+        }
+    }
+}
\ No newline at end of file
diff --git a/dev/tests/js/jasmine/spec_runner/tasks/connect.js b/dev/tests/js/jasmine/spec_runner/tasks/connect.js
new file mode 100644
index 0000000000000000000000000000000000000000..d472f210d3d5fe1abd5e0ac3e68336819eb12f42
--- /dev/null
+++ b/dev/tests/js/jasmine/spec_runner/tasks/connect.js
@@ -0,0 +1,64 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+'use strict';
+
+var tasks = {};
+
+function init(config) {
+    var serveStatic = require('serve-static'),
+        grunt       = require('grunt'),
+        _           = require('underscore'),
+        path        = require('path'),
+        ignoredPaths, middleware, themes, files, port;
+
+    port         = config.port;
+    files        = config.files;
+    themes       = config.themes;
+    ignoredPaths = config.server.serveAsIs;
+
+    function serveAsIs(path) {
+        return ignoredPaths.some(function (ignoredPath) {
+            return new RegExp(ignoredPath).test(path);
+        });
+    }
+
+    middleware = function (connect, options, middlewares) {
+        var server = serveStatic(process.cwd());
+
+        middlewares.unshift(function (req, res, next) {
+            var url = req.url;
+                
+            if (serveAsIs(url)) {
+                return server.apply(null, arguments);
+            }
+
+            return next();
+        });
+
+        return middlewares;
+    }
+
+    _.each(themes, function (themeData, themeName) {
+        var options = {
+            base: _.template(config.server.base)(themeData),
+            port: port++,
+            middleware: middleware
+        };
+
+        _.defaults(options, config.server.options);
+
+        tasks[themeName] = { options: options };
+    });
+}
+
+function getTasks() {
+    return tasks;
+}
+
+module.exports = {
+    init: init,
+    getTasks: getTasks
+};
\ No newline at end of file
diff --git a/dev/tests/js/jasmine/spec_runner/tasks/jasmine.js b/dev/tests/js/jasmine/spec_runner/tasks/jasmine.js
new file mode 100644
index 0000000000000000000000000000000000000000..9c2eaeb23996feb26f2f8f4819056cacdbc47bb0
--- /dev/null
+++ b/dev/tests/js/jasmine/spec_runner/tasks/jasmine.js
@@ -0,0 +1,65 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+'use strict';
+
+var tasks = {},
+    _ = require('underscore');
+
+function init(config) {
+    var grunt  = require('grunt'),
+        expand = grunt.file.expand.bind(grunt.file),
+        themes, root, host, port, files;
+
+    root         = config.root;
+    port         = config.port;
+    files        = config.files;
+    host         = _.template(config.host)({ port: port });
+    themes       = config.themes;
+
+    _.each(themes, function (themeData, themeName) {
+        var specs,
+            configs,
+            render;
+
+        _.extend(themeData, { root: root });
+
+        render  = renderTemplate.bind(null, themeData);
+        specs   = files.specs.map(render);
+        specs   = expand(specs).map(cutJsExtension);
+        configs = files.requirejsConfigs.map(render);
+
+        tasks[themeName] = {
+            src: configs,
+            options: {
+                host: host,
+                template: render(files.template),
+                vendor: files.requireJs,
+
+                /**
+                 * @todo rename "helpers" to "specs" (implies overriding grunt-contrib-jasmine code)
+                 */
+                helpers: specs
+            }
+        }
+    });
+}
+
+function renderTemplate(data, template) {
+    return _.template(template)(data);
+}
+
+function cutJsExtension(path) {
+    return path.replace(/\.js$/, '');
+}
+
+function getTasks() {
+    return tasks;
+}
+
+module.exports = {
+    init: init,
+    getTasks: getTasks
+};
\ No newline at end of file
diff --git a/dev/tests/js/jasmine/spec_runner/template.html b/dev/tests/js/jasmine/spec_runner/template.html
new file mode 100644
index 0000000000000000000000000000000000000000..39c2f843480509bbedaac4a21b11209c8bd45d62
--- /dev/null
+++ b/dev/tests/js/jasmine/spec_runner/template.html
@@ -0,0 +1,30 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+
+<!DOCTYPE html>
+<html>
+    <head>
+        <meta charset="utf-8" />
+        <title>Jasmine Spec Runner</title>
+        <link rel="shortcut icon" type="image/png" href="<%= temp %>/jasmine_favicon.png">
+        <% css.forEach(function (style) { %>
+        <link rel="stylesheet" href="<%= style %>">
+        <% }); %>
+        <% with (scripts) { %>
+            <% [].concat(polyfills, jasmine, boot, vendor, src, reporters).forEach(function (script) { %>
+            <script type="text/javascript" src="<%= script %>"></script>
+            <% }); %>
+        <% } %>
+        <script type="text/javascript">
+            var jasmineBoot = window.onload;
+            window.onload = null;
+
+            require(<%= JSON.stringify(scripts.helpers) %>, jasmineBoot);
+        </script>
+    </head>
+    <body></body>
+</html>
\ No newline at end of file
diff --git a/dev/tests/js/spec/integration/Magento/Msrp/frontend/js/msrp.js b/dev/tests/js/jasmine/tests/app/code/Magento/Msrp/frontend/js/msrp.test.js
similarity index 100%
rename from dev/tests/js/spec/integration/Magento/Msrp/frontend/js/msrp.js
rename to dev/tests/js/jasmine/tests/app/code/Magento/Msrp/frontend/js/msrp.test.js
diff --git a/dev/tests/js/spec/integration/Magento/PageCache/frontend/js/pageCache.js b/dev/tests/js/jasmine/tests/app/code/Magento/PageCache/frontend/js/page-cache.test.js
similarity index 100%
rename from dev/tests/js/spec/integration/Magento/PageCache/frontend/js/pageCache.js
rename to dev/tests/js/jasmine/tests/app/code/Magento/PageCache/frontend/js/page-cache.test.js
diff --git a/dev/tests/js/spec/unit/Magento/Ui/adminhtml/events.js b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/lib/events.test.js
similarity index 99%
rename from dev/tests/js/spec/unit/Magento/Ui/adminhtml/events.js
rename to dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/lib/events.test.js
index c97b375562b05bc3d08dd1f2a2684b86d37b0183..bc2f08748f45e25f476cd2b0494f988b9f2bf41f 100644
--- a/dev/tests/js/spec/unit/Magento/Ui/adminhtml/events.js
+++ b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/lib/events.test.js
@@ -2,6 +2,7 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
+
 define([
     'Magento_Ui/js/lib/events'
 ], function (EventBus) {
diff --git a/dev/tests/js/spec/integration/Magento/Ui/adminhtml/datepicker.js b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/lib/ko/bind/datepicker.test.js
similarity index 99%
rename from dev/tests/js/spec/integration/Magento/Ui/adminhtml/datepicker.js
rename to dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/lib/ko/bind/datepicker.test.js
index 48c728fcf2e283474aed3270a522ceee3398d16f..9868699682a9d4d7ff0df2634fb2fc4da1b6c921 100644
--- a/dev/tests/js/spec/integration/Magento/Ui/adminhtml/datepicker.js
+++ b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/lib/ko/bind/datepicker.test.js
@@ -2,6 +2,7 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
+
 define([
     'ko',
     'jquery',
diff --git a/dev/tests/js/spec/integration/lib/mage/apply.js b/dev/tests/js/jasmine/tests/lib/mage/apply.test.js
similarity index 98%
rename from dev/tests/js/spec/integration/lib/mage/apply.js
rename to dev/tests/js/jasmine/tests/lib/mage/apply.test.js
index 5e3965b5903b76d1089e57cf8d9e783065bfa342..a9d22ac7c67d2f59379da2e8aa67fdc503b8d2ae 100644
--- a/dev/tests/js/spec/integration/lib/mage/apply.js
+++ b/dev/tests/js/jasmine/tests/lib/mage/apply.test.js
@@ -4,7 +4,7 @@
  */
 define([
     'underscore',
-    'tests/tools',
+    'tests/assets/tools',
     'tests/assets/apply/index',
     'mage/apply/main'
 ], function (_, tools, config, mage) {
diff --git a/dev/tests/js/spec/integration/lib/mage/requirejs/static-jsbuild.js b/dev/tests/js/jasmine/tests/lib/mage/requirejs/static-jsbuild.test.js
similarity index 100%
rename from dev/tests/js/spec/integration/lib/mage/requirejs/static-jsbuild.js
rename to dev/tests/js/jasmine/tests/lib/mage/requirejs/static-jsbuild.test.js
diff --git a/dev/tests/js/spec/integration/lib/mage/requirejs/static-text.js b/dev/tests/js/jasmine/tests/lib/mage/requirejs/static-text.test.js
similarity index 100%
rename from dev/tests/js/spec/integration/lib/mage/requirejs/static-text.js
rename to dev/tests/js/jasmine/tests/lib/mage/requirejs/static-text.test.js
diff --git a/dev/tests/js/spec/unit/lib/mage/requirejs/statistician.js b/dev/tests/js/jasmine/tests/lib/mage/requirejs/statistician.test.js
similarity index 100%
rename from dev/tests/js/spec/unit/lib/mage/requirejs/statistician.js
rename to dev/tests/js/jasmine/tests/lib/mage/requirejs/statistician.test.js
diff --git a/dev/tests/js/spec/integration/lib/mage/scripts.js b/dev/tests/js/jasmine/tests/lib/mage/scripts.test.js
similarity index 98%
rename from dev/tests/js/spec/integration/lib/mage/scripts.js
rename to dev/tests/js/jasmine/tests/lib/mage/scripts.test.js
index 05c4c13388919dd9a0ffd482663cf9bb99eda4bc..3bfbd4b637ea97801570ff2a571e8e21c3009d9c 100644
--- a/dev/tests/js/spec/integration/lib/mage/scripts.js
+++ b/dev/tests/js/jasmine/tests/lib/mage/scripts.test.js
@@ -3,7 +3,7 @@
  * See COPYING.txt for license details.
  */
 define([
-    'tests/tools',
+    'tests/assets/tools',
     'tests/assets/script/index',
     'mage/apply/scripts'
 ], function (tools, config, processScripts) {
diff --git a/dev/tests/js/spec/unit/lib/mage/template.js b/dev/tests/js/jasmine/tests/lib/mage/template.test.js
similarity index 100%
rename from dev/tests/js/spec/unit/lib/mage/template.js
rename to dev/tests/js/jasmine/tests/lib/mage/template.test.js
diff --git a/dev/tests/js/spec/integration/config/adminhtml.js b/dev/tests/js/spec/integration/config/adminhtml.js
deleted file mode 100644
index a9a60a43acad7e385f816e2ddce011f2cf682167..0000000000000000000000000000000000000000
--- a/dev/tests/js/spec/integration/config/adminhtml.js
+++ /dev/null
@@ -1,10 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-require.config({
-    paths: {
-        'jquery/ui': 'jquery/jquery-ui-1.9.2'
-    }
-});
diff --git a/dev/tests/js/spec/integration/config/frontend.js b/dev/tests/js/spec/integration/config/frontend.js
deleted file mode 100644
index 8791f57a90cfd289dbad10f5c140a34052b48139..0000000000000000000000000000000000000000
--- a/dev/tests/js/spec/integration/config/frontend.js
+++ /dev/null
@@ -1,10 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-require.config({
-    paths: {
-        'jquery/ui': 'jquery/jquery-ui'    
-    }
-})
\ No newline at end of file
diff --git a/dev/tests/js/spec/integration/config/global.js b/dev/tests/js/spec/integration/config/global.js
deleted file mode 100644
index 0f9ac6f574916eec9b0ee5707333c4461eece39e..0000000000000000000000000000000000000000
--- a/dev/tests/js/spec/integration/config/global.js
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-require.config({
-    bundles: {
-        'mage/requirejs/static': [
-            'jsbuild',
-            'text',
-            'buildTools'
-        ]
-    },
-    config: {
-        jsbuild: {
-            'dev/tests/js/spec/assets/jsbuild/local.js': 'define([], function () {\'use strict\'; return \'internal module\'; });'
-        },
-        text: {
-            'dev/tests/js/spec/assets/text/local.html': '<span>Local Template</span>'
-        }
-    },
-    deps: [
-        'mage/requirejs/static'
-    ],
-    paths: {
-        'jquery/ui': 'jquery/jquery-ui'
-    }
-});
diff --git a/dev/tests/js/spec/require.config.js b/dev/tests/js/spec/require.config.js
deleted file mode 100644
index 2df785bb9962a997e3a19e838f834a8b1e984340..0000000000000000000000000000000000000000
--- a/dev/tests/js/spec/require.config.js
+++ /dev/null
@@ -1,16 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-require.config({
-    paths: {
-        'ko': 'ko/ko',
-        'domReady': 'requirejs/domReady',
-        'text': 'requirejs/text',
-        'tests': 'dev/tests/js/spec'
-    },
-    shim: {
-        'jquery/ui': ['jquery']
-    }
-});
diff --git a/dev/tests/js/spec/shim.js b/dev/tests/js/spec/shim.js
deleted file mode 100644
index 0cbe7edb109dee558040426db6c8d14678ff7b9c..0000000000000000000000000000000000000000
--- a/dev/tests/js/spec/shim.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-(function () {
-    'use strict';
-
-    var Ap = Array.prototype,
-        slice = Ap.slice,
-        Fp = Function.prototype;
-
-    if (!Fp.bind) {
-        /**
-         * PhantomJS doesn't support Function.prototype.bind natively, so
-         * polyfill it whenever this module is required.
-         *
-         * @param  {*} context
-         * @return {Function}
-         */
-        Fp.bind = function (context) {
-            var func = this,
-                args = slice.call(arguments, 1);
-                
-            function bound() {
-                var invokedAsConstructor = func.prototype && (this instanceof func);
-
-                return func.apply(
-                    // Ignore the context parameter when invoking the bound function
-                    // as a constructor. Note that this includes not only constructor
-                    // invocations using the new keyword but also calls to base class
-                    // constructors such as BaseClass.call(this, ...) or super(...).
-                    !invokedAsConstructor && context || this,
-                    args.concat(slice.call(arguments))
-                );
-            }
-
-            // The bound function must share the .prototype of the unbound
-            // function so that any object created by one constructor will count
-            // as an instance of both constructors.
-            bound.prototype = func.prototype;
-
-            return bound;
-        };
-    }
-
-})();
diff --git a/dev/tests/js/spec/unit/config/adminhtml.js b/dev/tests/js/spec/unit/config/adminhtml.js
deleted file mode 100644
index a9a60a43acad7e385f816e2ddce011f2cf682167..0000000000000000000000000000000000000000
--- a/dev/tests/js/spec/unit/config/adminhtml.js
+++ /dev/null
@@ -1,10 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-require.config({
-    paths: {
-        'jquery/ui': 'jquery/jquery-ui-1.9.2'
-    }
-});
diff --git a/dev/tests/js/spec/unit/config/frontend.js b/dev/tests/js/spec/unit/config/frontend.js
deleted file mode 100644
index f6ee8dc73b131128e9cb0709f9765b060cd2e90d..0000000000000000000000000000000000000000
--- a/dev/tests/js/spec/unit/config/frontend.js
+++ /dev/null
@@ -1,10 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-require.config({
-    paths: {
-        'jquery/ui': 'jquery/jquery-ui'
-    }
-});
diff --git a/dev/tests/js/spec/unit/config/global.js b/dev/tests/js/spec/unit/config/global.js
deleted file mode 100644
index c59abab9fc575c4c8b3c99e8ee3422c53523a79a..0000000000000000000000000000000000000000
--- a/dev/tests/js/spec/unit/config/global.js
+++ /dev/null
@@ -1,15 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-require.config({
-    bundles: {
-        'mage/requirejs/static': [
-            'buildTools'
-        ]
-    },
-    deps: [
-        'mage/requirejs/static'
-    ]
-});
diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/HhvmCompatibilityTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/HhvmCompatibilityTest.php
index c3a9fe9933ee4948c40bbd5630eea75f0b46a1e0..b7c342c1fd4ecdc410a7558a1a3131d76193c125 100644
--- a/dev/tests/static/testsuite/Magento/Test/Integrity/HhvmCompatibilityTest.php
+++ b/dev/tests/static/testsuite/Magento/Test/Integrity/HhvmCompatibilityTest.php
@@ -36,6 +36,7 @@ class HhvmCompatibilityTest extends \PHPUnit_Framework_TestCase
         'mime_magic.magicfile',
         'display_errors',
         'default_socket_timeout',
+        'pcre.recursion_limit',
     ];
 
     public function testAllowedIniGetSetDirectives()
diff --git a/dev/tests/static/testsuite/Magento/Test/Js/_files/blacklist/core.txt b/dev/tests/static/testsuite/Magento/Test/Js/_files/blacklist/core.txt
index 2ba58c46a10ad6d2ce222f759e2baa6051c067b0..9210d15d05df6a7a82ce4f6c5f1b312bf54ccf01 100644
--- a/dev/tests/static/testsuite/Magento/Test/Js/_files/blacklist/core.txt
+++ b/dev/tests/static/testsuite/Magento/Test/Js/_files/blacklist/core.txt
@@ -12,8 +12,8 @@ app/code/Magento/Sales/view/adminhtml/web/order/giftoptions_tooltip.js
 app/code/Magento/Shipping/view/adminhtml/web/order/packaging.js
 app/code/Magento/Theme/view/frontend/web/menu.js
 app/code/Magento/Variable/view/adminhtml/web/variables.js
-dev/tests/js/testsuite/mage/translate_inline_vde/translate-inline-vde-test.js
-dev/tests/js/framework/qunit
+dev/tests/js/JsTestDriver/testsuite/mage/translate_inline_vde/translate-inline-vde-test.js
+dev/tests/js/JsTestDriver/framework/qunit
 lib/web/mage/adminhtml
 lib/web/mage/captcha.js
 lib/web/legacy-build.min.js
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php
index 21ff60a356b59dbd10c2c7bcc2d9c5cc21c57bd4..7baeb9bac60b7ecbb782de7407a87d7033367831 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php
@@ -338,6 +338,11 @@ return [
     ['_getItemPosition', 'Magento\Catalog\Block\Navigation'],
     ['_renderCategoryMenuItemHtml', 'Magento\Catalog\Block\Navigation'],
     ['getCurrentCategoryPath', 'Magento\Catalog\Block\Navigation'],
+    [
+        'getIsMessagesAvailable',
+        'Magento\GiftMessage\Helper\Message',
+        'Magento\GiftMessage\Helper\Message::isMessagesAllowed'
+    ],
     ['drawOpenCategoryItem', 'Magento\Catalog\Block\Navigation'],
     ['renderCategoriesMenuHtml', 'Magento\Catalog\Block\Navigation'],
     ['dropKey', 'Magento\Framework\DB\Adapter\Pdo\Mysql'],
diff --git a/dev/tests/unit/phpunit.xml.dist b/dev/tests/unit/phpunit.xml.dist
index da22efa001e62023edca737d21fce161a764a665..5c785e252e48aa8c82aa8bcfe817c761b38ecc23 100644
--- a/dev/tests/unit/phpunit.xml.dist
+++ b/dev/tests/unit/phpunit.xml.dist
@@ -44,5 +44,8 @@
         <!--coverage_clover_placeholder
             <log type="coverage-clover" target="{{coverage_dir}}/test-reports/phpunit.coverage.xml"/>
         coverage_clover_placeholder-->
+        <!--coverage_crap4j_placeholder
+            <log type="coverage-crap4j" target="{{coverage_dir}}/test-reports/phpunit.crap4j.xml"/>
+        coverage_crap4j_placeholder-->
     </logging>
 </phpunit>
diff --git a/dev/tools/Magento/Tools/Di/compiler.php b/dev/tools/Magento/Tools/Di/compiler.php
index fca4673dd90fdf85f5feb74bfd3257d99a83e78b..ced28772e7c6108f8f1a033617cf4af379687195 100644
--- a/dev/tools/Magento/Tools/Di/compiler.php
+++ b/dev/tools/Magento/Tools/Di/compiler.php
@@ -247,11 +247,6 @@ try {
         . ' in the "var" directory. For instance, if you run the Magento application using Apache,'
         . ' the owner of the files in the "var" directory should be the Apache user (example command:'
         . ' "chown -R www-data:www-data <MAGENTO_ROOT>/var" where MAGENTO_ROOT is the Magento root directory).' . "\n";
-    /** TODO: Temporary solution before having necessary changes on bamboo to overcome issue described above */
-    $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($rootDir . '/var'));
-    foreach ($iterator as $item) {
-        chmod($item, 0777);
-    }
 
 } catch (Zend_Console_Getopt_Exception $e) {
     echo $e->getUsageMessage();
diff --git a/dev/tools/grunt/configs/jasmine.js b/dev/tools/grunt/configs/jasmine.js
deleted file mode 100644
index 75c33b5d92f98e3df5e7e4d9922a9cb6cc0d59c8..0000000000000000000000000000000000000000
--- a/dev/tools/grunt/configs/jasmine.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-'use strict';
-
-var path = require('path');
-
-module.exports = function (grunt) {
-    var file = path.join(process.cwd(), 'dev/tests/js/framework/spec_runner'),
-        specRunner = require(file)(grunt);
-
-    return {
-        options: {
-            template: require('grunt-template-jasmine-requirejs'),
-            ignoreEmpty: true
-        },
-        'lib-unit':               specRunner.configure('unit', 'lib', 8080),
-        'lib-integration':        specRunner.configure('integration', 'lib', 8080),
-        'backend-unit':           specRunner.configure('unit', 'adminhtml', 8000),
-        'backend-integration':    specRunner.configure('integration', 'adminhtml', 8000),
-        'frontend-unit':          specRunner.configure('unit', 'frontend', 3000),
-        'frontend-integration':   specRunner.configure('integration', 'frontend', 3000)
-    };
-};
diff --git a/dev/tools/grunt/configs/specRunner.json b/dev/tools/grunt/configs/specRunner.json
deleted file mode 100644
index 0d47c57e101a2b121e6ea5f0f67c87ca2191b70e..0000000000000000000000000000000000000000
--- a/dev/tools/grunt/configs/specRunner.json
+++ /dev/null
@@ -1,24 +0,0 @@
-{
-    "options": {
-        "shareDir": "base"
-    },
-    "backend": {
-        "options": {
-            "port": 8000,
-            "areaDir": "adminhtml",
-            "theme": "backend"
-        }
-    },
-    "frontend": {
-        "options": {
-            "port": 3000,
-            "areaDir": "frontend",
-            "theme": "blank"
-        }
-    },
-    "lib": {
-        "options": {
-            "port": 8080
-        }
-    }
-}
\ No newline at end of file
diff --git a/dev/tools/grunt/configs/watch.js b/dev/tools/grunt/configs/watch.js
index f1a117ac8edb4dc079841f83c74edbb9c03f5b7f..ffe0fcc097e5216278f9c12f81455b7d63001ce9 100644
--- a/dev/tools/grunt/configs/watch.js
+++ b/dev/tools/grunt/configs/watch.js
@@ -25,6 +25,12 @@ var watchOptions = {
         "files": "<%= path.less.setup %>/**/*.less",
         "tasks": "less:setup"
     },
+    "reload": {
+        "files": "<%= path.pub %>/**/*.css",
+        "options": {
+            livereload: true
+        }
+    },
     "backendMigration": {
         "files": [
             "<%= combo.autopath(\"backend\",\"pub\") %>/css/styles.css"
diff --git a/dev/tools/grunt/tasks/deploy.js b/dev/tools/grunt/tasks/deploy.js
new file mode 100644
index 0000000000000000000000000000000000000000..bff8b1fabecaf8d9774a79aa3134c7163847ca30
--- /dev/null
+++ b/dev/tools/grunt/tasks/deploy.js
@@ -0,0 +1,35 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+module.exports = function (grunt) {
+    'use strict';
+
+    var exec    = require('child_process').execSync,
+        spawn   = require('child_process').spawn,
+        log     = grunt.log.write,
+        ok      = grunt.log.ok,
+        error   = grunt.log.error;
+
+    grunt.registerTask('deploy', function () {
+        var deploy,
+            done = this.async();
+
+        log('Cleaning "pub/static"...');
+        exec('rm -rf pub/static/*');
+        ok('"pub/static" is empty.');
+
+        log('Deploying Magento application...');
+        deploy = spawn('php', ['dev/tools/Magento/Tools/View/deploy.php']);
+
+        deploy.stdout.on('data', function (data) {
+            log(data);
+        });
+
+        deploy.stdin.on('data', function (data) {
+            error(data);
+        });
+
+        deploy.on('close', done);
+    });
+};
diff --git a/dev/tools/performance-toolkit/benchmark.jmx b/dev/tools/performance-toolkit/benchmark.jmx
index 1fe4919a59eb43c0f72910d7de13a1448d2b8ab8..7d3d7aef7fa0ab39b7dce61fa73f45e9972e59bd 100644
--- a/dev/tools/performance-toolkit/benchmark.jmx
+++ b/dev/tools/performance-toolkit/benchmark.jmx
@@ -316,7 +316,7 @@ props.put(&quot;category_name&quot;, vars.get(&quot;category_name&quot;));</stri
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
           <stringProp name="HTTPSampler.protocol"></stringProp>
           <stringProp name="HTTPSampler.contentEncoding">UTF-8</stringProp>
-          <stringProp name="HTTPSampler.path">${base_path}catalogsearch/result/?limit=30&amp;q=Simple</stringProp>
+          <stringProp name="HTTPSampler.path">${base_path}catalogsearch/result/index/?limit=30&amp;q=Simple</stringProp>
           <stringProp name="HTTPSampler.method">GET</stringProp>
           <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
@@ -340,7 +340,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">${base_path}(index.php/)?(simple.*)${url_suffix}&quot; title=&quot;[Ss]imple.*&quot;</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.template">$2$</stringProp>
             <stringProp name="RegexExtractor.default"></stringProp>
             <stringProp name="RegexExtractor.match_number">-1</stringProp>
@@ -386,7 +386,7 @@ props.put(&quot;category_name&quot;, vars.get(&quot;category_name&quot;));</stri
             <XPathExtractor guiclass="XPathExtractorGui" testclass="XPathExtractor" testname="XPath Extractor: Extarct product title" enabled="true">
               <stringProp name="XPathExtractor.default"></stringProp>
               <stringProp name="XPathExtractor.refname">simple_product_title</stringProp>
-              <stringProp name="XPathExtractor.xpathQuery">.//*[@data-ui-id=&apos;page-title&apos;]/text()</stringProp>
+              <stringProp name="XPathExtractor.xpathQuery">.//*[@data-ui-id=&apos;page-title-wrapper&apos;]/text()</stringProp>
               <boolProp name="XPathExtractor.validate">false</boolProp>
               <boolProp name="XPathExtractor.tolerant">true</boolProp>
               <boolProp name="XPathExtractor.namespace">false</boolProp>
@@ -471,7 +471,7 @@ productList.add(productMap);                        </stringProp>
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
           <stringProp name="HTTPSampler.protocol"></stringProp>
           <stringProp name="HTTPSampler.contentEncoding">UTF-8</stringProp>
-          <stringProp name="HTTPSampler.path">${base_path}catalogsearch/result/?limit=30&amp;q=Configurable</stringProp>
+          <stringProp name="HTTPSampler.path">${base_path}catalogsearch/result/index/?limit=30&amp;q=Configurable</stringProp>
           <stringProp name="HTTPSampler.method">GET</stringProp>
           <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
@@ -495,7 +495,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">${base_path}(index.php/)?(configurable.*)${url_suffix}&quot; title=&quot;[Cc]onfigurable.*&quot;</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.template">$2$</stringProp>
             <stringProp name="RegexExtractor.default"></stringProp>
             <stringProp name="RegexExtractor.match_number">-1</stringProp>
@@ -541,7 +541,7 @@ productList.add(productMap);                        </stringProp>
             <XPathExtractor guiclass="XPathExtractorGui" testclass="XPathExtractor" testname="XPath Extractor: Extarct product title" enabled="true">
               <stringProp name="XPathExtractor.default"></stringProp>
               <stringProp name="XPathExtractor.refname">configurable_product_title</stringProp>
-              <stringProp name="XPathExtractor.xpathQuery">.//*[@data-ui-id=&apos;page-title&apos;]/text()</stringProp>
+              <stringProp name="XPathExtractor.xpathQuery">.//*[@data-ui-id=&apos;page-title-wrapper&apos;]/text()</stringProp>
               <boolProp name="XPathExtractor.validate">false</boolProp>
               <boolProp name="XPathExtractor.tolerant">true</boolProp>
               <boolProp name="XPathExtractor.namespace">false</boolProp>
@@ -550,7 +550,7 @@ productList.add(productMap);                        </stringProp>
             <RegexExtractor guiclass="RegexExtractorGui" testclass="RegexExtractor" testname="Regular Expression Extractor: Extarct product attribute id" enabled="true">
               <stringProp name="RegexExtractor.useHeaders">false</stringProp>
               <stringProp name="RegexExtractor.refname">configurable_product_attribute_id</stringProp>
-              <stringProp name="RegexExtractor.regex">&quot;spConfig&quot;:\{&quot;attributes&quot;:\{&quot;(\d+)&quot;</stringProp>
+              <stringProp name="RegexExtractor.regex">&quot;attributes&quot;:\{&quot;(\d+)&quot;</stringProp>
               <stringProp name="RegexExtractor.template">$1$</stringProp>
               <stringProp name="RegexExtractor.default"></stringProp>
               <stringProp name="RegexExtractor.match_number">1</stringProp>
@@ -1401,6 +1401,26 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
             <intProp name="Assertion.test_type">2</intProp>
           </ResponseAssertion>
           <hashTree/>
+          <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.template">$1$</stringProp>
+            <stringProp name="RegexExtractor.default"></stringProp>
+            <stringProp name="RegexExtractor.match_number">1</stringProp>
+          </RegexExtractor>
+          <hashTree/>
+          <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Assert form_action extracted" enabled="true">
+            <collectionProp name="Asserion.test_strings">
+              <stringProp name="2845929">^.+$</stringProp>
+            </collectionProp>
+            <stringProp name="Assertion.test_field">Assertion.response_data</stringProp>
+            <boolProp name="Assertion.assume_success">false</boolProp>
+            <intProp name="Assertion.test_type">1</intProp>
+            <stringProp name="Assertion.scope">variable</stringProp>
+            <stringProp name="Scope.variable">simple_product_1_form_action</stringProp>
+          </ResponseAssertion>
+          <hashTree/>
         </hashTree>
         <GaussianRandomTimer guiclass="GaussianRandomTimerGui" testclass="GaussianRandomTimer" testname="Random Timer" enabled="true">
           <stringProp name="ConstantTimer.delay">${think_time_delay_offset}</stringProp>
@@ -1431,6 +1451,20 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
                 <boolProp name="HTTPArgument.use_equals">true</boolProp>
                 <stringProp name="Argument.name">qty</stringProp>
               </elementProp>
+              <elementProp name="isAjax" elementType="HTTPArgument">
+                <boolProp name="HTTPArgument.always_encode">false</boolProp>
+                <stringProp name="Argument.value">true</stringProp>
+                <stringProp name="Argument.metadata">=</stringProp>
+                <boolProp name="HTTPArgument.use_equals">true</boolProp>
+                <stringProp name="Argument.name">isAjax</stringProp>
+              </elementProp>
+              <elementProp name="ajax" elementType="HTTPArgument">
+                <boolProp name="HTTPArgument.always_encode">false</boolProp>
+                <stringProp name="Argument.value">true</stringProp>
+                <stringProp name="Argument.metadata">=</stringProp>
+                <boolProp name="HTTPArgument.use_equals">true</boolProp>
+                <stringProp name="Argument.name">ajax</stringProp>
+              </elementProp>
             </collectionProp>
           </elementProp>
           <stringProp name="HTTPSampler.domain"></stringProp>
@@ -1439,7 +1473,7 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
           <stringProp name="HTTPSampler.protocol">http</stringProp>
           <stringProp name="HTTPSampler.contentEncoding"></stringProp>
-          <stringProp name="HTTPSampler.path">${base_path}checkout/cart/add</stringProp>
+          <stringProp name="HTTPSampler.path">${simple_product_1_form_action}</stringProp>
           <stringProp name="HTTPSampler.method">POST</stringProp>
           <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
@@ -1468,17 +1502,6 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
             <intProp name="Assertion.test_type">6</intProp>
           </ResponseAssertion>
           <hashTree/>
-          <XPathAssertion guiclass="XPathAssertionGui" testclass="XPathAssertion" testname="XPath Assertion" enabled="true">
-            <boolProp name="XPath.negate">false</boolProp>
-            <stringProp name="XPath.xpath">count(//*[@class=&apos;cart item&apos;])=1</stringProp>
-            <boolProp name="XPath.validate">false</boolProp>
-            <boolProp name="XPath.whitespace">false</boolProp>
-            <boolProp name="XPath.tolerant">true</boolProp>
-            <boolProp name="XPath.namespace">false</boolProp>
-            <boolProp name="XPath.show_warnings">true</boolProp>
-            <boolProp name="XPath.report_errors">true</boolProp>
-          </XPathAssertion>
-          <hashTree/>
         </hashTree>
         <GaussianRandomTimer guiclass="GaussianRandomTimerGui" testclass="GaussianRandomTimer" testname="Random Timer" enabled="true">
           <stringProp name="ConstantTimer.delay">${think_time_delay_offset}</stringProp>
@@ -1516,6 +1539,26 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
             <intProp name="Assertion.test_type">2</intProp>
           </ResponseAssertion>
           <hashTree/>
+          <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.template">$1$</stringProp>
+            <stringProp name="RegexExtractor.default"></stringProp>
+            <stringProp name="RegexExtractor.match_number">1</stringProp>
+          </RegexExtractor>
+          <hashTree/>
+          <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Assert form_action extracted" enabled="true">
+            <collectionProp name="Asserion.test_strings">
+              <stringProp name="2845929">^.+$</stringProp>
+            </collectionProp>
+            <stringProp name="Assertion.test_field">Assertion.response_data</stringProp>
+            <boolProp name="Assertion.assume_success">false</boolProp>
+            <intProp name="Assertion.test_type">1</intProp>
+            <stringProp name="Assertion.scope">variable</stringProp>
+            <stringProp name="Scope.variable">simple_product_2_form_action</stringProp>
+          </ResponseAssertion>
+          <hashTree/>
         </hashTree>
         <GaussianRandomTimer guiclass="GaussianRandomTimerGui" testclass="GaussianRandomTimer" testname="Random Timer" enabled="true">
           <stringProp name="ConstantTimer.delay">${think_time_delay_offset}</stringProp>
@@ -1546,6 +1589,20 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
                 <boolProp name="HTTPArgument.use_equals">true</boolProp>
                 <stringProp name="Argument.name">qty</stringProp>
               </elementProp>
+              <elementProp name="isAjax" elementType="HTTPArgument">
+                <boolProp name="HTTPArgument.always_encode">false</boolProp>
+                <stringProp name="Argument.value">true</stringProp>
+                <stringProp name="Argument.metadata">=</stringProp>
+                <boolProp name="HTTPArgument.use_equals">true</boolProp>
+                <stringProp name="Argument.name">isAjax</stringProp>
+              </elementProp>
+              <elementProp name="ajax" elementType="HTTPArgument">
+                <boolProp name="HTTPArgument.always_encode">false</boolProp>
+                <stringProp name="Argument.value">true</stringProp>
+                <stringProp name="Argument.metadata">=</stringProp>
+                <boolProp name="HTTPArgument.use_equals">true</boolProp>
+                <stringProp name="Argument.name">ajax</stringProp>
+              </elementProp>
             </collectionProp>
           </elementProp>
           <stringProp name="HTTPSampler.domain"></stringProp>
@@ -1554,7 +1611,7 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
           <stringProp name="HTTPSampler.protocol">http</stringProp>
           <stringProp name="HTTPSampler.contentEncoding"></stringProp>
-          <stringProp name="HTTPSampler.path">${base_path}checkout/cart/add</stringProp>
+          <stringProp name="HTTPSampler.path">${simple_product_2_form_action}</stringProp>
           <stringProp name="HTTPSampler.method">POST</stringProp>
           <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
@@ -1583,17 +1640,6 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
             <intProp name="Assertion.test_type">6</intProp>
           </ResponseAssertion>
           <hashTree/>
-          <XPathAssertion guiclass="XPathAssertionGui" testclass="XPathAssertion" testname="XPath Assertion" enabled="true">
-            <boolProp name="XPath.negate">false</boolProp>
-            <stringProp name="XPath.xpath">count(//*[@class=&apos;cart item&apos;])=2</stringProp>
-            <boolProp name="XPath.validate">false</boolProp>
-            <boolProp name="XPath.whitespace">false</boolProp>
-            <boolProp name="XPath.tolerant">true</boolProp>
-            <boolProp name="XPath.namespace">false</boolProp>
-            <boolProp name="XPath.show_warnings">true</boolProp>
-            <boolProp name="XPath.report_errors">true</boolProp>
-          </XPathAssertion>
-          <hashTree/>
         </hashTree>
         <GaussianRandomTimer guiclass="GaussianRandomTimerGui" testclass="GaussianRandomTimer" testname="Random Timer" enabled="true">
           <stringProp name="ConstantTimer.delay">${think_time_delay_offset}</stringProp>
@@ -1631,6 +1677,26 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
             <intProp name="Assertion.test_type">2</intProp>
           </ResponseAssertion>
           <hashTree/>
+          <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.template">$1$</stringProp>
+            <stringProp name="RegexExtractor.default"></stringProp>
+            <stringProp name="RegexExtractor.match_number">1</stringProp>
+          </RegexExtractor>
+          <hashTree/>
+          <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Assert form_action extracted" enabled="true">
+            <collectionProp name="Asserion.test_strings">
+              <stringProp name="2845929">^.+$</stringProp>
+            </collectionProp>
+            <stringProp name="Assertion.test_field">Assertion.response_data</stringProp>
+            <boolProp name="Assertion.assume_success">false</boolProp>
+            <intProp name="Assertion.test_type">1</intProp>
+            <stringProp name="Assertion.scope">variable</stringProp>
+            <stringProp name="Scope.variable">configurable_product_form_action</stringProp>
+          </ResponseAssertion>
+          <hashTree/>
         </hashTree>
         <GaussianRandomTimer guiclass="GaussianRandomTimerGui" testclass="GaussianRandomTimer" testname="Random Timer" enabled="true">
           <stringProp name="ConstantTimer.delay">${think_time_delay_offset}</stringProp>
@@ -1668,6 +1734,20 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
                 <boolProp name="HTTPArgument.use_equals">true</boolProp>
                 <stringProp name="Argument.name">super_attribute[${configurable_attribute_id}]</stringProp>
               </elementProp>
+              <elementProp name="isAjax" elementType="HTTPArgument">
+                <boolProp name="HTTPArgument.always_encode">false</boolProp>
+                <stringProp name="Argument.value">true</stringProp>
+                <stringProp name="Argument.metadata">=</stringProp>
+                <boolProp name="HTTPArgument.use_equals">true</boolProp>
+                <stringProp name="Argument.name">isAjax</stringProp>
+              </elementProp>
+              <elementProp name="ajax" elementType="HTTPArgument">
+                <boolProp name="HTTPArgument.always_encode">false</boolProp>
+                <stringProp name="Argument.value">true</stringProp>
+                <stringProp name="Argument.metadata">=</stringProp>
+                <boolProp name="HTTPArgument.use_equals">true</boolProp>
+                <stringProp name="Argument.name">ajax</stringProp>
+              </elementProp>
             </collectionProp>
           </elementProp>
           <stringProp name="HTTPSampler.domain"></stringProp>
@@ -1676,7 +1756,7 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
           <stringProp name="HTTPSampler.protocol">http</stringProp>
           <stringProp name="HTTPSampler.contentEncoding"></stringProp>
-          <stringProp name="HTTPSampler.path">${base_path}checkout/cart/add</stringProp>
+          <stringProp name="HTTPSampler.path">${configurable_product_form_action}</stringProp>
           <stringProp name="HTTPSampler.method">POST</stringProp>
           <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
@@ -1705,17 +1785,6 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
             <intProp name="Assertion.test_type">6</intProp>
           </ResponseAssertion>
           <hashTree/>
-          <XPathAssertion guiclass="XPathAssertionGui" testclass="XPathAssertion" testname="XPath Assertion" enabled="true">
-            <boolProp name="XPath.negate">false</boolProp>
-            <stringProp name="XPath.xpath">count(//*[@class=&apos;cart item&apos;])=3</stringProp>
-            <boolProp name="XPath.validate">false</boolProp>
-            <boolProp name="XPath.whitespace">false</boolProp>
-            <boolProp name="XPath.tolerant">true</boolProp>
-            <boolProp name="XPath.namespace">false</boolProp>
-            <boolProp name="XPath.show_warnings">true</boolProp>
-            <boolProp name="XPath.report_errors">true</boolProp>
-          </XPathAssertion>
-          <hashTree/>
         </hashTree>
       </hashTree>
       <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Guest Checkout" enabled="true">
@@ -1882,6 +1951,26 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
             <intProp name="Assertion.test_type">2</intProp>
           </ResponseAssertion>
           <hashTree/>
+          <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.template">$1$</stringProp>
+            <stringProp name="RegexExtractor.default"></stringProp>
+            <stringProp name="RegexExtractor.match_number">1</stringProp>
+          </RegexExtractor>
+          <hashTree/>
+          <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Assert form_action extracted" enabled="true">
+            <collectionProp name="Asserion.test_strings">
+              <stringProp name="2845929">^.+$</stringProp>
+            </collectionProp>
+            <stringProp name="Assertion.test_field">Assertion.response_data</stringProp>
+            <boolProp name="Assertion.assume_success">false</boolProp>
+            <intProp name="Assertion.test_type">1</intProp>
+            <stringProp name="Assertion.scope">variable</stringProp>
+            <stringProp name="Scope.variable">simple_product_1_form_action</stringProp>
+          </ResponseAssertion>
+          <hashTree/>
         </hashTree>
         <GaussianRandomTimer guiclass="GaussianRandomTimerGui" testclass="GaussianRandomTimer" testname="Random Timer" enabled="true">
           <stringProp name="ConstantTimer.delay">${think_time_delay_offset}</stringProp>
@@ -1912,6 +2001,20 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
                 <boolProp name="HTTPArgument.use_equals">true</boolProp>
                 <stringProp name="Argument.name">qty</stringProp>
               </elementProp>
+              <elementProp name="isAjax" elementType="HTTPArgument">
+                <boolProp name="HTTPArgument.always_encode">false</boolProp>
+                <stringProp name="Argument.value">true</stringProp>
+                <stringProp name="Argument.metadata">=</stringProp>
+                <boolProp name="HTTPArgument.use_equals">true</boolProp>
+                <stringProp name="Argument.name">isAjax</stringProp>
+              </elementProp>
+              <elementProp name="ajax" elementType="HTTPArgument">
+                <boolProp name="HTTPArgument.always_encode">false</boolProp>
+                <stringProp name="Argument.value">true</stringProp>
+                <stringProp name="Argument.metadata">=</stringProp>
+                <boolProp name="HTTPArgument.use_equals">true</boolProp>
+                <stringProp name="Argument.name">ajax</stringProp>
+              </elementProp>
             </collectionProp>
           </elementProp>
           <stringProp name="HTTPSampler.domain"></stringProp>
@@ -1920,7 +2023,7 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
           <stringProp name="HTTPSampler.protocol">http</stringProp>
           <stringProp name="HTTPSampler.contentEncoding"></stringProp>
-          <stringProp name="HTTPSampler.path">${base_path}checkout/cart/add</stringProp>
+          <stringProp name="HTTPSampler.path">${simple_product_1_form_action}</stringProp>
           <stringProp name="HTTPSampler.method">POST</stringProp>
           <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
@@ -1949,17 +2052,6 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
             <intProp name="Assertion.test_type">6</intProp>
           </ResponseAssertion>
           <hashTree/>
-          <XPathAssertion guiclass="XPathAssertionGui" testclass="XPathAssertion" testname="XPath Assertion" enabled="true">
-            <boolProp name="XPath.negate">false</boolProp>
-            <stringProp name="XPath.xpath">count(//*[@class=&apos;cart item&apos;])=1</stringProp>
-            <boolProp name="XPath.validate">false</boolProp>
-            <boolProp name="XPath.whitespace">false</boolProp>
-            <boolProp name="XPath.tolerant">true</boolProp>
-            <boolProp name="XPath.namespace">false</boolProp>
-            <boolProp name="XPath.show_warnings">true</boolProp>
-            <boolProp name="XPath.report_errors">true</boolProp>
-          </XPathAssertion>
-          <hashTree/>
         </hashTree>
         <GaussianRandomTimer guiclass="GaussianRandomTimerGui" testclass="GaussianRandomTimer" testname="Random Timer" enabled="true">
           <stringProp name="ConstantTimer.delay">${think_time_delay_offset}</stringProp>
@@ -1997,6 +2089,26 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
             <intProp name="Assertion.test_type">2</intProp>
           </ResponseAssertion>
           <hashTree/>
+          <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.template">$1$</stringProp>
+            <stringProp name="RegexExtractor.default"></stringProp>
+            <stringProp name="RegexExtractor.match_number">1</stringProp>
+          </RegexExtractor>
+          <hashTree/>
+          <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Assert form_action extracted" enabled="true">
+            <collectionProp name="Asserion.test_strings">
+              <stringProp name="2845929">^.+$</stringProp>
+            </collectionProp>
+            <stringProp name="Assertion.test_field">Assertion.response_data</stringProp>
+            <boolProp name="Assertion.assume_success">false</boolProp>
+            <intProp name="Assertion.test_type">1</intProp>
+            <stringProp name="Assertion.scope">variable</stringProp>
+            <stringProp name="Scope.variable">simple_product_2_form_action</stringProp>
+          </ResponseAssertion>
+          <hashTree/>
         </hashTree>
         <GaussianRandomTimer guiclass="GaussianRandomTimerGui" testclass="GaussianRandomTimer" testname="Random Timer" enabled="true">
           <stringProp name="ConstantTimer.delay">${think_time_delay_offset}</stringProp>
@@ -2027,6 +2139,20 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
                 <boolProp name="HTTPArgument.use_equals">true</boolProp>
                 <stringProp name="Argument.name">qty</stringProp>
               </elementProp>
+              <elementProp name="isAjax" elementType="HTTPArgument">
+                <boolProp name="HTTPArgument.always_encode">false</boolProp>
+                <stringProp name="Argument.value">true</stringProp>
+                <stringProp name="Argument.metadata">=</stringProp>
+                <boolProp name="HTTPArgument.use_equals">true</boolProp>
+                <stringProp name="Argument.name">isAjax</stringProp>
+              </elementProp>
+              <elementProp name="ajax" elementType="HTTPArgument">
+                <boolProp name="HTTPArgument.always_encode">false</boolProp>
+                <stringProp name="Argument.value">true</stringProp>
+                <stringProp name="Argument.metadata">=</stringProp>
+                <boolProp name="HTTPArgument.use_equals">true</boolProp>
+                <stringProp name="Argument.name">ajax</stringProp>
+              </elementProp>
             </collectionProp>
           </elementProp>
           <stringProp name="HTTPSampler.domain"></stringProp>
@@ -2035,7 +2161,7 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
           <stringProp name="HTTPSampler.protocol">http</stringProp>
           <stringProp name="HTTPSampler.contentEncoding"></stringProp>
-          <stringProp name="HTTPSampler.path">${base_path}checkout/cart/add</stringProp>
+          <stringProp name="HTTPSampler.path">${simple_product_2_form_action}</stringProp>
           <stringProp name="HTTPSampler.method">POST</stringProp>
           <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
@@ -2064,17 +2190,6 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
             <intProp name="Assertion.test_type">6</intProp>
           </ResponseAssertion>
           <hashTree/>
-          <XPathAssertion guiclass="XPathAssertionGui" testclass="XPathAssertion" testname="XPath Assertion" enabled="true">
-            <boolProp name="XPath.negate">false</boolProp>
-            <stringProp name="XPath.xpath">count(//*[@class=&apos;cart item&apos;])=2</stringProp>
-            <boolProp name="XPath.validate">false</boolProp>
-            <boolProp name="XPath.whitespace">false</boolProp>
-            <boolProp name="XPath.tolerant">true</boolProp>
-            <boolProp name="XPath.namespace">false</boolProp>
-            <boolProp name="XPath.show_warnings">true</boolProp>
-            <boolProp name="XPath.report_errors">true</boolProp>
-          </XPathAssertion>
-          <hashTree/>
         </hashTree>
         <GaussianRandomTimer guiclass="GaussianRandomTimerGui" testclass="GaussianRandomTimer" testname="Random Timer" enabled="true">
           <stringProp name="ConstantTimer.delay">${think_time_delay_offset}</stringProp>
@@ -2112,6 +2227,26 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
             <intProp name="Assertion.test_type">2</intProp>
           </ResponseAssertion>
           <hashTree/>
+          <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.template">$1$</stringProp>
+            <stringProp name="RegexExtractor.default"></stringProp>
+            <stringProp name="RegexExtractor.match_number">1</stringProp>
+          </RegexExtractor>
+          <hashTree/>
+          <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Assert form_action extracted" enabled="true">
+            <collectionProp name="Asserion.test_strings">
+              <stringProp name="2845929">^.+$</stringProp>
+            </collectionProp>
+            <stringProp name="Assertion.test_field">Assertion.response_data</stringProp>
+            <boolProp name="Assertion.assume_success">false</boolProp>
+            <intProp name="Assertion.test_type">1</intProp>
+            <stringProp name="Assertion.scope">variable</stringProp>
+            <stringProp name="Scope.variable">configurable_product_form_action</stringProp>
+          </ResponseAssertion>
+          <hashTree/>
         </hashTree>
         <GaussianRandomTimer guiclass="GaussianRandomTimerGui" testclass="GaussianRandomTimer" testname="Random Timer" enabled="true">
           <stringProp name="ConstantTimer.delay">${think_time_delay_offset}</stringProp>
@@ -2149,6 +2284,20 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
                 <boolProp name="HTTPArgument.use_equals">true</boolProp>
                 <stringProp name="Argument.name">super_attribute[${configurable_attribute_id}]</stringProp>
               </elementProp>
+              <elementProp name="isAjax" elementType="HTTPArgument">
+                <boolProp name="HTTPArgument.always_encode">false</boolProp>
+                <stringProp name="Argument.value">true</stringProp>
+                <stringProp name="Argument.metadata">=</stringProp>
+                <boolProp name="HTTPArgument.use_equals">true</boolProp>
+                <stringProp name="Argument.name">isAjax</stringProp>
+              </elementProp>
+              <elementProp name="ajax" elementType="HTTPArgument">
+                <boolProp name="HTTPArgument.always_encode">false</boolProp>
+                <stringProp name="Argument.value">true</stringProp>
+                <stringProp name="Argument.metadata">=</stringProp>
+                <boolProp name="HTTPArgument.use_equals">true</boolProp>
+                <stringProp name="Argument.name">ajax</stringProp>
+              </elementProp>
             </collectionProp>
           </elementProp>
           <stringProp name="HTTPSampler.domain"></stringProp>
@@ -2157,7 +2306,7 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
           <stringProp name="HTTPSampler.protocol">http</stringProp>
           <stringProp name="HTTPSampler.contentEncoding"></stringProp>
-          <stringProp name="HTTPSampler.path">${base_path}checkout/cart/add</stringProp>
+          <stringProp name="HTTPSampler.path">${configurable_product_form_action}</stringProp>
           <stringProp name="HTTPSampler.method">POST</stringProp>
           <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
@@ -2186,17 +2335,6 @@ vars.put(&quot;category_name&quot;, props.get(&quot;category_name&quot;));</stri
             <intProp name="Assertion.test_type">6</intProp>
           </ResponseAssertion>
           <hashTree/>
-          <XPathAssertion guiclass="XPathAssertionGui" testclass="XPathAssertion" testname="XPath Assertion" enabled="true">
-            <boolProp name="XPath.negate">false</boolProp>
-            <stringProp name="XPath.xpath">count(//*[@class=&apos;cart item&apos;])=3</stringProp>
-            <boolProp name="XPath.validate">false</boolProp>
-            <boolProp name="XPath.whitespace">false</boolProp>
-            <boolProp name="XPath.tolerant">true</boolProp>
-            <boolProp name="XPath.namespace">false</boolProp>
-            <boolProp name="XPath.show_warnings">true</boolProp>
-            <boolProp name="XPath.report_errors">true</boolProp>
-          </XPathAssertion>
-          <hashTree/>
         </hashTree>
         <GaussianRandomTimer guiclass="GaussianRandomTimerGui" testclass="GaussianRandomTimer" testname="Random Timer" enabled="true">
           <stringProp name="ConstantTimer.delay">${think_time_delay_offset}</stringProp>
@@ -2932,6 +3070,26 @@ if (emailsCount &lt; 1) {
             <intProp name="Assertion.test_type">2</intProp>
           </ResponseAssertion>
           <hashTree/>
+          <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.template">$1$</stringProp>
+            <stringProp name="RegexExtractor.default"></stringProp>
+            <stringProp name="RegexExtractor.match_number">1</stringProp>
+          </RegexExtractor>
+          <hashTree/>
+          <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Assert form_action extracted" enabled="true">
+            <collectionProp name="Asserion.test_strings">
+              <stringProp name="2845929">^.+$</stringProp>
+            </collectionProp>
+            <stringProp name="Assertion.test_field">Assertion.response_data</stringProp>
+            <boolProp name="Assertion.assume_success">false</boolProp>
+            <intProp name="Assertion.test_type">1</intProp>
+            <stringProp name="Assertion.scope">variable</stringProp>
+            <stringProp name="Scope.variable">simple_product_1_form_action</stringProp>
+          </ResponseAssertion>
+          <hashTree/>
         </hashTree>
         <GaussianRandomTimer guiclass="GaussianRandomTimerGui" testclass="GaussianRandomTimer" testname="Random Timer" enabled="true">
           <stringProp name="ConstantTimer.delay">${think_time_delay_offset}</stringProp>
@@ -2962,6 +3120,20 @@ if (emailsCount &lt; 1) {
                 <boolProp name="HTTPArgument.use_equals">true</boolProp>
                 <stringProp name="Argument.name">qty</stringProp>
               </elementProp>
+              <elementProp name="isAjax" elementType="HTTPArgument">
+                <boolProp name="HTTPArgument.always_encode">false</boolProp>
+                <stringProp name="Argument.value">true</stringProp>
+                <stringProp name="Argument.metadata">=</stringProp>
+                <boolProp name="HTTPArgument.use_equals">true</boolProp>
+                <stringProp name="Argument.name">isAjax</stringProp>
+              </elementProp>
+              <elementProp name="ajax" elementType="HTTPArgument">
+                <boolProp name="HTTPArgument.always_encode">false</boolProp>
+                <stringProp name="Argument.value">true</stringProp>
+                <stringProp name="Argument.metadata">=</stringProp>
+                <boolProp name="HTTPArgument.use_equals">true</boolProp>
+                <stringProp name="Argument.name">ajax</stringProp>
+              </elementProp>
             </collectionProp>
           </elementProp>
           <stringProp name="HTTPSampler.domain"></stringProp>
@@ -2970,7 +3142,7 @@ if (emailsCount &lt; 1) {
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
           <stringProp name="HTTPSampler.protocol">http</stringProp>
           <stringProp name="HTTPSampler.contentEncoding"></stringProp>
-          <stringProp name="HTTPSampler.path">${base_path}checkout/cart/add</stringProp>
+          <stringProp name="HTTPSampler.path">${simple_product_1_form_action}</stringProp>
           <stringProp name="HTTPSampler.method">POST</stringProp>
           <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
@@ -2999,17 +3171,6 @@ if (emailsCount &lt; 1) {
             <intProp name="Assertion.test_type">6</intProp>
           </ResponseAssertion>
           <hashTree/>
-          <XPathAssertion guiclass="XPathAssertionGui" testclass="XPathAssertion" testname="XPath Assertion" enabled="true">
-            <boolProp name="XPath.negate">false</boolProp>
-            <stringProp name="XPath.xpath">count(//*[@class=&apos;cart item&apos;])=1</stringProp>
-            <boolProp name="XPath.validate">false</boolProp>
-            <boolProp name="XPath.whitespace">false</boolProp>
-            <boolProp name="XPath.tolerant">true</boolProp>
-            <boolProp name="XPath.namespace">false</boolProp>
-            <boolProp name="XPath.show_warnings">true</boolProp>
-            <boolProp name="XPath.report_errors">true</boolProp>
-          </XPathAssertion>
-          <hashTree/>
         </hashTree>
         <GaussianRandomTimer guiclass="GaussianRandomTimerGui" testclass="GaussianRandomTimer" testname="Random Timer" enabled="true">
           <stringProp name="ConstantTimer.delay">${think_time_delay_offset}</stringProp>
@@ -3047,6 +3208,26 @@ if (emailsCount &lt; 1) {
             <intProp name="Assertion.test_type">2</intProp>
           </ResponseAssertion>
           <hashTree/>
+          <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.template">$1$</stringProp>
+            <stringProp name="RegexExtractor.default"></stringProp>
+            <stringProp name="RegexExtractor.match_number">1</stringProp>
+          </RegexExtractor>
+          <hashTree/>
+          <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Assert form_action extracted" enabled="true">
+            <collectionProp name="Asserion.test_strings">
+              <stringProp name="2845929">^.+$</stringProp>
+            </collectionProp>
+            <stringProp name="Assertion.test_field">Assertion.response_data</stringProp>
+            <boolProp name="Assertion.assume_success">false</boolProp>
+            <intProp name="Assertion.test_type">1</intProp>
+            <stringProp name="Assertion.scope">variable</stringProp>
+            <stringProp name="Scope.variable">simple_product_2_form_action</stringProp>
+          </ResponseAssertion>
+          <hashTree/>
         </hashTree>
         <GaussianRandomTimer guiclass="GaussianRandomTimerGui" testclass="GaussianRandomTimer" testname="Random Timer" enabled="true">
           <stringProp name="ConstantTimer.delay">${think_time_delay_offset}</stringProp>
@@ -3077,6 +3258,20 @@ if (emailsCount &lt; 1) {
                 <boolProp name="HTTPArgument.use_equals">true</boolProp>
                 <stringProp name="Argument.name">qty</stringProp>
               </elementProp>
+              <elementProp name="isAjax" elementType="HTTPArgument">
+                <boolProp name="HTTPArgument.always_encode">false</boolProp>
+                <stringProp name="Argument.value">true</stringProp>
+                <stringProp name="Argument.metadata">=</stringProp>
+                <boolProp name="HTTPArgument.use_equals">true</boolProp>
+                <stringProp name="Argument.name">isAjax</stringProp>
+              </elementProp>
+              <elementProp name="ajax" elementType="HTTPArgument">
+                <boolProp name="HTTPArgument.always_encode">false</boolProp>
+                <stringProp name="Argument.value">true</stringProp>
+                <stringProp name="Argument.metadata">=</stringProp>
+                <boolProp name="HTTPArgument.use_equals">true</boolProp>
+                <stringProp name="Argument.name">ajax</stringProp>
+              </elementProp>
             </collectionProp>
           </elementProp>
           <stringProp name="HTTPSampler.domain"></stringProp>
@@ -3085,7 +3280,7 @@ if (emailsCount &lt; 1) {
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
           <stringProp name="HTTPSampler.protocol">http</stringProp>
           <stringProp name="HTTPSampler.contentEncoding"></stringProp>
-          <stringProp name="HTTPSampler.path">${base_path}checkout/cart/add</stringProp>
+          <stringProp name="HTTPSampler.path">${simple_product_2_form_action}</stringProp>
           <stringProp name="HTTPSampler.method">POST</stringProp>
           <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
@@ -3114,17 +3309,6 @@ if (emailsCount &lt; 1) {
             <intProp name="Assertion.test_type">6</intProp>
           </ResponseAssertion>
           <hashTree/>
-          <XPathAssertion guiclass="XPathAssertionGui" testclass="XPathAssertion" testname="XPath Assertion" enabled="true">
-            <boolProp name="XPath.negate">false</boolProp>
-            <stringProp name="XPath.xpath">count(//*[@class=&apos;cart item&apos;])=2</stringProp>
-            <boolProp name="XPath.validate">false</boolProp>
-            <boolProp name="XPath.whitespace">false</boolProp>
-            <boolProp name="XPath.tolerant">true</boolProp>
-            <boolProp name="XPath.namespace">false</boolProp>
-            <boolProp name="XPath.show_warnings">true</boolProp>
-            <boolProp name="XPath.report_errors">true</boolProp>
-          </XPathAssertion>
-          <hashTree/>
         </hashTree>
         <GaussianRandomTimer guiclass="GaussianRandomTimerGui" testclass="GaussianRandomTimer" testname="Random Timer" enabled="true">
           <stringProp name="ConstantTimer.delay">${think_time_delay_offset}</stringProp>
@@ -3162,6 +3346,26 @@ if (emailsCount &lt; 1) {
             <intProp name="Assertion.test_type">2</intProp>
           </ResponseAssertion>
           <hashTree/>
+          <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.template">$1$</stringProp>
+            <stringProp name="RegexExtractor.default"></stringProp>
+            <stringProp name="RegexExtractor.match_number">1</stringProp>
+          </RegexExtractor>
+          <hashTree/>
+          <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Assert form_action extracted" enabled="true">
+            <collectionProp name="Asserion.test_strings">
+              <stringProp name="2845929">^.+$</stringProp>
+            </collectionProp>
+            <stringProp name="Assertion.test_field">Assertion.response_data</stringProp>
+            <boolProp name="Assertion.assume_success">false</boolProp>
+            <intProp name="Assertion.test_type">1</intProp>
+            <stringProp name="Assertion.scope">variable</stringProp>
+            <stringProp name="Scope.variable">configurable_product_form_action</stringProp>
+          </ResponseAssertion>
+          <hashTree/>
         </hashTree>
         <GaussianRandomTimer guiclass="GaussianRandomTimerGui" testclass="GaussianRandomTimer" testname="Random Timer" enabled="true">
           <stringProp name="ConstantTimer.delay">${think_time_delay_offset}</stringProp>
@@ -3199,6 +3403,20 @@ if (emailsCount &lt; 1) {
                 <boolProp name="HTTPArgument.use_equals">true</boolProp>
                 <stringProp name="Argument.name">super_attribute[${configurable_attribute_id}]</stringProp>
               </elementProp>
+              <elementProp name="isAjax" elementType="HTTPArgument">
+                <boolProp name="HTTPArgument.always_encode">false</boolProp>
+                <stringProp name="Argument.value">true</stringProp>
+                <stringProp name="Argument.metadata">=</stringProp>
+                <boolProp name="HTTPArgument.use_equals">true</boolProp>
+                <stringProp name="Argument.name">isAjax</stringProp>
+              </elementProp>
+              <elementProp name="ajax" elementType="HTTPArgument">
+                <boolProp name="HTTPArgument.always_encode">false</boolProp>
+                <stringProp name="Argument.value">true</stringProp>
+                <stringProp name="Argument.metadata">=</stringProp>
+                <boolProp name="HTTPArgument.use_equals">true</boolProp>
+                <stringProp name="Argument.name">ajax</stringProp>
+              </elementProp>
             </collectionProp>
           </elementProp>
           <stringProp name="HTTPSampler.domain"></stringProp>
@@ -3207,7 +3425,7 @@ if (emailsCount &lt; 1) {
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
           <stringProp name="HTTPSampler.protocol">http</stringProp>
           <stringProp name="HTTPSampler.contentEncoding"></stringProp>
-          <stringProp name="HTTPSampler.path">${base_path}checkout/cart/add</stringProp>
+          <stringProp name="HTTPSampler.path">${configurable_product_form_action}</stringProp>
           <stringProp name="HTTPSampler.method">POST</stringProp>
           <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
@@ -3236,17 +3454,6 @@ if (emailsCount &lt; 1) {
             <intProp name="Assertion.test_type">6</intProp>
           </ResponseAssertion>
           <hashTree/>
-          <XPathAssertion guiclass="XPathAssertionGui" testclass="XPathAssertion" testname="XPath Assertion" enabled="true">
-            <boolProp name="XPath.negate">false</boolProp>
-            <stringProp name="XPath.xpath">count(//*[@class=&apos;cart item&apos;])=3</stringProp>
-            <boolProp name="XPath.validate">false</boolProp>
-            <boolProp name="XPath.whitespace">false</boolProp>
-            <boolProp name="XPath.tolerant">true</boolProp>
-            <boolProp name="XPath.namespace">false</boolProp>
-            <boolProp name="XPath.show_warnings">true</boolProp>
-            <boolProp name="XPath.report_errors">true</boolProp>
-          </XPathAssertion>
-          <hashTree/>
         </hashTree>
         <GaussianRandomTimer guiclass="GaussianRandomTimerGui" testclass="GaussianRandomTimer" testname="Random Timer" enabled="true">
           <stringProp name="ConstantTimer.delay">${think_time_delay_offset}</stringProp>
diff --git a/dev/tools/performance-toolkit/generate.php b/dev/tools/performance-toolkit/generate.php
index 43a4d61cc09621160a16435766c723f5fbabb5b2..861abee07ef81a10ceee9e80fc2aa9ef91ccb20d 100644
--- a/dev/tools/performance-toolkit/generate.php
+++ b/dev/tools/performance-toolkit/generate.php
@@ -41,6 +41,18 @@ try {
         echo ' |- ' . $label . ': ' . $config->getValue($configKey) . PHP_EOL;
     }
 
+    /** @var $config \Magento\Indexer\Model\Config */
+    $config = $application->getObjectManager()->get('Magento\Indexer\Model\Config');
+    $indexerListIds = $config->getIndexers();
+    /** @var $indexerRegistry \Magento\Indexer\Model\IndexerRegistry */
+    $indexerRegistry = $application->getObjectManager()->create('Magento\Indexer\Model\IndexerRegistry');
+    $indexersState = [];
+    foreach ($indexerListIds as $key => $indexerId) {
+        $indexer = $indexerRegistry->get($indexerId['indexer_id']);
+        $indexersState[$indexerId['indexer_id']] = $indexer->isScheduled();
+        $indexer->setScheduled(true);
+    }
+
     foreach ($application->getFixtures() as $fixture) {
         echo $fixture->getActionTitle() . '... ';
         $startTime = microtime(true);
@@ -50,6 +62,12 @@ try {
         echo ' done in ' . gmdate('H:i:s', $resultTime) . PHP_EOL;
     }
 
+    foreach ($indexerListIds as $indexerId) {
+        /** @var $indexer \Magento\Indexer\Model\Indexer */
+        $indexer = $indexerRegistry->get($indexerId['indexer_id']);
+        $indexer->setScheduled($indexersState[$indexerId['indexer_id']]);
+    }
+
     $application->reindex();
     $totalEndTime = microtime(true);
     $totalResultTime = $totalEndTime - $totalStartTime;
diff --git a/lib/internal/Magento/Framework/Api/SearchCriteria.php b/lib/internal/Magento/Framework/Api/SearchCriteria.php
index 727be2cac88b47b98e73fc919a2cb47057997433..b98908fcb85d6756df137cb48d526fed1b3ce184 100644
--- a/lib/internal/Magento/Framework/Api/SearchCriteria.php
+++ b/lib/internal/Magento/Framework/Api/SearchCriteria.php
@@ -15,7 +15,7 @@ class SearchCriteria extends AbstractSimpleObject implements SearchCriteriaInter
     /**#@+
      * Constants for Data Object keys
      */
-    const FILTER_GROUPS = 'filterGroups';
+    const FILTER_GROUPS = 'filter_groups';
     const SORT_ORDERS = 'sort_orders';
     const PAGE_SIZE = 'page_size';
     const CURRENT_PAGE = 'current_page';
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
index 94a8dcbcb22a93738bba019ae1e4c9d4e168cbe6..a89986314b2ca32c7aac579cf2ab2ab95361eb09 100644
--- a/lib/internal/Magento/Framework/App/Test/Unit/View/Deployment/VersionTest.php
+++ b/lib/internal/Magento/Framework/App/Test/Unit/View/Deployment/VersionTest.php
@@ -40,7 +40,7 @@ class VersionTest extends \PHPUnit_Framework_TestCase
             ->method('getMode')
             ->will($this->returnValue(\Magento\Framework\App\State::MODE_DEVELOPER));
         $this->versionStorage->expects($this->never())->method($this->anything());
-        $this->assertEquals(time(), $this->object->getValue());
+        $this->assertEquals(time(), $this->object->getValue(), '', 5);
         $this->object->getValue(); // Ensure computation occurs only once and result is cached in memory
     }
 
@@ -80,7 +80,7 @@ class VersionTest extends \PHPUnit_Framework_TestCase
             ->expects($this->once())
             ->method('load')
             ->will($this->throwException($storageException));
-        $this->versionStorage->expects($this->once())->method('save')->with(time());
+        $this->versionStorage->expects($this->once())->method('save')->with($this->equalTo(time(), 5));
         $this->assertEquals(time(), $this->object->getValue());
         $this->object->getValue(); // Ensure caching in memory
     }
diff --git a/lib/internal/Magento/Framework/AppInterface.php b/lib/internal/Magento/Framework/AppInterface.php
index 85c2186e67320a90827eb1499b604e9a1ade03ea..8d7f705d6661566cdaef4c424cdb9a8a351dea29 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-beta1';
+    const VERSION = '0.74.0-beta2';
 
     /**
      * Launch application
diff --git a/lib/internal/Magento/Framework/Code/Minifier/Adapter/Css/CssMinifier.php b/lib/internal/Magento/Framework/Code/Minifier/Adapter/Css/CssMinifier.php
index dddf0a6e4c00605e256cb9e1f349ea9c050df343..e1d4d01942333670ac1799df0820c589520b8118 100644
--- a/lib/internal/Magento/Framework/Code/Minifier/Adapter/Css/CssMinifier.php
+++ b/lib/internal/Magento/Framework/Code/Minifier/Adapter/Css/CssMinifier.php
@@ -11,6 +11,11 @@ use Magento\Framework\Code\Minifier\AdapterInterface;
 
 class CssMinifier implements AdapterInterface
 {
+    /**
+     * 'pcre.recursion_limit' value for CSSMin minification
+     */
+    const PCRE_RECURSION_LIMIT = 1000;
+
     /**
      * @var CSSmin
      */
@@ -32,6 +37,10 @@ class CssMinifier implements AdapterInterface
      */
     public function minify($content)
     {
-        return $this->cssMinifier->run($content);
+        $pcreRecursionLimit = ini_get('pcre.recursion_limit');
+        ini_set('pcre.recursion_limit', self::PCRE_RECURSION_LIMIT);
+        $result = $this->cssMinifier->run($content);
+        ini_set('pcre.recursion_limit', $pcreRecursionLimit);
+        return $result;
     }
 }
diff --git a/lib/internal/Magento/Framework/Data/Tree/NodeFactory.php b/lib/internal/Magento/Framework/Data/Tree/NodeFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..0fa561adbd7aa9f6f0bf7fe1720d47f85b9a5c40
--- /dev/null
+++ b/lib/internal/Magento/Framework/Data/Tree/NodeFactory.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Framework\Data\Tree;
+
+use Magento\Framework\ObjectManagerInterface;
+
+/**
+ * Factory class for @see \Magento\Framework\Data\Tree\Node
+ */
+class NodeFactory
+{
+    /**
+     * Object Manager instance
+     *
+     * @var ObjectManagerInterface
+     */
+    protected $objectManager;
+
+    /**
+     * Instance name to create
+     *
+     * @var string
+     */
+    protected $instanceName;
+
+    /**
+     * Factory constructor
+     *
+     * @param ObjectManagerInterface $objectManager
+     * @param string $instanceName
+     */
+    public function __construct(
+        ObjectManagerInterface $objectManager,
+        $instanceName = '\Magento\Framework\Data\Tree\Node'
+    ) {
+        $this->objectManager = $objectManager;
+        $this->instanceName = $instanceName;
+    }
+
+    /**
+     * Create class instance with specified parameters
+     *
+     * @param array $data
+     * @return \Magento\Framework\Data\Tree\Node
+     */
+    public function create(array $data = [])
+    {
+        return $this->objectManager->create($this->instanceName, $data);
+    }
+}
diff --git a/lib/internal/Magento/Framework/Data/TreeFactory.php b/lib/internal/Magento/Framework/Data/TreeFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..ad3a41304b09fd8472a590d639df80984188807e
--- /dev/null
+++ b/lib/internal/Magento/Framework/Data/TreeFactory.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Framework\Data;
+
+use Magento\Framework\ObjectManagerInterface;
+
+/**
+ * Factory class for @see \Magento\Framework\Data\Tree
+ */
+class TreeFactory
+{
+    /**
+     * 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\Data\Tree'
+    ) {
+        $this->objectManager = $objectManager;
+        $this->instanceName = $instanceName;
+    }
+
+    /**
+     * Create class instance with specified parameters
+     *
+     * @param array $data
+     * @return \Magento\Framework\Data\Tree
+     */
+    public function create(array $data = [])
+    {
+        return $this->objectManager->create($this->instanceName, $data);
+    }
+}
diff --git a/lib/internal/Magento/Framework/composer.json b/lib/internal/Magento/Framework/composer.json
index d45fdb1c4457449bf35ce7d6986ab78a4c86f884..6584da302fbcc5cb180a9921b029beda1a41049b 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-beta1",
+    "version": "0.74.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/lib/web/css/source/lib/_navigation.less b/lib/web/css/source/lib/_navigation.less
index d56bd79f32c59e9ef806be17b8acaddd2d013288..6cf85b4ba0474fb65c4b07309445e12d85a5263f 100644
--- a/lib/web/css/source/lib/_navigation.less
+++ b/lib/web/css/source/lib/_navigation.less
@@ -8,6 +8,7 @@
 //  _____________________________________________
 
 .main-navigation(
+    @_nav__indent-side: 15px,
     @_nav-background-color: @navigation__background,
     @_nav-border: @navigation__border,
     @_nav-level0-font-size: @navigation-level0-item__font-size,
@@ -23,16 +24,21 @@
     @_nav-level0-item-text-decoration: @navigation-level0-item__text-decoration,
 
     @_nav-level0-item-background-color-active: @navigation-level0-item__active__background,
-    @_nav-level0-item-border-active: @navigation-level0-item__active__border,
+    @_nav-level0-item__active__border-color: @navigation-level0-item__active__border-color,
+    @_nav-level0-item__active__border-style: @navigation-level0-item__active__border-style,
+    @_nav-level0-item__active__border-width: @navigation-level0-item__active__border-width,
     @_nav-level0-item-color-active: @navigation-level0-item__active__color,
     @_nav-level0-item-text-decoration-active: @navigation-level0-item__active__text-decoration,
 
     @_submenu-background-color: @submenu__background,
     @_submenu-border: @submenu__border,
-    @_submenu-padding: @submenu__padding,
     @_submenu-font-size: @submenu__font-size,
     @_submenu-font-weight: @submenu__font-weight,
-    @_submenu-item-padding: @submenu-item__padding,
+    @_submenu-line-height: @submenu-item__line-height,
+    @_submenu-item__padding-top: @submenu__padding-top,
+    @_submenu-item__padding-right: @submenu__padding-right,
+    @_submenu-item__padding-bottom: @submenu__padding-bottom,
+    @_submenu-item__padding-left: @submenu__padding-left,
 
     @_submenu-item-background-color: @submenu-item__background,
     @_submenu-item-border: @submenu-item__border,
@@ -40,7 +46,10 @@
     @_submenu-item-text-decoration: @submenu-item__text-decoration,
 
     @_submenu-item-background-color-active: @submenu-item__active__background,
-    @_submenu-item-border-active: @submenu-item__active__border,
+    @_submenu-item__active__border: @submenu-item__active__border,
+    @_submenu-item__active__border-color: @submenu-item__active__border-color,
+    @_submenu-item__active__border-style: @submenu-item__active__border-style,
+    @_submenu-item__active__border-width: @submenu-item__active__border-width,
     @_submenu-item-color-active: @submenu-item__active__color,
     @_submenu-item-text-decoration-active: @submenu-item__active__text-decoration
 ) {
@@ -52,6 +61,16 @@
             margin: 0;
             padding: 0;
         }
+        li {
+            margin: 0;
+        }
+        a {
+            display: block;
+            .css(padding-top, @_submenu-item__padding-top);
+            .css(padding-right, @_submenu-item__padding-right);
+            .css(padding-bottom, @_submenu-item__padding-bottom);
+            .css(padding-left, @_submenu-item__padding-left);
+        }
         a,
         a:hover {
             .css(color, @_nav-level0-item-color);
@@ -60,22 +79,47 @@
         .level0 {
             .font-size(@_nav-level0-font-size);
             .css(border-top, @_nav-level0-item-border);
-            margin: 0;
             > .level-top {
                 .css(background, @_nav-level0-item-background-color);
                 .css(font-weight, @_nav-level0-font-weight);
                 .css(line-height, @_nav-level0-item-line-height);
                 .css(padding, @_nav-level0-item-padding);
                 .css(text-transform, @_nav-level0-text-transform);
-                display: block;
                 word-break: break-all;
             }
-            &.active > a {
-                .css(background, @_nav-level0-item-background-color-active);
-                .css(border, @_nav-level0-item-border-active);
-                .css(color, @_nav-level0-item-color-active);
-                .css(text-decoration, @_nav-level0-item-text-decoration-active);
+            &.active {
+                .all-category {
+                    .ui-state-focus {
+                        .css(background, @_nav-level0-item-background-color-active);
+                        .css(border-color, @_nav-level0-item__active__border-color);
+                        .css(border-style, @_nav-level0-item__active__border-style);
+                        .css(border-width, @_nav-level0-item__active__border-width);
+                        .css(color, @_nav-level0-item-color-active);
+                        .css(padding-left, @_nav__indent-side - @_submenu-item__active__border);
+                        .css(text-decoration, @_nav-level0-item-text-decoration-active);
+                        display: inline-block;
+                    }
+                }
+            }
+            > .level1 {
+                font-weight: @font-weight__semibold;
             }
+            &.active,
+            &.has-active { // ToDo UI: remove "has_active" here, when mobile navigation default open state is implemented
+                > a:not(.ui-state-active) {
+                    .css(background, @_nav-level0-item-background-color-active);
+                    .css(border-color, @_nav-level0-item__active__border-color);
+                    .css(border-style, @_nav-level0-item__active__border-style);
+                    .css(border-width, @_nav-level0-item__active__border-width);
+                    .css(color, @_nav-level0-item-color-active);
+                    .css(text-decoration, @_nav-level0-item-text-decoration-active);
+                    span:not(.ui-menu-icon) {
+                        margin-left: -@_submenu-item__active__border;
+                    }
+                }
+            }
+        }
+        li.level0 {
             &:last-child {
                 .css(border-bottom, @_nav-level0-item-border);
             }
@@ -89,25 +133,33 @@
                 .css(border, @_submenu-border);
                 .css(font-size, @_submenu-font-size);
                 .css(font-weight, @_submenu-font-weight);
+                .css(line-height, @_submenu-line-height);
+                left: auto !important;
                 overflow-x: hidden;
+                padding: 0;
                 position: relative;
-                transition: left .3s ease-out 0;
                 top: auto !important;
-                left: auto !important;
-                padding: 10px 20px;
-                > ul {
+                transition: left .3s ease-out;
+                > li {
+                    > a {
+                        padding-left: @_nav__indent-side;
+                    }
+                    &:last-child {
+                        margin-bottom: 0;
+                    }
+                }
+                ul {
                     display: block;
-                    .css(padding, @_submenu-padding);
+                    .css(padding-left, @_submenu-item__padding-left);
                     > li {
                         margin: 0;
                         a {
                             .css(background, @_submenu-item-background-color);
                             .css(border, @_submenu-item-border);
                             .css(color, @_submenu-item-color);
-                            .css(text-decoration, @_submenu-item-text-decoration);
                             display: block;
                             line-height: normal;
-                            .css(padding, @_submenu-item-padding);
+                            .css(text-decoration, @_submenu-item-text-decoration);
                         }
                     }
                 }
@@ -116,11 +168,23 @@
                     top: 0 !important;
                     padding-right: 0;
                 }
-                .active > a {
-                    .css(background, @_submenu-item-background-color-active);
-                    .css(border, @_submenu-item-border-active);
-                    .css(color, @_submenu-item-color-active);
-                    .css(text-decoration, @_submenu-item-text-decoration-active);
+                .active {
+                    > a {
+                        .css(background, @_submenu-item-background-color-active);
+                        .css(border-color, @_submenu-item__active__border-color);
+                        .css(border-style, @_submenu-item__active__border-style);
+                        .css(border-width, @_submenu-item__active__border-width);
+                        .css(color, @_submenu-item-color-active);
+                        .css(padding-left, @_nav__indent-side - @_submenu-item__active__border);
+                        .css(text-decoration, @_submenu-item-text-decoration-active);
+                    }
+                }
+                .level1 {
+                    &.active {
+                        > a {
+                            padding-left: @_nav__indent-side - @_submenu-item__active__border;
+                        }
+                    }
                 }
             }
         }
@@ -152,7 +216,9 @@
     @_nav-level0-item-text-decoration-hover: @navigation-desktop-level0-item__hover__text-decoration,
 
     @_nav-level0-item-background-color-active: @navigation-desktop-level0-item__active__background,
-    @_nav-level0-item-border-active: @navigation-desktop-level0-item__active__border,
+    @_nav-level0-item__active__border-color: @navigation-desktop-level0-item__active__border-color,
+    @_nav-level0-item__active__border-style: @navigation-desktop-level0-item__active__border-style,
+    @_nav-level0-item__active__border-width: @navigation-desktop-level0-item__active__border-width,
     @_nav-level0-item-color-active: @navigation-desktop-level0-item__active__color,
     @_nav-level0-item-text-decoration-active: @navigation-desktop-level0-item__active__text-decoration,
 
@@ -182,7 +248,9 @@
     @_submenu-item-text-decoration-hover: @submenu-desktop-item__hover__text-decoration,
 
     @_submenu-item-background-color-active: @submenu-desktop-item__active__background,
-    @_submenu-item-border-active: @submenu-desktop-item__active__border,
+    @_submenu-item__active__border-color: @submenu-desktop-item__active__border-color,
+    @_submenu-item__active__border-style: @submenu-desktop-item__active__border-style,
+    @_submenu-item__active__border-width: @submenu-desktop-item__active__border-width,
     @_submenu-item-color-active: @submenu-desktop-item__active__color,
     @_submenu-item-text-decoration-active: @submenu-desktop-item__active__text-decoration
 ) {
@@ -237,12 +305,16 @@
                     .css(text-decoration, @_nav-level0-item-text-decoration-hover);
                 }
             }
-            &.active {
+            &.active,
+            &.has-active {
                 > .level-top {
                     .css(background, @_nav-level0-item-background-color-active);
-                    .css(border, @_nav-level0-item-border-active);
+                    .css(border-color, @_nav-level0-item__active__border-color);
+                    .css(border-style, @_nav-level0-item__active__border-style);
+                    .css(border-width, @_nav-level0-item__active__border-width);
                     .css(color, @_nav-level0-item-color-active);
                     .css(text-decoration, @_nav-level0-item-text-decoration-active);
+                    display: inline-block;
                 }
             }
             &.parent:hover > .submenu {
@@ -288,7 +360,9 @@
                 }
                 .active > a {
                     .css(background, @_submenu-item-background-color-active);
-                    .css(border, @_submenu-item-border-active);
+                    .css(border-color, @_submenu-item__active__border-color);
+                    .css(border-style, @_submenu-item__active__border-style);
+                    .css(border-width, @_submenu-item__active__border-width);
                     .css(color, @_submenu-item-color-active);
                     .css(text-decoration, @_submenu-item-text-decoration-active);
                 }
@@ -365,7 +439,7 @@
         .css(margin-top, -@_size);
         > ul {
             .css(margin-top, @_size);
-            &:before{
+            &:before {
                 .css(color, @_bg);
                 content: '';
                 display: block;
@@ -382,7 +456,7 @@
         .css(margin-top, -@_size);
         > ul {
             .css(margin-top, @_size);
-            &:before{
+            &:before {
                 .css(color, @_border);
                 content: '';
                 display: block;
diff --git a/lib/web/css/source/lib/variables/_colors.less b/lib/web/css/source/lib/variables/_colors.less
index 603a465151215b6ad4b766484de0edba7c25479f..95374e5802e6db799efd9467872db5928d19fbec 100644
--- a/lib/web/css/source/lib/variables/_colors.less
+++ b/lib/web/css/source/lib/variables/_colors.less
@@ -33,6 +33,7 @@
 @color-gray94: #f0f0f0;
 @color-gray95: #f2f2f2;
 @color-white-smoke: #f5f5f5;
+@color-white-dark-smoke: #efefef;
 @color-white-fog: #f8f8f8;
 
 @color-gray-light0: #f6f6f6;
diff --git a/lib/web/css/source/lib/variables/_navigation.less b/lib/web/css/source/lib/variables/_navigation.less
index eb1840348a47677eabd5fd15fb314e0bb2e8c766..73d1ad71cb3e4e69fe9f26a6553e8cae1e77bab8 100644
--- a/lib/web/css/source/lib/variables/_navigation.less
+++ b/lib/web/css/source/lib/variables/_navigation.less
@@ -14,7 +14,7 @@
 @navigation-level0-item__font-weight: @font-weight__bold;
 @navigation-level0-item__line-height: false;
 @navigation-level0-item__margin: 0;
-@navigation-level0-item__padding: 8px @indent__xl 8px @indent__base;
+@navigation-level0-item__padding: 8px @indent__xl 8px 15px;
 @navigation-level0-item__text-transform: uppercase;
 
 @navigation-level0-item__background: '';
@@ -23,24 +23,32 @@
 @navigation-level0-item__text-decoration: none;
 
 @navigation-level0-item__active__background: '';
-@navigation-level0-item__active__border: '';
+@navigation-level0-item__active__border-color: @color-orange-red1;
+@navigation-level0-item__active__border-style: solid;
+@navigation-level0-item__active__border-width: 0 0 0 8px;
 @navigation-level0-item__active__color: '';
 @navigation-level0-item__active__text-decoration: '';
 
 @submenu__background: '';
 @submenu__border: '';
-@submenu__padding: 0 0 0 @indent__base;
+@submenu__padding-top: @indent__s;
+@submenu__padding-right: 0;
+@submenu__padding-bottom: @indent__s;
+@submenu__padding-left: 15px;
 @submenu__font-size: '';
 @submenu__font-weight: @font-weight__regular;
+@submenu-item__line-height: 1.3;
 
-@submenu-item__padding: 8px 0;
 @submenu-item__background: '';
 @submenu-item__border: '';
 @submenu-item__color: @color-gray34;
 @submenu-item__text-decoration: '';
 
 @submenu-item__active__background: '';
-@submenu-item__active__border: '';
+@submenu-item__active__border: 8px;
+@submenu-item__active__border-color: @color-orange-red1;
+@submenu-item__active__border-style: solid;
+@submenu-item__active__border-width: 0 0 0 @submenu-item__active__border;
 @submenu-item__active__color: '';
 @submenu-item__active__text-decoration: '';
 
@@ -68,7 +76,9 @@
 @navigation-desktop-level0-item__hover__text-decoration: @navigation-desktop-level0-item__text-decoration;
 
 @navigation-desktop-level0-item__active__background: '';
-@navigation-desktop-level0-item__active__border: '';
+@navigation-desktop-level0-item__active__border-color: @color-orange-red1;
+@navigation-desktop-level0-item__active__border-style: solid;
+@navigation-desktop-level0-item__active__border-width: 0 0 3px;
 @navigation-desktop-level0-item__active__color: @navigation-desktop-level0-item__hover__color;
 @navigation-desktop-level0-item__active__text-decoration: @navigation-desktop-level0-item__text-decoration;
 
@@ -98,6 +108,8 @@
 @submenu-desktop-item__hover__text-decoration: @navigation-desktop-level0-item__text-decoration;
 
 @submenu-desktop-item__active__background: '';
-@submenu-desktop-item__active__border: '';
+@submenu-desktop-item__active__border-color: @color-orange-red1;
+@submenu-desktop-item__active__border-style: solid;
+@submenu-desktop-item__active__border-width: 0 0 0 3px;
 @submenu-desktop-item__active__color: '';
 @submenu-desktop-item__active__text-decoration: '';
diff --git a/package.json b/package.json
index 12ffc19d59651831c958e793c61e221f076988c0..eaee4e18e2484b09731ec9a8e2a165eef83ae29c 100644
--- a/package.json
+++ b/package.json
@@ -9,11 +9,11 @@
   },
   "homepage": "http://magento.com/",
   "devDependencies": {
-    "connect": "^3.3.3",
     "grunt": "^0.4.5",
     "grunt-autoprefixer": "^2.0.0",
     "grunt-banner": "^0.3.1",
     "grunt-contrib-clean": "^0.6.0",
+    "grunt-contrib-connect": "^0.9.0",
     "grunt-contrib-cssmin": "^0.10.0",
     "grunt-contrib-imagemin": "^0.9.2",
     "grunt-contrib-jasmine": "^0.8.1",
@@ -28,6 +28,7 @@
     "morgan": "^1.5.0",
     "node-minify": "^1.0.1",
     "serve-static": "^1.7.1",
+    "strip-json-comments": "^1.0.2",
     "time-grunt": "^1.0.0",
     "underscore": "^1.7.0"
   },