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/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/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/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/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/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/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/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/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/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/User/Test/Handler/Role/Curl.php b/dev/tests/functional/tests/app/Magento/User/Test/Handler/Role/Curl.php
index 9fa901fa7027177a1a174971b08b21a6eb416bec..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
@@ -63,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 a1b5ea977ca197f908052e708db8a0619e796f2f..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
@@ -46,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 30d0ee18b96e64b214d3819cd7e58fb6f3dbb940..f4022f124511e6ff7e953af51754645b55399e28 100644
--- a/dev/tests/integration/testsuite/Magento/Multishipping/Controller/CheckoutTest.php
+++ b/dev/tests/integration/testsuite/Magento/Multishipping/Controller/CheckoutTest.php
@@ -57,11 +57,9 @@ class CheckoutTest extends \Magento\TestFramework\TestCase\AbstractController
         $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(
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/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/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/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/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/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/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"
   },